Compare commits

...

5 commits

Author SHA1 Message Date
62838e3b64
feat: reset button 2024-12-26 04:15:00 +00:00
55eaa057ad
feat: basic website style 2024-12-26 04:14:46 +00:00
77c7b9cade
fix: proper update with locking 2024-12-26 04:12:38 +00:00
b63b7d2b3f
fix: only rotate on pointerlock 2024-12-26 01:25:50 +00:00
46fbf1e289
refactor: multiple javascript files 2024-12-26 01:25:29 +00:00
7 changed files with 202 additions and 128 deletions

36
algebra.mjs Normal file
View file

@ -0,0 +1,36 @@
export function calcRotationMatrix(vec, rad) {
// Equation used from:
// https://people.eecs.berkeley.edu/~ug/slide/pipeline/assignments/as5/rotation.html
let A = glMatrix.mat3.fromValues(
0,
-vec[2],
vec[1],
vec[2],
0,
-vec[0],
-vec[1],
vec[0],
0,
);
let I = glMatrix.mat3.create();
// Matrix Exponential
let Mpow = glMatrix.mat3.create();
glMatrix.mat3.mul(Mpow, A, A);
let M1 = glMatrix.mat3.create();
let M2 = glMatrix.mat3.create();
// Scalar Multiplications
glMatrix.mat3.multiplyScalar(M1, A, Math.sin(rad));
glMatrix.mat3.multiplyScalar(M2, Mpow, 1 - Math.cos(rad));
// Matrix Addition
let M3 = glMatrix.mat3.create();
let Q = glMatrix.mat3.create();
glMatrix.mat3.add(M3, I, M1);
glMatrix.mat3.add(Q, M3, M2);
return Q;
}

BIN
bg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View file

@ -4,9 +4,31 @@
<meta charset="UTF-8" />
<title>Shaders are Fun</title>
<link rel="icon" href="https://fav.farm/🐴" />
<script defer src="shader.mjs" type="module"></script>
<link rel="stylesheet" type="text/css" href="/style.css" />
<script defer src="main.mjs" type="module"></script>
</head>
<body>
<canvas id="shader"> </canvas>
<main>
<h1 style="margin-bottom: 0px">
<svg viewBox="0 0 1000 40" xmlns="http://www.w3.org/2000/svg">
<text
x="500"
text-anchor="middle"
dominant-baseline="hanging"
fill="#51fefe"
stroke-width="6"
paint-order="stroke"
>
Stitchy's Shaders
</text>
</svg>
</h1>
<div class="render">
<canvas id="shader"> </canvas>
</div>
<div style="padding: 1rem">
<button id="reset_button">Reset</button>
</div>
</main>
</body>
</html>

99
main.mjs Normal file
View file

@ -0,0 +1,99 @@
import "https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.js";
import { initShader } from "./shader.mjs";
import { calcRotationMatrix } from "./algebra.mjs";
const CANVAS_WIDTH = 800;
const CANVAS_HEIGHT = 800;
let TIME = 0;
let camera_pos = [0, 0, 0];
let mouse_pos = [0, 0];
// Update the Camera position
function updateCamera(gl, program) {
if (document.pointerLockElement) {
if (keymap.get("w")) {
camera_pos[2] += 0.1;
}
if (keymap.get("a")) {
camera_pos[0] += -0.1;
}
if (keymap.get("s")) {
camera_pos[2] += -0.1;
}
if (keymap.get("d")) {
camera_pos[0] += 0.1;
}
if (keymap.get("e")) {
camera_pos[1] += 0.1;
}
if (keymap.get("q")) {
camera_pos[1] += -0.1;
}
}
// Position
const pos = gl.getUniformLocation(program, "camera_pos");
gl.uniform3fv(pos, camera_pos);
// Rotation
const rot = gl.getUniformLocation(program, "camera_rot");
let M1 = calcRotationMatrix([0, -1, 0], mouse_pos[0]);
let M2 = calcRotationMatrix([-1, 0, 0], mouse_pos[1]);
let rot_mat = glMatrix.mat3.create();
glMatrix.mat3.mul(rot_mat, M1, M2);
gl.uniform3fv(rot, rot_mat);
}
// update the canvas
function draw(gl, program) {
// Create uniform
const loc = gl.getUniformLocation(program, "time");
TIME += 1 / 60;
gl.uniform1f(loc, TIME);
updateCamera(gl, program);
// Draw the frame recursively on next frame
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(() => draw(gl, program));
}
const button = document.getElementById("reset_button");
button.addEventListener("click", reset_transform);
function reset_transform() {
camera_pos = [0, 0, 0];
mouse_pos = [0, 0];
}
//** MAIN PROGRAM **//
// Initialize the shader
const [gl, program, canvas] = await initShader(CANVAS_WIDTH, CANVAS_HEIGHT);
// Key Presses
let keymap = new Map();
document.addEventListener("keydown", function (event) {
keymap.set(event.key, true);
});
document.addEventListener("keyup", function (event) {
keymap.set(event.key, false);
});
// Mouse movement
document.addEventListener("mousemove", function (event) {
if (document.pointerLockElement) {
mouse_pos[0] += event.movementX / 800;
mouse_pos[1] += event.movementY / 800;
}
});
// Request pointer Lock
canvas.addEventListener("click", async () => {
await canvas.requestPointerLock();
});
// Update loop
draw(gl, program);

