Feat : handle settings gracefully

This commit is contained in:
2024-05-24 17:19:31 +02:00
parent 766dc92931
commit 4ea5c25a47
5 changed files with 131 additions and 77 deletions
+71 -26
View File
@@ -6,9 +6,9 @@ import resolveLygia from "https://lygia.xyz/resolve.esm.js"
declare const resolveLygia: (source: string) => string
let interval: number
let timeout: number
const shaderOptions = { quality: 6, framerate: 1000 / 60 }
const bounds = { left: 0, bottom: 0 }
const shaderOptions = { quality: 1, framerate: 1000 / 60 }
const screen = { width: 0, height: 0, devicePixelRatio: 0 }
const _colorStart = [0, 0, 0]
@@ -18,19 +18,22 @@ let fragmentShader = resolveLygia(noise);
let canvas: OffscreenCanvas
async function main(canvas: OffscreenCanvas, fragmentShader2: string) {
let render: (time: number) => void
let must_resize = false
async function main(canvas: OffscreenCanvas) {
const gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
const program = gl.createProgram()
if (!program) { return }
const fragment = gl.createShader(gl.FRAGMENT_SHADER);
if (!fragment) { return }
gl.shaderSource(fragment, fragmentShader2)
gl.shaderSource(fragment, fragmentShader)
gl.compileShader(fragment);
if (!gl.getShaderParameter(fragment, gl.COMPILE_STATUS)) {
const lastError = gl.getShaderInfoLog(fragment);
@@ -87,6 +90,12 @@ async function main(canvas: OffscreenCanvas, fragmentShader2: string) {
const gl2 = gl
function render(time: number) {
if (must_resize) {
canvas.width = screen.width * shaderOptions.quality / 10
canvas.height = screen.height * shaderOptions.quality / 10
must_resize = false;
}
time *= 0.001; // convert to seconds
// Tell WebGL how to convert from clip space to pixels
gl2.viewport(0, 0, gl2.canvas.width, gl2.canvas.height);
@@ -110,11 +119,19 @@ async function main(canvas: OffscreenCanvas, fragmentShader2: string) {
0, // start at the beginning of the buffer
);
const secondRatio = screen.width / screen.height
const aspectRatio = Math.max(screen.width, screen.height) * screen.devicePixelRatio
gl2.uniform2f(offset, bounds.left, -bounds.bottom);
if (secondRatio < 1) {
const half = canvas.height / 2
gl2.uniform2f(resolutionLocation, canvas.width, canvas.height * secondRatio);
gl2.uniform2f(offset, 0, -half + ((half) / (1 / secondRatio)));
} else {
const half = canvas.width / 2
gl2.uniform2f(resolutionLocation, canvas.width / secondRatio, canvas.height);
gl2.uniform2f(offset, -half + ((half) / secondRatio), 0);
}
gl2.uniform1i(quality, shaderOptions.quality)
gl2.uniform2f(resolutionLocation, aspectRatio, aspectRatio);
gl2.uniform3f(colorStart, _colorStart[0], _colorStart[1], _colorStart[2]);
gl2.uniform3f(colorEnd, _colorEnd[0], _colorEnd[1], _colorEnd[2]);
gl2.uniform1f(timeLocation, time);
@@ -123,43 +140,71 @@ async function main(canvas: OffscreenCanvas, fragmentShader2: string) {
0, // offset
6, // num vertices to process
);
requestAnimationFrame(render)
if (timeout) {
self.clearTimeout(timeout)
timeout = self.setTimeout(() => {
requestAnimationFrame(render)
}, 1000 / shaderOptions.framerate)
}
console.log("a")
}
// self.clearInterval(interval)
// interval = self.setInterval(() => requestAnimationFrame(render), shaderOptions.framerate)
requestAnimationFrame(render)
// interval = self.setInterval(() => requestAnimationFrame(render), 1000 / shaderOptions.framerate)
self.clearTimeout(timeout)
timeout = self.setTimeout(() => {
requestAnimationFrame(render)
}, 1000 / shaderOptions.framerate)
return render
}
self.addEventListener("message", (e) => {
const data = e.data
if (data.command == "initShader") {
canvas = data.canvas
} else if (data.command == "killShader") {
console.log("killShader")
self.clearInterval(interval)
} else {
console.log(screen.devicePixelRatio)
bounds.bottom = data.bounds.bottom
bounds.left = data.bounds.left
shaderOptions.quality = data.shaderOptions.quality
screen.devicePixelRatio = data.screen.devicePixelRatio
screen.width = data.screen.width
screen.height = data.screen.height
loadShader()
} else if (data.command == "killShader") {
console.log("killShader")
self.clearInterval(interval)
self.clearTimeout(timeout)
}
else if (data.command == "resumeShader") {
self.clearInterval(interval)
self.clearTimeout(timeout)
shaderOptions.framerate = data.shaderOptions.framerate
if (shaderOptions.framerate == 65) {
shaderOptions.framerate == Infinity
}
timeout = self.setTimeout(() => {
requestAnimationFrame(render)
}, 1000 / shaderOptions.framerate)
// interval = self.setInterval(() => requestAnimationFrame(render), 1000 / shaderOptions.framerate)
} else if (data.command == "recolorShader") {
_colorStart[0] = data.colorStart[0]
_colorStart[1] = data.colorStart[1]
_colorStart[2] = data.colorStart[2]
_colorEnd[0] = data.colorEnd[0]
_colorEnd[1] = data.colorEnd[1]
_colorEnd[2] = data.colorEnd[2]
if (data.command == "reloadShader") {
shaderOptions.quality = data.shaderOptions.quality
shaderOptions.framerate = data.shaderOptions.framerate
reloadShader()
}
} else if (data.command == "resizeShader") {
shaderOptions.quality = data.shaderOptions.quality
screen.devicePixelRatio = data.screen.devicePixelRatio
screen.width = data.screen.width
screen.height = data.screen.height
must_resize = true
}
})
async function reloadShader() {
async function loadShader() {
if (!canvas) { return }
let fragmentShader2 = fragmentShader.replace("#define FBM_OCTAVES 6", "#define FBM_OCTAVES " + shaderOptions.quality);
main(canvas, fragmentShader2);
console.log("a")
// let fragmentShader2 = fragmentShader.replace("#define FBM_OCTAVES 6", "#define FBM_OCTAVES " + shaderOptions.quality);
const temp = await main(canvas);
if (temp) {
render = temp
}
}