(() => { var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/shaders/buffer_0.glsl var require_buffer_0 = __commonJS({ "src/shaders/buffer_0.glsl"(exports, module) { module.exports = `#version 300 es precision highp float; uniform sampler2D iChannel0; // Random texture uniform sampler2D iChannel1; // Buffer A output uniform sampler2D iChannel2; // Buffer B output uniform sampler2D iChannel3; // Buffer C output uniform vec3 iResolution; // Resolution of the rendering canvas, used to calculate screen UVs. uniform int iFrame; // Current frame of the animation. uniform float iTime; uniform vec3 iMouse; uniform int frameCount; // Total frame count for the animation. out vec4 fragColor; // Output color. void mainImage(out vec4 fragColor, in vec2 fragCoord) { // Placeholder shader logic fragColor = vec4(1.0, 1.0, 0.0, 0.0); } // Run mainImage. void main() { mainImage(fragColor, gl_FragCoord.xy); }`; } }); // src/shaders/buffer_1.glsl var require_buffer_1 = __commonJS({ "src/shaders/buffer_1.glsl"(exports, module) { module.exports = `#version 300 es precision highp float; // Uniform inputs uniform sampler2D iChannel0; // Random texture uniform sampler2D iChannel1; // Buffer A output uniform sampler2D iChannel2; // Buffer B output uniform sampler2D iChannel3; // Buffer C output uniform vec3 iResolution; // Resolution of the rendering canvas uniform int iFrame; // Current frame of the animation uniform float iTime; uniform float iGlobalTime; uniform vec3 iMouse; uniform int frameCount; // Total frame count for the animation uniform vec3 params[14]; // Output out vec4 fragColor; // Constants #define PI 3.14159 #define keyTex iChannel3 #define KEY_I texture(keyTex, vec2((105.5 - 32.0) / 256.0, (0.5 + 0.0) / 3.0)).x #define angRnd 1.0 #define RotNum 3 #define posRnd 0.0 // Utility Functions float circle(in vec2 _st, in float _radius) { vec2 dist = _st - vec2(0.5); return 1.0 - smoothstep( _radius - (_radius * 0.11), _radius + (_radius * 0.11), dot(dist, dist) * 3.0 ); } // Blur function (Gaussian kernel) vec4 blur(vec2 uv, sampler2D tex, float radius) { vec4 color = vec4(0.0); float totalWeight = 0.0; const int kernelSize = 5; // Number of samples per axis (odd value) for (int x = -kernelSize; x <= kernelSize; x++) { for (int y = -kernelSize; y <= kernelSize; y++) { // Gaussian weight calculation float weight = exp(-0.5 * (float(x * x + y * y) / (radius * radius))); vec2 offset = vec2(float(x), float(y)) / iResolution.xy; color += texture(tex, uv + offset) * weight; totalWeight += weight; } } return color / totalWeight; // Normalize by the total weight } float random(in vec2 _st) { return fract(sin(dot(_st.xy, vec2(12.9898, 78.233))) * 43758.5453123); } float getVal(vec2 uv) { return length(texture(iChannel2, uv).xyz); } vec2 getGrad(vec2 uv, float delta) { vec2 d = vec2(delta, 0.0); return vec2( getVal(uv + d.xy) - getVal(uv - d.xy), getVal(uv + d.yx) - getVal(uv - d.yx) ) / delta; } vec4 offset(vec2 uv, vec2 offsetVal) { return texture(iChannel2, (uv + offsetVal / iResolution.xy)); } vec4 randS(vec2 uv) { //return getRand4(uv.y+uv.x*1234.567)-vec4(0.5); return texture(iChannel0,uv*iResolution.xy/iResolution.xy)-vec4(0.5); } const float ang = 2.0*3.1415926535/float(RotNum); mat2 m = mat2(cos(ang),sin(ang),-sin(ang),cos(ang)); float getRot(vec2 uv, float sc) { float ang2 = angRnd*randS(uv).x*ang; vec2 p = vec2(cos(ang2),sin(ang2)); float rot=0.0; for(int i=0;i 0.5 && iMouse.y / iResolution.y > 0.9 && iMouse.x / iResolution.x > 0.9) { uv0.x = random(uv0); uv0.y = random(uv0); } // Time-based and parameter-driven UV offset uv += vec2( sin((17338407607. * params[2].x)) * (1733847607. * params[1].x), sin((17338470607. * params[3].x)) * (1733847607. * params[4].x) ); // Texture sampling and processing vec4 c = texture(iChannel0, uv / 50.0); vec4 d = texture(iChannel2, uv / 1.0); float a = length(fract(c.r * params[1].x * 10000000.0)); float b = length(fract(c.g * params[2].x * 10000000.0)); vec3 n = vec3(getGrad(uv, 1.0 / iResolution.y), 1.0); // Offset calculations vec2 delta = vec2(1.0) / iResolution.xy; float pX = offset(uv, delta).r; float nX = offset(uv, -delta).r; float pY = offset(uv, delta.yx).g; float nY = offset(uv, -delta.yx).g; float dpY = (d.g - pY) / params[1].x; float dpX = (d.r - pX) / params[2].y; float dnY = (nY - d.g) / params[3].x; float dnX = (nX - d.r) / params[4].y; // Main processing loop int g = 10; vec2 dd = vec2(dpX, dpY); for (int i = 0; i < g; i++) { c.rg *= mh; c.rg += normalize((vec2(c.r, c.g) - vec2(0.5)) / dot(c.rg, c.rg)); c.rg += fract(sin((vec2(random(params[1].xy), random(params[2].xy))/2.))); float rot = getRot(c.rg, params[1].x); c += rot; c.rg = normalize(c.rg); c *= 4.91+params[6].x-params[7].x; // Smoothing vec2 csmooth = smoothstep(vec2(-0.0), vec2(1.0), c.rg); //water estuary //vec2 csmooth = smoothstep(vec2(0.0), vec2(1.0), vec2(a,b)); //cityscape c.rg = mix(c.rg, csmooth, 0.7); //c.rg = mix(c.rg, csmooth, params[1].x / 1.0); } vec2 modUV = fract(uv + (c.xy / iResolution.xy)); // Apply blur to the current texture float blurRadius = 0.2; // Adjust this for stronger/weaker blur vec4 blurredTexture = blur(modUV, iChannel2, blurRadius); // Final color mixing vec4 prevTex = texture(iChannel2, fract(uv + (c.xy / iResolution.xy))); //crystallize vec3 color = mix( blurredTexture.rgb, fract(texture(iChannel0, uv).rgb), 0.0001 * params[1].r ); if (iFrame <= 1) { // Set the output color to a constant gray fragColor = texture(iChannel0, uv);} else{ // Circle masking fragColor = vec4(color.r);} float cir = circle(uv0 - vec2(0.0, 0.0), 20.2); //fragColor = mix(vec4(cir), fragColor, 0.99); //fragColor *= cir; } // Entry point for WebGL shader execution void main() { mainImage(fragColor, gl_FragCoord.xy); }`;} }); // src/shaders/buffer_2.glsl var require_buffer_2 = __commonJS({ "src/shaders/buffer_2.glsl"(exports, module) { module.exports = `#version 300 es precision highp float; // This is the last "buffer" before blit.frag, technically "Image" // Uniform inputs uniform sampler2D iChannel0; // Random texture uniform sampler2D iChannel1; // Buffer A output uniform sampler2D iChannel2; // Buffer B output uniform sampler2D iChannel3; // Buffer C output uniform vec3 iResolution; uniform vec4 iMouse; uniform float iGlobalTime; uniform float iTime; uniform int iFrame; uniform vec3 params[14]; // Output out vec4 fragColor; // Color utility functions #define hue(v) (0.6 + 0.6 * cos(12.0 * (v) + vec4(params[1].x, params[2].y, params[3].z, 0.0))) vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return vec3( abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x ); } vec3 hsv2rgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } // Color palette generation vec3 palette(in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d) { return a + b * cos(6.28318 * (c * t + d)); } // Texture value and gradient utility functions float getVal(vec2 uv) { return length(texture(iChannel2, uv).xyz); } vec2 getGrad(vec2 uv, float delta) { vec2 d = vec2(delta, 0.0); return vec2( getVal(uv + d.xy) - getVal(uv - d.xy), getVal(uv + d.yx) - getVal(uv - d.yx) ) / delta; } // Main shader logic void mainImage(out vec4 fragColor, in vec2 fragCoord) { // Calculate UV coordinates vec2 uv = fragCoord.xy / iResolution.xy; // Calculate normal and gradient vec3 n = vec3(getGrad(uv, 1.0 / iResolution.y), 150.0); n = normalize(n); // Lighting calculations vec3 light = normalize(vec3(1.0, 0.8, 0.6)); // Adjusted light direction for variety float diff = clamp(dot(n, light), 0.0, 1.0) * 1.5; // Amplify diffuse light float spec = clamp(dot(reflect(light, n), vec3(0.0, 0.0, 1.0)), 0.0, 1.0); spec = pow(spec, 15.0) * 4.8; // Sharpen and boost specular highlights // Apply vibrant palette vec3 baseColor = palette( diff, vec3(0.2, 0.3, 0.4), // Base color tones vec3(0.81, 0.8, 0.5), // Vivid color range vec3(1.0, 1.0, 1.0), // Color oscillation vec3(params[1].r, params[2].r, params[3].r) // Offset ); // Increase vibrancy using HSV vec3 hsvColor = rgb2hsv(baseColor); hsvColor.y *= 1.0; // Increase saturation hsvColor.z *= 1.0; // Boost brightness vec3 vibrantColor = hsv2rgb(hsvColor); // Final color composition vec3 finalColor = vibrantColor * (1.0 + spec); // Combine vibrant colors and highlights fragColor = vec4(finalColor, 1.0); // Output with alpha } // Entry point for WebGL shader execution void main() { mainImage(fragColor, gl_FragCoord.xy); }`; } }); // src/shaders/rt.vert.glsl var require_rt_vert = __commonJS({ "src/shaders/rt.vert.glsl"(exports, module) { module.exports = `#version 300 es precision highp float; // Uniform block configuration layout(std140, column_major) uniform; // Input vertex position layout(location = 0) in vec3 position; // Main vertex shader entry point void main() { gl_Position = vec4(position, 1.0); }`; } }); // src/shaders/blit.frag.glsl var require_blit_frag = __commonJS({ "src/shaders/blit.frag.glsl"(exports, module) { module.exports = `#version 300 es precision highp float; // Input texture for blitting uniform sampler2D blitTex; uniform vec3 iResolution; // Output fragment color out vec4 fragColor; // Color enhancement functions vec3 vibranceAdjust(vec3 color) { // Increase color saturation while preserving skin tones float average = (color.r + color.g + color.b) / 3.0; float maxColor = max(color.r, max(color.g, color.b)); float minColor = min(color.r, min(color.g, color.b)); // Enhance vibrance based on color deviation from average float vibrance = 0.5; // Adjust this value to control vibrance intensity float amount = (maxColor - average) * vibrance; return mix(color, vec3(maxColor), amount); } vec3 contrastAdjustment(vec3 color) { // Increase contrast by spreading out color values float contrast = 1.3; // Adjust this value to control contrast return ((color - 0.5) * contrast) + 0.5; } // Main fragment shader entry point void main() { // Fetch the pixel at the current fragment coordinate vec4 originalColor = texelFetch(blitTex, ivec2(gl_FragCoord.xy), 0); // Apply color enhancements vec3 enhancedColor = originalColor.rgb; enhancedColor = vibranceAdjust(enhancedColor); enhancedColor = contrastAdjustment(enhancedColor); // Optional: Slight color temperature warmth enhancedColor *= vec3(1.1, 1.05, 1.0); // Clamp to prevent over-saturation fragColor = vec4(clamp(enhancedColor, 0.0, 1.0), originalColor.a); }`; } }); // src/lib.ts var { ARRAY_BUFFER, COLOR_ATTACHMENT0, COLOR_BUFFER_BIT, COMPILE_STATUS, DEPTH_ATTACHMENT, DEPTH_BUFFER_BIT, DEPTH_COMPONENT32F, FLOAT, FRAGMENT_SHADER, FRAMEBUFFER, LINEAR, LINEAR_MIPMAP_LINEAR, NEAREST, RENDERBUFFER, REPEAT, RGBA, RGBA32F, STATIC_DRAW, TEXTURE_2D, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER, TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE0, UNPACK_FLIP_Y_WEBGL, UNSIGNED_BYTE, VERTEX_SHADER } = WebGL2RenderingContext; function createWebGL2Canvas(width, height) { const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const glContext = canvas.getContext("webgl2", { antialias: false, preserveDrawingBuffer: true, alpha: false }); if (!glContext) throw new Error("Could not create WebGL2 context"); const context = glContext; var extC = context.getExtension("EXT_color_buffer_float"); var extF = context.getExtension("OES_texture_float"); const canvasWidth = canvas.width; const canvasHeight = canvas.height; console.log(canvasHeight + "hi"); return { canvas, context, canvasHeight, canvasWidth }; } function createRandomTexture(rng) { const { canvas, canvasHeight, canvasWidth } = createWebGL2Canvas(window.outerWidth + 500, window.outerHeight + 200); const data = new Uint8Array(canvasWidth * canvasHeight * 4); console.log(canvasHeight); const randomTex = { data, type: "u8", width: canvasWidth, height: canvasHeight }; for (let y = 0; y < canvasHeight; y++) { for (let x = 0; x < canvasWidth; x++) { const off = y * canvasWidth + x | 0; const off2 = (y + 17) % canvasHeight * canvasWidth + (x + 37) % canvasWidth | 0; const v = canvasWidth * rng() | 0; data[off * 4] = data[off2 * 4 + 1] = v; data[off * 4 + 2] = canvasWidth * rng() | 0; data[off * 4 + 3] = canvasWidth * rng() | 0; } } return randomTex; } function loadShaders(gl, rtVert, width, height, iResolution, shaderSources) { const programs = shaderSources.map((shaderSrc, i) => { const pixelBuffer = { data: null, type: "f32", width, height }; const program = createProgram(gl, rtVert, shaderSrc); const texture = createTexture(gl, pixelBuffer, i + 1); gl.useProgram(program); u3fv(gl, program, "iResolution", iResolution); u1i(gl, program, "iChannel0", 0); u1i(gl, program, "iChannel1", 1); u1i(gl, program, "iChannel2", 2); u1i(gl, program, "iChannel3", 3); u1i(gl, program, "iChannel4", 4); const pos = gl.getAttribLocation(program, "position"); gl.enableVertexAttribArray(pos); gl.vertexAttribPointer(pos, 3, gl.FLOAT, false, 0, 0); const p = { program, pixelBuffer, texture }; return p; }); return programs; } function resize(w, h, gl, framebuffer, programs, iResolution) { gl.canvas.width = w; gl.canvas.height = h; iResolution[0] = w; iResolution[1] = h; gl.viewport(0, 0, w, h); programs.forEach((p, i) => { gl.useProgram(p.program); u3fv(gl, p.program, "iResolution", iResolution); p.pixelBuffer.width = w; p.pixelBuffer.height = h; resizeTexture(gl, p.texture, p.pixelBuffer, i + 1); }); resizeFramebuffer(gl, framebuffer, w, h); gl.clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT); framebuffer.width = w; framebuffer.height = h; } function copyFramebufferToTexture(gl, unit, width, height) { gl.activeTexture(TEXTURE0 + unit); gl.copyTexImage2D(TEXTURE_2D, 0, RGBA32F, 0, 0, width, height, 0); } function resizeFramebuffer(gl, fb, width, height) { const { framebuffer, renderbufferDepth, renderbufferColor } = fb; gl.bindFramebuffer(FRAMEBUFFER, framebuffer); gl.bindRenderbuffer(RENDERBUFFER, renderbufferDepth); gl.renderbufferStorage(RENDERBUFFER, DEPTH_COMPONENT32F, width, height); gl.bindRenderbuffer(RENDERBUFFER, renderbufferColor); gl.renderbufferStorage(RENDERBUFFER, RGBA32F, width, height); gl.clear(DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT); gl.bindRenderbuffer(RENDERBUFFER, null); gl.bindFramebuffer(FRAMEBUFFER, null); return __spreadProps(__spreadValues({}, fb), { width, height }); } function createFramebuffer(gl, width, height) { const framebuffer = gl.createFramebuffer(); if (!framebuffer) throw new Error("Unable to create framebuffer"); gl.bindFramebuffer(FRAMEBUFFER, framebuffer); const renderbufferDepth = gl.createRenderbuffer(); if (!renderbufferDepth) throw new Error("Unable to create renderbufferDepth"); gl.bindRenderbuffer(RENDERBUFFER, renderbufferDepth); gl.renderbufferStorage(RENDERBUFFER, DEPTH_COMPONENT32F, width, height); gl.framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER, renderbufferDepth); const renderbufferColor = gl.createRenderbuffer(); if (!renderbufferColor) throw new Error("Unable to create renderbufferColor"); gl.bindRenderbuffer(RENDERBUFFER, renderbufferColor); gl.renderbufferStorage(RENDERBUFFER, RGBA32F, width, height); gl.framebufferRenderbuffer(FRAMEBUFFER, COLOR_ATTACHMENT0, RENDERBUFFER, renderbufferColor); gl.bindRenderbuffer(RENDERBUFFER, null); gl.bindFramebuffer(FRAMEBUFFER, null); return { framebuffer, renderbufferDepth, renderbufferColor, width, height }; } function resizeTexture(gl, tex, buf, unit) { gl.activeTexture(TEXTURE0 + (unit || 0)); gl.bindTexture(TEXTURE_2D, tex); gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, false); if (buf.type === "f32") { gl.texImage2D(TEXTURE_2D, 0, RGBA32F, buf.width, buf.height, 0, RGBA, FLOAT, buf.data); gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST); gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST); gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, REPEAT); gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, REPEAT); } else { gl.texImage2D(TEXTURE_2D, 0, RGBA, buf.width, buf.height, 0, RGBA, UNSIGNED_BYTE, buf.data); gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, LINEAR); gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR_MIPMAP_LINEAR); gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, REPEAT); gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, REPEAT); gl.generateMipmap(TEXTURE_2D); } } function createTexture(gl, buf, unit) { const tex = gl.createTexture(); if (!tex) throw new Error("Unable to create texture"); resizeTexture(gl, tex, buf, unit); return tex; } function createBuffer(gl) { var buf = gl.createBuffer(); gl.bindBuffer(ARRAY_BUFFER, buf); var arr = new Float32Array([ -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, -1, 0, 1, 1, 0, -1, 1, 0 ]); gl.bufferData(ARRAY_BUFFER, arr, STATIC_DRAW); return buf; } function createShader(gl, source, type) { var s = source; if (typeof source === "string") { const shader = gl.createShader(type); if (!shader) throw new Error("Unable to create shader"); s = shader; gl.shaderSource(s, source); gl.compileShader(s); if (!gl.getShaderParameter(s, COMPILE_STATUS)) { throw new Error(gl.getShaderInfoLog(s) || "No shader info log"); } } return s; } function createProgram(gl, vert, frag) { var t0 = Date.now(); var p = gl.createProgram(); if (!p) throw new Error("Failed to create program"); var vs = createShader(gl, vert, VERTEX_SHADER); var fs = createShader(gl, frag, FRAGMENT_SHADER); gl.attachShader(p, vs); gl.attachShader(p, fs); gl.linkProgram(p); if (DEBUG) console.log("Create program: " + (Date.now() - t0) + " ms"); return p; } function getUniform(gl, p, name) { if (!p.uniforms) p.uniforms = {}; if (!p.uniforms[name]) p.uniforms[name] = gl.getUniformLocation(p, name); return p.uniforms[name]; } function u3fv(gl, p, name, v) { gl.uniform3fv(getUniform(gl, p, name), v); } function u1f(gl, p, name, x) { gl.uniform1f(getUniform(gl, p, name), x); } function u1i(gl, p, name, x) { gl.uniform1i(getUniform(gl, p, name), x); } function vec3(x = 0, y = x, z = y) { var v = new Float32Array(3); v[0] = x; v[1] = y; v[2] = z; return v; } var rc = vec3(0); var traceTmp = vec3(0); var up = vec3(0, 1, 0); var uvd = vec3(0); var xaxis = vec3(0); var yaxis = vec3(0); var zaxis = vec3(0); function download(filename, blob) { const a = document.createElement("a"); a.download = filename; a.href = typeof blob === "string" ? blob : URL.createObjectURL(blob); a.click(); URL.revokeObjectURL(a.href); } // src/runner.ts window.DEBUG = false; var ShaderSources = [ require_buffer_0(), require_buffer_1(), require_buffer_2() ]; init(ShaderSources, window.innerWidth * devicePixelRatio, window.innerHeight * devicePixelRatio); function init(shaderSources, width, height) { return __async(this, null, function* () { const randomTex = createRandomTexture(fxrand); const { canvas: glc, context: gl } = createWebGL2Canvas(width, height); document.body.appendChild(glc); const buf = createBuffer(gl); const rTex = createTexture(gl, randomTex, 0); const iResolution = vec3(glc.width, glc.height, 1); const framebuffer = createFramebuffer(gl, width, height); const rtVert = require_rt_vert(); const blitFrag = require_blit_frag(); const blitProgram = createProgram(gl, rtVert, blitFrag); let programs = loadShaders(gl, rtVert, width, height, iResolution, shaderSources); resize(width, height, gl, framebuffer, programs, iResolution); gl.useProgram(blitProgram); u1i(gl, blitProgram, "blitTex", programs.length); let t = 0; let frame = 0; let frameCount = 0; const params = new Float32Array(14 * 3); reseed(); this.mouse = { x: 0.5, y: 0.5 }; // Add the mousemove event listener window.addEventListener("mousemove", (e) => { this.mouse.x = e.clientX / window.innerWidth; this.mouse.y = e.clientY / window.innerHeight; }); let continuousMode = true; function reseed() { frame = 0; for (let i = 0; i <= params.length; i++) params[i] = $fx.rand(); console.log(params[1] + "param1"); console.log(params[2] + "param2"); console.log(params[3] + "param3"); frameCount = 100 + Math.floor($fx.rand() * 100); } let tickRequested = true; tick(); function draw(frame2, frameCount2, t2, globalTime) { gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer.framebuffer); if (frame2 === 0) { programs.forEach((p, i) => { gl.useProgram(p.program); copyFramebufferToTexture(gl, i + 1, width, height); u1i(gl, p.program, "frameCount", frameCount2); u3fv(gl, p.program, "params", params); }); } programs.forEach((p, i) => { gl.useProgram(p.program); u1f(gl, p.program, "iGlobalTime", globalTime); u1f(gl, p.program, "iTime", t2); u1i(gl, p.program, "iFrame", frame2); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, 6); copyFramebufferToTexture(gl, i + 1, width, height); }); //console.log(globalTime + "global time"); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.useProgram(blitProgram); gl.drawArrays(gl.TRIANGLES, 0, 6); } function tick() { if (tickRequested) { tickRequested = false; const canvasBBox = document.body.getBoundingClientRect(); const w = canvasBBox.width * devicePixelRatio; const h = canvasBBox.height * devicePixelRatio; if (w !== width || h !== height) { width = w; height = h; resize(width, height, gl, framebuffer, programs, iResolution); } gl.bindFramebuffer(gl.FRAMEBUFFER, null); if (continuousMode) document.body.classList.remove("rendering"); else document.body.classList.add("rendering"); draw(frame, frameCount, t, Date.now() / 1e3); t += 16; frame++; tickRequested = true; if (frame === 0) { tickRequested = false; document.body.classList.remove("rendering"); if (continuousMode) { reseed(); tickRequested = true; } if (isFxpreview) setTimeout(fxpreview, 300); } } requestAnimationFrame(tick); } glc.ondblclick = function(ev) { ev.preventDefault(); reseed(); document.body.classList.add("rendering"); setTimeout(() => { tickRequested = true; }, 300); }; window.onkeydown = function(ev) { if (ev.keyCode === 32) { reseed(); continuousMode = !continuousMode; tickRequested = true; } if (ev.keyCode === 83) { glc.toBlob((blob) => { if (!blob) throw new Error("Canvas toBlob failed"); download(document.title + ".jpg", blob); }, "image/jpeg", 0.95); } }; window.onresize = function(ev) { frame = 0; tickRequested = true; }; }); } })();