View file

@ -20,7 +20,7 @@ const float PI = 3.1415;
//const vec3 camera_pos = vec3(0.);
const vec3 color1 = vec3(0.494, 0.361, 0.678);
const vec3 color2 = vec3(0.827, 0.945, 0.875);
const vec3 color2 = vec3(0.18, 0.945, 0.975);
// Scene Object (sphere)

View file

@ -1,29 +1,21 @@
import "https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.js";
const CANVAS_WIDTH = 700;
const CANVAS_HEIGHT = 700;
let TIME = 0;
let camera_pos = [0, 0, 0];
let mouse_pos = [0, 0];
// ** Initialization stuffs ** //
async function initShader() {
export async function initShader(c_width, c_height) {
// Get GL contexts and stuffs
const canvas = document.getElementById("shader");
const gl = canvas.getContext("webgl2");
canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;
canvas.width = c_width;
canvas.height = c_height;
gl.viewport(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
gl.viewport(0, 0, c_width, c_height);
// Create Vertex Array
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
// manipulating bitfield for canvas
gl.clearColor(1, 1, 0, 1);
gl.clearColor(0.18, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Array of verticies for gpu to render
@ -97,93 +89,7 @@ async function fetch_local(src) {
return await res.text();
}
// Update the Camera position
function updateCamera(gl, program) {
if (keymap.get("w")) {
camera_pos[2] += 0.1;
}
if (keymap.get("a")) {
camera_pos[0] += -0.1;
}
if (keymap.get("s")) {
camera_pos[2] += -0.1;
}
if (keymap.get("d")) {
camera_pos[0] += 0.1;
}
if (keymap.get("e")) {
camera_pos[1] += 0.1;
}
if (keymap.get("q")) {
camera_pos[1] += -0.1;
}
// Position
const pos = gl.getUniformLocation(program, "camera_pos");
gl.uniform3fv(pos, camera_pos);
// Rotation
const rot = gl.getUniformLocation(program, "camera_rot");
let M1 = calcRotationMatrix([0, -1, 0], mouse_pos[0]);
let M2 = calcRotationMatrix([-1, 0, 0], mouse_pos[1]);
let rot_mat = glMatrix.mat3.create();
glMatrix.mat3.mul(rot_mat, M1, M2);
gl.uniform3fv(rot, rot_mat);
}
// update the canvas
function draw(gl, program) {
// Create uniform
const loc = gl.getUniformLocation(program, "time");
TIME += 1 / 60;
gl.uniform1f(loc, TIME);
updateCamera(gl, program);
// Draw the frame recursively on next frame
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(() => draw(gl, program));
}
function calcRotationMatrix(vec, rad) {
// Equation used from:
// https://people.eecs.berkeley.edu/~ug/slide/pipeline/assignments/as5/rotation.html
let A = glMatrix.mat3.fromValues(
0,
-vec[2],
vec[1],
vec[2],
0,
-vec[0],
-vec[1],
vec[0],
0,
);
let I = glMatrix.mat3.create();
// Matrix Exponential
let Mpow = glMatrix.mat3.create();
glMatrix.mat3.mul(Mpow, A, A);
let M1 = glMatrix.mat3.create();
let M2 = glMatrix.mat3.create();
// Scalar Multiplications
glMatrix.mat3.multiplyScalar(M1, A, Math.sin(rad));
glMatrix.mat3.multiplyScalar(M2, Mpow, 1 - Math.cos(rad));
// Matrix Addition
let M3 = glMatrix.mat3.create();
let Q = glMatrix.mat3.create();
glMatrix.mat3.add(M3, I, M1);
glMatrix.mat3.add(Q, M3, M2);
return Q;
}
// Loads a single Texture to the Shader
function loadTexture(gl, url, gl_tex) {
// Create texture
const texture = gl.createTexture();
@ -211,28 +117,3 @@ function loadTexture(gl, url, gl_tex) {
return texture;
}
// Initialize the shader
const [gl, program, canvas] = await initShader();
// Key Presses
let keymap = new Map();
document.addEventListener("keydown", function (event) {
keymap.set(event.key, true);
});
document.addEventListener("keyup", function (event) {
keymap.set(event.key, false);
});
// Mouse movement
document.addEventListener("mousemove", function (event) {
mouse_pos[0] += event.movementX / 800;
mouse_pos[1] += event.movementY / 800;
});
// Request pointer Lock
canvas.addEventListener("click", async () => {
await canvas.requestPointerLock();
});
// Update loop
draw(gl, program);

36
style.css Normal file
View file

@ -0,0 +1,36 @@
:root {
--text-color: #a1a;
--bg-color: #51fefe;
}
body {
margin: 0px;
padding: 0px;
background-image: url("./bg.webp");
background-attachment: fixed;
overflow: hidden;
}
main {
color: var(--text-color);
text-align: center;
margin: 1rem;
}
svg {
color: var(--text-color);
stroke: #a1a;
}
.render {
padding: 0px;
margin: 0px;
border: var(--text-color) 4px solid;
display: inline-flex;
}
button {
color: var(--text-color);
background-color: var(--bg-color);
border: 4px var(--text-color) solid;
padding: 0.5rem 2rem;
}