Compare commits
No commits in common. "62838e3b645d2590b9fe51a1723b3976e8e873a9" and "367153bbf691c29cb114b54219c8022c2b3e580b" have entirely different histories.
62838e3b64
...
367153bbf6
7 changed files with 128 additions and 202 deletions
36
algebra.mjs
36
algebra.mjs
|
@ -1,36 +0,0 @@
|
||||||
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
BIN
bg.webp
Binary file not shown.
Before Width: | Height: | Size: 69 KiB |
26
index.html
26
index.html
|
@ -4,31 +4,9 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Shaders are Fun</title>
|
<title>Shaders are Fun</title>
|
||||||
<link rel="icon" href="https://fav.farm/🐴" />
|
<link rel="icon" href="https://fav.farm/🐴" />
|
||||||
<link rel="stylesheet" type="text/css" href="/style.css" />
|
<script defer src="shader.mjs" type="module"></script>
|
||||||
<script defer src="main.mjs" type="module"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<canvas id="shader"> </canvas>
|
||||||
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
99
main.mjs
99
main.mjs
|
@ -1,99 +0,0 @@
|
||||||
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);
|
|
|
@ -20,7 +20,7 @@ const float PI = 3.1415;
|
||||||
|
|
||||||
//const vec3 camera_pos = vec3(0.);
|
//const vec3 camera_pos = vec3(0.);
|
||||||
const vec3 color1 = vec3(0.494, 0.361, 0.678);
|
const vec3 color1 = vec3(0.494, 0.361, 0.678);
|
||||||
const vec3 color2 = vec3(0.18, 0.945, 0.975);
|
const vec3 color2 = vec3(0.827, 0.945, 0.875);
|
||||||
|
|
||||||
// Scene Object (sphere)
|
// Scene Object (sphere)
|
||||||
|
|
||||||
|
|
131
shader.mjs
131
shader.mjs
|
@ -1,21 +1,29 @@
|
||||||
|
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 ** //
|
// ** Initialization stuffs ** //
|
||||||
|
|
||||||
export async function initShader(c_width, c_height) {
|
async function initShader() {
|
||||||
// Get GL contexts and stuffs
|
// Get GL contexts and stuffs
|
||||||
const canvas = document.getElementById("shader");
|
const canvas = document.getElementById("shader");
|
||||||
const gl = canvas.getContext("webgl2");
|
const gl = canvas.getContext("webgl2");
|
||||||
|
|
||||||
canvas.width = c_width;
|
canvas.width = CANVAS_WIDTH;
|
||||||
canvas.height = c_height;
|
canvas.height = CANVAS_HEIGHT;
|
||||||
|
|
||||||
gl.viewport(0, 0, c_width, c_height);
|
gl.viewport(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||||
|
|
||||||
// Create Vertex Array
|
// Create Vertex Array
|
||||||
const vao = gl.createVertexArray();
|
const vao = gl.createVertexArray();
|
||||||
gl.bindVertexArray(vao);
|
gl.bindVertexArray(vao);
|
||||||
|
|
||||||
// manipulating bitfield for canvas
|
// manipulating bitfield for canvas
|
||||||
gl.clearColor(0.18, 1, 1, 1);
|
gl.clearColor(1, 1, 0, 1);
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// Array of verticies for gpu to render
|
// Array of verticies for gpu to render
|
||||||
|
@ -89,7 +97,93 @@ async function fetch_local(src) {
|
||||||
return await res.text();
|
return await res.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loads a single Texture to the Shader
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
function loadTexture(gl, url, gl_tex) {
|
function loadTexture(gl, url, gl_tex) {
|
||||||
// Create texture
|
// Create texture
|
||||||
const texture = gl.createTexture();
|
const texture = gl.createTexture();
|
||||||
|
@ -117,3 +211,28 @@ function loadTexture(gl, url, gl_tex) {
|
||||||
|
|
||||||
return texture;
|
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
36
style.css
|
@ -1,36 +0,0 @@
|
||||||
: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;
|
|
||||||
}
|
|
Loading…
Reference in a new issue