webgl-shader/script.js
Christian Lawson-Perfect 61faec2e92 WebGL 2 shader
2025-05-16 06:32:13 +00:00

128 lines
No EOL
3.3 KiB
JavaScript

console.clear();
function error(...msgs) {
const msg = msgs.join('\n');
console.error(msg);
document.getElementById('errors').textContent = msg;
}
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
error('An error occurred compiling the shaders:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
function initShaderProgram(gl, vs, fs) {
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vs);
gl.attachShader(shaderProgram, fs);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
error('Unable to initialize the shader program:', gl.getProgramInfoLog(shaderProgram));
return null;
}
return shaderProgram;
}
function initBuffers(gl) {
const vertices = new Float32Array([
-1, 1,
1, 1,
-1, -1,
-1, -1,
1, 1,
1, -1
]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
return vertexBuffer;
}
async function init() {
const vsSource = `#version 300 es
in vec4 aVertexPosition;
out vec4 v_pos;
void main(void) {
gl_Position = aVertexPosition;
v_pos = gl_Position;
}
`;
const fsSource = await (await fetch('fragshader.glsl')).text();
console.log(fsSource);
function set_canvas_size() {
const dpr = window.devicePixelRatio;
const {clientWidth: width, clientHeight: height} = canvas;
canvas.width = Math.round(width * dpr);
canvas.height = Math.round(height * dpr);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT);
const vertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
const tLoc = gl.getUniformLocation(shaderProgram, "t");
const screen_sizeLoc = gl.getUniformLocation(shaderProgram, "screen_size");
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
const t = (new Date() - t1) / 1000;
gl.uniform1f(tLoc, t);
gl.uniform2fv(screen_sizeLoc, [canvas.width, canvas.height]);
gl.vertexAttribPointer(vertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexPosition);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.useProgram(shaderProgram);
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(drawScene);
}
let mx = 0, my = 0;
const canvas = document.getElementById('glCanvas');
set_canvas_size();
const gl = canvas.getContext('webgl2');
if (!gl) {
throw new Error('Unable to initialize WebGL. Your browser may not support it.');
}
if (gl) {
gl.clearColor(0.0, 0.0, 0.0, 1.0);
}
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = initShaderProgram(gl, vertexShader, fragmentShader);
const vertexBuffer = initBuffers(gl);
const t1 = new Date();
drawScene();
const resize_observer = new ResizeObserver((entries) => set_canvas_size());
resize_observer.observe(canvas);
}
init();