This commit is contained in:
Daniel
2026-04-02 10:07:24 +08:00
parent 198d8534ad
commit a5bf2adad9
2 changed files with 82 additions and 14 deletions

View File

@@ -106,6 +106,7 @@ uniform float iTime;
uniform float iTimeDelta;
uniform int iFrame;
uniform vec4 iMouse;
uniform vec4 iDate;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
@@ -114,6 +115,18 @@ ${userCode}
void main() { mainImage(outColor, gl_FragCoord.xy); }`;
}
function setIDateUniform(gl, loc) {
if (loc == null) return;
const d = new Date();
gl.uniform4f(
loc,
d.getFullYear(),
d.getMonth() + 1,
d.getDate(),
d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds() + d.getMilliseconds() * 0.001
);
}
function createQuad(gl) {
const quad = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);
const vao = gl.createVertexArray();
@@ -128,19 +141,29 @@ function createQuad(gl) {
}
function compileProgram(gl, fragmentShaderSource) {
function compile(type, source) {
function compile(type, label, source) {
if (gl.isContextLost?.()) {
throw new Error(`${label}: WebGL context lost`);
}
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const info = gl.getShaderInfoLog(shader);
let info = (gl.getShaderInfoLog(shader) || "").trim();
if (!info) {
const err = gl.getError();
info =
err && err !== gl.NO_ERROR
? `WebGL getError 0x${err.toString(16)} (driver returned no compile log)`
: "No compile log (often: shader too complex, loop/unroll limits, or driver bug). Try a simpler shader.";
}
gl.deleteShader(shader);
throw new Error(info || "unknown compile error");
throw new Error(`${label} shader:\n${info}`);
}
return shader;
}
const vs = compile(gl.VERTEX_SHADER, vertexShaderSource);
const fs = compile(gl.FRAGMENT_SHADER, fragmentShaderSource);
const vs = compile(gl.VERTEX_SHADER, "Vertex", vertexShaderSource);
const fs = compile(gl.FRAGMENT_SHADER, "Fragment", fragmentShaderSource);
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
@@ -148,9 +171,16 @@ function compileProgram(gl, fragmentShaderSource) {
gl.deleteShader(vs);
gl.deleteShader(fs);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const info = gl.getProgramInfoLog(program);
let info = (gl.getProgramInfoLog(program) || "").trim();
if (!info) {
const err = gl.getError();
info =
err && err !== gl.NO_ERROR
? `WebGL getError 0x${err.toString(16)} (no link log)`
: "No link log (vertex/fragment interface mismatch or resource limits).";
}
gl.deleteProgram(program);
throw new Error(info || "unknown link error");
throw new Error(`Program link:\n${info}`);
}
return program;
}
@@ -349,6 +379,7 @@ function ensurePreviewWebGL(state) {
iTimeDelta: gl.getUniformLocation(program, "iTimeDelta"),
iFrame: gl.getUniformLocation(program, "iFrame"),
iMouse: gl.getUniformLocation(program, "iMouse"),
iDate: gl.getUniformLocation(program, "iDate"),
};
state.gl = gl;
state.program = program;
@@ -611,6 +642,7 @@ function openDetail(previewState) {
iTimeDelta: gl.getUniformLocation(program, "iTimeDelta"),
iFrame: gl.getUniformLocation(program, "iFrame"),
iMouse: gl.getUniformLocation(program, "iMouse"),
iDate: gl.getUniformLocation(program, "iDate"),
},
mouse: { x: 0, y: 0, downX: 0, downY: 0, down: false },
_layoutW: 0,
@@ -741,6 +773,7 @@ function renderAll(ts) {
gl.uniform1f(uniforms.iTimeDelta, 0);
gl.uniform1i(uniforms.iFrame, 0);
}
setIDateUniform(gl, uniforms.iDate);
gl.uniform4f(
uniforms.iMouse,
mouse.x,
@@ -776,6 +809,7 @@ function renderAll(ts) {
gl.uniform1f(uniforms.iTime, elapsed);
gl.uniform1f(uniforms.iTimeDelta, dt);
gl.uniform1i(uniforms.iFrame, frame);
setIDateUniform(gl, uniforms.iDate);
gl.uniform4f(
uniforms.iMouse,
mouse.x,