shaderpad 1.0.0-beta.68 → 1.0.0-beta.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ import{a as b}from"./chunk-LXQJ4NRK.mjs";import{a as g}from"./chunk-N45SWDLN.mjs";var O=`#version 300 es
2
+ in vec2 a_position;
3
+ out vec2 v_uv;
4
+ void main() {
5
+ gl_Position = vec4(a_position, 0.0, 1.0);
6
+ v_uv = a_position * 0.5 + 0.5;
7
+ }`,H=[["8UI","UNSIGNED_BYTE"],["8I","BYTE"],["16UI","UNSIGNED_SHORT"],["16I","SHORT"],["16F","HALF_FLOAT"],["32UI","UNSIGNED_INT"],["32I","INT"],["32F","FLOAT"],["8","UNSIGNED_BYTE"]],w={float:"f",int:"i",uint:"ui"};function M(l){return l&&H.find(([t])=>l.endsWith(t))?.[1]}var R=Symbol("u_history"),T=Symbol("__SHADERPAD_BUFFER"),v=new WeakMap;function N(l,t){if(!t?.length)return l;let e=l.split(`
8
+ `),r=e.findLastIndex(i=>{let s=i.trimStart();return s.startsWith("precision ")||s.startsWith("#version ")})+1;return e.splice(r,0,...t),e.join(`
9
+ `)}function P(l){return l instanceof WebGLTexture?{width:0,height:0}:l instanceof S?{width:l.canvas.width,height:l.canvas.height}:l instanceof HTMLVideoElement?{width:l.videoWidth,height:l.videoHeight}:l instanceof HTMLImageElement?{width:l.naturalWidth??l.width,height:l.naturalHeight??l.height}:{width:l.width,height:l.height}}function F(l){return typeof l=="symbol"?l.description??"":l}var S=class l{isHeadless=!1;isTouchDevice=!1;gl;glHelpers;uniforms=new Map;textures=new Map;textureUnitPool;buffer=null;vao=null;program=null;animationFrameId;eventListeners=new Map;frame=0;startTime=Number.NaN;isPlaying=!1;cursorPosition=[.5,.5];clickPosition=[.5,.5];isMouseDown=!1;canvas;resolutionObserver=null;hooks=new Map;historyDepth=0;textureOptions;cursorTarget;intermediateFbo=null;constructor(t,{canvas:e,plugins:r,history:i,cursorTarget:s,...a}={}){if(e&&"getContext"in e)this.canvas=e;else{let{width:c=1,height:m=1}=e||{};this.canvas=new OffscreenCanvas(c,m),this.isHeadless=!0}let n=this.canvas.getContext("webgl2",{antialias:!1});if(!n)throw g(0,!1);this.gl=n,this.glHelpers={typeToArray:new Map([[n.FLOAT,Float32Array],[n.HALF_FLOAT,Uint16Array],[n.UNSIGNED_SHORT,Uint16Array],[n.SHORT,Int16Array],[n.BYTE,Int8Array],[n.UNSIGNED_INT,Uint32Array],[n.INT,Int32Array]]),typeToInternalFormatString:new Map([[n.FLOAT,"RGBA32F"],[n.HALF_FLOAT,"RGBA16F"],[n.UNSIGNED_SHORT,"RGBA32UI"],[n.SHORT,"RGBA32I"],[n.BYTE,"RGBA32I"],[n.UNSIGNED_INT,"RGBA32UI"],[n.INT,"RGBA32I"]]),unsignedIntTypes:new Set([n.UNSIGNED_BYTE,n.UNSIGNED_SHORT,n.UNSIGNED_INT])};let o=v.get(this.canvas);o||(o={textureUnitPool:{free:[],next:0,max:n.getParameter(n.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},instances:new Set([this])},v.set(this.canvas,o)),this.textureUnitPool=o.textureUnitPool,o.instances.add(this),this.textureOptions=a,i&&(this.historyDepth=i),this.cursorTarget=s??(this.canvas instanceof HTMLCanvasElement?this.canvas:void 0),this.animationFrameId=null;let u=[];r&&r.forEach(c=>c(this,{gl:n,canvas:this.canvas,injectGLSL:m=>{u.push(m)},emitHook:this.emitHook.bind(this),updateTexturesInternal:this.updateTexturesInternal.bind(this)}));let h=this.gl.createProgram();if(!h)throw g(1);this.program=h;let f=this.createShader(this.gl.VERTEX_SHADER,O),x=this.createShader(n.FRAGMENT_SHADER,N(t,u));if(n.attachShader(h,f),n.attachShader(h,x),n.bindAttribLocation(h,0,"a_position"),n.linkProgram(h),n.deleteShader(f),n.deleteShader(x),!n.getProgramParameter(h,n.LINK_STATUS)){let c=n.getProgramInfoLog(h),m=g(2,!1);throw n.deleteProgram(h),m}if(this.vao=n.createVertexArray(),n.bindVertexArray(this.vao),this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,this.buffer),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),n.STATIC_DRAW),n.enableVertexAttribArray(0),n.vertexAttribPointer(0,2,n.FLOAT,!1,0,0),n.viewport(0,0,n.drawingBufferWidth,n.drawingBufferHeight),n.useProgram(h),this.canvas instanceof HTMLCanvasElement)this.resolutionObserver=new MutationObserver(()=>this.updateResolution()),this.resolutionObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]});else{let c=m=>{let d=Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype,m),p=this.canvas;Object.defineProperty(p,m,{get:()=>d.get.call(p),set:_=>{d.set.call(p,_);let E=v.get(p);if(E)for(let A of E.instances)A.updateResolution()},configurable:d.configurable,enumerable:d.enumerable})};c("width"),c("height")}this.updateResolution(),this.initializeUniform("u_cursor","float",this.cursorPosition,{allowMissing:!0}),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0],{allowMissing:!0}),this.initializeUniform("u_time","float",0,{allowMissing:!0}),this.initializeUniform("u_frame","int",0,{allowMissing:!0}),this._initializeTexture(T,this.canvas,{...this.textureOptions}),this.intermediateFbo=n.createFramebuffer(),this.bindIntermediate(),n.bindFramebuffer(n.FRAMEBUFFER,null),this.historyDepth>0&&this._initializeTexture(R,this.canvas,{history:this.historyDepth,...this.textureOptions}),this.cursorTarget&&this.addEventListeners(),this.emitHook("_init")}resolveGLConstant(t){let e=this.gl[t];if(e===void 0)throw g(3,!1);return e}emitHook(t,...e){this.hooks.get(t)?.forEach(r=>r.call(this,...e))}on(t,e){this.hooks.has(t)||this.hooks.set(t,[]),this.hooks.get(t).push(e)}off(t,e){let r=this.hooks.get(t);if(r){let i=r.indexOf(e);i>=0&&r.splice(i,1)}}createShader(t,e){let r=this.gl.createShader(t);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS)){let i=this.gl.getShaderInfoLog(r),s=t===this.gl.VERTEX_SHADER?"vertex":"fragment",a=g(4,!1);throw this.gl.deleteShader(r),a}return r}getCursorTargetRect(){let t=this.cursorTarget;return t===window?{left:0,top:0,width:window.innerWidth,height:window.innerHeight}:t.getBoundingClientRect()}addEventListeners(){if(!this.cursorTarget)return;let t=(r,i)=>{if(!this.uniforms.has("u_cursor"))return;let s=this.getCursorTargetRect(),a=(r-s.left)/s.width,n=1-(i-s.top)/s.height;this.cursorPosition[0]=Math.max(0,Math.min(1,a)),this.cursorPosition[1]=Math.max(0,Math.min(1,n)),this.updateUniforms({u_cursor:this.cursorPosition})},e=(r,i,s)=>{if(this.uniforms.has("u_click")){if(this.isMouseDown=r,r){let a=this.getCursorTargetRect(),n=i,o=s;this.clickPosition[0]=Math.max(0,Math.min(1,(n-a.left)/a.width)),this.clickPosition[1]=Math.max(0,Math.min(1,1-(o-a.top)/a.height))}this.updateUniforms({u_click:[...this.clickPosition,this.isMouseDown?1:0]})}};this.eventListeners.set("mousemove",r=>{let i=r;this.isTouchDevice||t(i.clientX,i.clientY)}),this.eventListeners.set("mousedown",r=>{let i=r;this.isTouchDevice||i.button===0&&(this.isMouseDown=!0,e(!0,i.clientX,i.clientY))}),this.eventListeners.set("mouseup",r=>{let i=r;this.isTouchDevice||i.button===0&&e(!1)}),this.eventListeners.set("touchmove",r=>{let i=r;i.touches.length>0&&t(i.touches[0].clientX,i.touches[0].clientY)}),this.eventListeners.set("touchstart",r=>{let i=r;this.isTouchDevice=!0,i.touches.length>0&&(t(i.touches[0].clientX,i.touches[0].clientY),e(!0,i.touches[0].clientX,i.touches[0].clientY))}),this.eventListeners.set("touchend",r=>{r.touches.length===0&&e(!1)}),this.eventListeners.forEach((r,i)=>{this.cursorTarget.addEventListener(i,r)})}updateResolution(){let t=[this.gl.drawingBufferWidth,this.gl.drawingBufferHeight];this.gl.viewport(0,0,...t),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:t}):this.initializeUniform("u_resolution","float",t,{allowMissing:!0}),this.resizeTexture(T,...t),this.historyDepth>0&&this.resizeTexture(R,...t),this.emitHook("updateResolution",...t)}resizeTexture(t,e,r){let i=this.textures.get(t);if(!i||i.width===e&&i.height===r)return;this.gl.deleteTexture(i.texture),i.width=e,i.height=r;let{texture:s}=this.createTexture(t,i);i.texture=s,i.history&&(i.history.writeIndex=0,this.clearHistoryTextureLayers(i))}reserveTextureUnit(t){let e=this.textures.get(t);if(e)return e.unitIndex;if(this.textureUnitPool.free.length>0)return this.textureUnitPool.free.pop();if(this.textureUnitPool.next>=this.textureUnitPool.max)throw g(5,!1);return this.textureUnitPool.next++}resolveTextureOptions(t){let{gl:e}=this,r=t?.internalFormat,i=t?.type??M(r)??"UNSIGNED_BYTE",s=this.resolveGLConstant(i),a=r??this.glHelpers.typeToInternalFormatString.get(s)??"RGBA8",n=/^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(a),o=t?.format??(n?"RGBA_INTEGER":"RGBA"),u={type:s,format:this.resolveGLConstant(o),internalFormat:this.resolveGLConstant(a),minFilter:this.resolveGLConstant(t?.minFilter??"LINEAR"),magFilter:this.resolveGLConstant(t?.magFilter??"LINEAR"),wrapS:this.resolveGLConstant(t?.wrapS??"CLAMP_TO_EDGE"),wrapT:this.resolveGLConstant(t?.wrapT??"CLAMP_TO_EDGE"),preserveY:t?.preserveY,isIntegerColorFormat:n};if((u.internalFormat===e.RGBA16F||u.internalFormat===e.RGBA32F)&&!e.getExtension("EXT_color_buffer_float"))throw g(6,!1);return u}getPixelArray(t,e){let r=this.glHelpers.typeToArray.get(t)??Uint8Array;return new r(e)}isNotRgba(t){return t!==this.gl.RGBA&&t!==this.gl.RGBA_INTEGER}clearHistoryTextureLayers(t){if(!t.history)return;let e=this.gl,{type:r,format:i}=t.options,s=this.getPixelArray(r,t.width*t.height*4);e.activeTexture(e.TEXTURE0+t.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,t.texture);let a=this.isNotRgba(i),n;a&&(n=e.getParameter(e.UNPACK_ALIGNMENT),e.pixelStorei(e.UNPACK_ALIGNMENT,1));for(let o=0;o<t.history.depth;++o)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,o,t.width,t.height,1,i,r,s);a&&e.pixelStorei(e.UNPACK_ALIGNMENT,n)}initializeUniform(t,e,r,i){let s=i?.arrayLength,a=i?.allowMissing??!1;if(this.uniforms.has(t))throw g(7,!1);if(!w[e])throw g(8,!1);if(s&&!(Array.isArray(r)&&r.length===s))throw g(9,!1);let n=this.gl.getUniformLocation(this.program,t);if(!n&&s&&(n=this.gl.getUniformLocation(this.program,`${t}[0]`)),!n){if(a)return;throw g(19,!1)}let o=s?r[0]:r,u=Array.isArray(o)?o.length:1;this.uniforms.set(t,{type:e,length:u,location:n,arrayLength:s});try{this.updateUniforms({[t]:r})}catch(h){throw this.uniforms.delete(t),h}this.emitHook("initializeUniform",...arguments)}updateUniforms(t,e){this.gl.useProgram(this.program),Object.entries(t).forEach(([r,i])=>{let s=this.uniforms.get(r);if(!s){if(e?.allowMissing)return;throw g(20,!1)}let a=`uniform${s.length}${w[s.type]}`;if(s.arrayLength){if(!Array.isArray(i))throw g(10,!1);let n=i.length;if(!n)return;if(n>s.arrayLength)throw g(11,!1);if(i.some(f=>(Array.isArray(f)?f.length:1)!==s.length))throw g(12,!1);let o=i.flat(),u=s.type==="float"?new Float32Array(o):s.type==="uint"?new Uint32Array(o):new Int32Array(o),h=s.location;if(e?.startIndex){let f=this.gl.getUniformLocation(this.program,`${r}[${e.startIndex}]`);if(!f)throw g(13,!1);h=f}this.gl[a+"v"](h,u)}else{Array.isArray(i)||(i=[i]);let n=i;if(n.length!==s.length)throw g(14,!1);this.gl[a](s.location,...n)}}),this.emitHook("updateUniforms",...arguments)}createTexture(t,e){let{width:r,height:i}=e,s=e.history?.depth??0,a=this.gl.createTexture();if(!a)throw g(15,!1);let n=e.unitIndex;if(typeof n!="number")try{n=this.reserveTextureUnit(t)}catch(f){throw this.gl.deleteTexture(a),f}let o=s>0,u=o?this.gl.TEXTURE_2D_ARRAY:this.gl.TEXTURE_2D,{options:h}=e;return this.gl.activeTexture(this.gl.TEXTURE0+n),this.gl.bindTexture(u,a),this.gl.texParameteri(u,this.gl.TEXTURE_WRAP_S,h.wrapS),this.gl.texParameteri(u,this.gl.TEXTURE_WRAP_T,h.wrapT),this.gl.texParameteri(u,this.gl.TEXTURE_MIN_FILTER,h.minFilter),this.gl.texParameteri(u,this.gl.TEXTURE_MAG_FILTER,h.magFilter),o?this.gl.texStorage3D(u,1,h.internalFormat,r,i,s):t===T&&this.gl.texImage2D(this.gl.TEXTURE_2D,0,h.internalFormat,r,i,0,h.format,h.type,null),{texture:a,unitIndex:n}}_initializeTexture(t,e,r){if(this.textures.has(t))throw g(16,!1);let{history:i=0,...s}=r??{},{width:a,height:n}=P(e);if(!a||!n)throw g(17,!1);let o={width:a,height:n,options:e instanceof l&&Object.keys(s).length===0&&e.textures.has(T)?e.textures.get(T).options:this.resolveTextureOptions(s)};i>0&&(o.history={depth:i,writeIndex:0});let{texture:u,unitIndex:h}=this.createTexture(t,o),f={texture:u,unitIndex:h,...o};i>0&&(this.initializeUniform(`${F(t)}FrameOffset`,"int",0,{allowMissing:!0}),this.clearHistoryTextureLayers(f)),this.textures.set(t,f),t!==T&&t!==R&&this.updateTexture(t,e),this.gl.useProgram(this.program);let x=this.gl.getUniformLocation(this.program,F(t));x&&this.gl.uniform1i(x,h)}initializeTexture(t,e,r){let i=r?.history!=null&&r.history>0?{...r,history:r.history+1}:r;this._initializeTexture(t,e,i),this.emitHook("initializeTexture",...arguments)}updateTextures(t,e){this.updateTexturesInternal(t,e),this.emitHook("updateTextures",...arguments)}updateTexturesInternal(t,e){Object.entries(t).forEach(([r,i])=>{this.updateTexture(r,i,e)})}updateTexture(t,e,r){let i=this.textures.get(t);if(!i)throw g(18,!1);if(e instanceof WebGLTexture){this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,e);return}let s=e;if(e instanceof l){let m=e.textures.get(T),d=m.width,p=m.height;if(e.gl===this.gl){if(!i.history){this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,m.texture);return}let{depth:L}=i.history,U=r?.historyWriteIndex===void 0?[i.history.writeIndex]:Array.isArray(r?.historyWriteIndex)?r.historyWriteIndex.map(D=>b(D,L)):[b(r.historyWriteIndex,L)];this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER,e.intermediateFbo),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture);for(let D of U)this.gl.copyTexSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,D,0,0,d,p);this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER,null),this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture);let G=`${F(t)}FrameOffset`;this.updateUniforms({[G]:U[U.length-1]},{allowMissing:!0}),r?.historyWriteIndex===void 0&&(i.history.writeIndex=(i.history.writeIndex+1)%L);return}let{width:_,height:E,options:{format:A,type:I}}=m,y=this.getPixelArray(I,_*E*4);e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,e.intermediateFbo),e.gl.readPixels(0,0,_,E,A,I,y),e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,null),s={data:y,width:_,height:E}}let{width:a,height:n}=P(s);if(!a||!n)return;let o="isPartial"in s&&s.isPartial;o||this.resizeTexture(t,a,n);let u="data"in s&&s.data,h=!u&&!i.options?.preserveY,f=this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL),x=u&&this.isNotRgba(i.options.format),c;if(x&&(c=this.gl.getParameter(this.gl.UNPACK_ALIGNMENT),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1)),i.history){if(this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture),!r?.skipHistoryWrite){let{depth:m}=i.history,d=r?.historyWriteIndex===void 0?[i.history.writeIndex]:Array.isArray(r.historyWriteIndex)?r.historyWriteIndex.map(y=>b(y,m)):[b(r.historyWriteIndex,m)];this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,h);let p=s,_=p.data??s,E=o?p.x??0:0,A=o?p.y??0:0;for(let y of d)this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,E,A,y,a,n,1,i.options.format,i.options.type,_);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,f);let I=`${F(t)}FrameOffset`;this.updateUniforms({[I]:d[d.length-1]}),r?.historyWriteIndex===void 0&&(i.history.writeIndex=(i.history.writeIndex+1)%m)}}else{if(this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,i.texture),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,h),o){let m=s;this.gl.texSubImage2D(this.gl.TEXTURE_2D,0,m.x??0,m.y??0,a,n,i.options.format,i.options.type,m.data)}else this.gl.texImage2D(this.gl.TEXTURE_2D,0,i.options.internalFormat,a,n,0,i.options.format,i.options.type,s.data??s);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,f)}x&&this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,c)}bindIntermediate(){let t=this.gl,e=this.textures.get(T);t.bindFramebuffer(t.FRAMEBUFFER,this.intermediateFbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,e.texture,0)}clear(){this.bindIntermediate();let t=this.gl,e=this.textures.get(T);if(e.options.isIntegerColorFormat){let r=e.options.type;this.glHelpers.unsignedIntTypes.has(r)?t.clearBufferuiv(t.COLOR,0,new Uint32Array(4)):t.clearBufferiv(t.COLOR,0,new Int32Array(4))}else t.clear(t.COLOR_BUFFER_BIT)}draw(t){this.emitHook("beforeDraw",...arguments);let e=this.gl,r=e.drawingBufferWidth,i=e.drawingBufferHeight;t?.skipClear?this.bindIntermediate():this.clear(),e.useProgram(this.program),e.bindVertexArray(this.vao),e.viewport(0,0,r,i),e.drawArrays(e.TRIANGLES,0,3),this.isHeadless||this.textures.get(T).options.isIntegerColorFormat||(e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,r,i,0,0,r,i,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null)),this.emitHook("afterDraw",...arguments)}step(t){Number.isFinite(this.startTime)||(this.startTime=performance.now()),this._step((performance.now()-this.startTime)/1e3,t)}_step(t,e){this.emitHook("beforeStep",t,this.frame,e);let r={};this.uniforms.has("u_time")&&(r.u_time=t),this.uniforms.has("u_frame")&&(r.u_frame=this.frame),this.updateUniforms(r),this.draw(e);let i=this.textures.get(R);if(i&&!e?.skipHistoryWrite){let{writeIndex:s,depth:a}=i.history,n=this.gl;n.bindFramebuffer(n.READ_FRAMEBUFFER,this.intermediateFbo),n.bindTexture(n.TEXTURE_2D_ARRAY,i.texture),n.copyTexSubImage3D(n.TEXTURE_2D_ARRAY,0,0,0,s,0,0,n.drawingBufferWidth,n.drawingBufferHeight),n.bindFramebuffer(n.READ_FRAMEBUFFER,null);let o=(s+1)%a;this.updateUniforms({[`${F(R)}FrameOffset`]:o},{allowMissing:!0}),i.history.writeIndex=o}++this.frame,this.emitHook("afterStep",t,this.frame,e)}play(t){this._pause(),Number.isFinite(this.startTime)||(this.startTime=performance.now()),this.isPlaying=!0;let e=r=>{r=(r-this.startTime)/1e3;let i=t?.(r,this.frame)??void 0;this._step(r,i),this.isPlaying&&(this.animationFrameId=requestAnimationFrame(e))};this.animationFrameId=requestAnimationFrame(e),this.emitHook("play")}_pause(){let t=this.isPlaying;return this.isPlaying=!1,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),t}pause(){this._pause()&&this.emitHook("pause")}resetFrame(){this.frame=0,this.startTime=performance.now()}reset(){this.resetFrame(),this.textures.forEach(t=>{t.history&&(t.history.writeIndex=0,this.clearHistoryTextureLayers(t))}),this.clear(),this.emitHook("reset")}destroy(){this.emitHook("destroy"),this._pause(),this.cursorTarget&&(this.eventListeners.forEach((e,r)=>{this.cursorTarget.removeEventListener(r,e)}),this.eventListeners.clear()),this.resolutionObserver&&(this.resolutionObserver.disconnect(),this.resolutionObserver=null),this.program&&(this.gl.deleteProgram(this.program),this.program=null),this.intermediateFbo&&(this.gl.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(e=>{this.textureUnitPool.free.push(e.unitIndex),this.gl.deleteTexture(e.texture)}),this.textures.clear();let t=v.get(this.canvas);t&&(t.instances.delete(this),t.instances.size===0&&v.delete(this.canvas)),this.vao&&(this.gl.deleteVertexArray(this.vao),this.vao=null),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.uniforms.clear(),this.hooks.clear()}},W=S;export{W as a};
10
+ //# sourceMappingURL=chunk-GVITL4JU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { safeMod } from './util.js';\nimport spError from './internal/spError.js';\n\nconst DEFAULT_VERTEX_SHADER_SRC = `#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_uv = a_position * 0.5 + 0.5;\n}`;\n\ninterface Uniform {\n\ttype: 'float' | 'int' | 'uint';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n\tarrayLength?: number;\n}\n\ntype GLInternalFormatChannels = 'R' | 'RG' | 'RGB' | 'RGBA';\ntype GLInternalFormatDepth = '8' | '16F' | '32F' | '8UI' | '8I' | '16UI' | '16I' | '32UI' | '32I';\nexport type GLInternalFormatString = `${GLInternalFormatChannels}${GLInternalFormatDepth}`;\n\nexport type GLFormatString =\n\t| 'RED'\n\t| 'RG'\n\t| 'RGB'\n\t| 'RGBA'\n\t| 'RED_INTEGER'\n\t| 'RG_INTEGER'\n\t| 'RGB_INTEGER'\n\t| 'RGBA_INTEGER';\nexport type GLTypeString =\n\t| 'UNSIGNED_BYTE'\n\t| 'BYTE'\n\t| 'FLOAT'\n\t| 'HALF_FLOAT'\n\t| 'UNSIGNED_SHORT'\n\t| 'SHORT'\n\t| 'UNSIGNED_INT'\n\t| 'INT';\nexport type GLFilterString = 'LINEAR' | 'NEAREST';\nexport type GLWrapString = 'CLAMP_TO_EDGE' | 'REPEAT' | 'MIRRORED_REPEAT';\n\nconst FORMAT_TYPE_SUFFIXES: [string, GLTypeString][] = [\n\t['8UI', 'UNSIGNED_BYTE'],\n\t['8I', 'BYTE'],\n\t['16UI', 'UNSIGNED_SHORT'],\n\t['16I', 'SHORT'],\n\t['16F', 'HALF_FLOAT'],\n\t['32UI', 'UNSIGNED_INT'],\n\t['32I', 'INT'],\n\t['32F', 'FLOAT'],\n\t['8', 'UNSIGNED_BYTE'],\n];\n\nconst UNIFORM_TYPE_SUFFIXES: Record<Uniform['type'], string> = {\n\tfloat: 'f',\n\tint: 'i',\n\tuint: 'ui',\n};\n\nfunction typeFromInternalFormatString(internalFormatString?: GLInternalFormatString): GLTypeString | undefined {\n\treturn internalFormatString && FORMAT_TYPE_SUFFIXES.find(([suffix]) => internalFormatString.endsWith(suffix))?.[1];\n}\n\ntype GLConstantString = GLInternalFormatString | GLFormatString | GLTypeString | GLFilterString | GLWrapString;\n\nexport interface TextureOptions {\n\tinternalFormat?: GLInternalFormatString;\n\tformat?: GLFormatString;\n\ttype?: GLTypeString;\n\tminFilter?: GLFilterString;\n\tmagFilter?: GLFilterString;\n\twrapS?: GLWrapString;\n\twrapT?: GLWrapString;\n\tpreserveY?: boolean;\n}\ntype ResolvedTextureOptions = {\n\ttype: number;\n\tformat: number;\n\tinternalFormat: number;\n\tminFilter: number;\n\tmagFilter: number;\n\twrapS: number;\n\twrapT: number;\n\tpreserveY?: boolean;\n\tisIntegerColorFormat: boolean;\n};\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n\twidth: number;\n\theight: number;\n\thistory?: {\n\t\tdepth: number;\n\t\twriteIndex: number;\n\t};\n\toptions: ResolvedTextureOptions;\n}\n\nexport interface CustomTexture {\n\tdata: ArrayBufferView | null;\n\twidth: number;\n\theight: number;\n}\n\nexport interface PartialCustomTexture extends CustomTexture {\n\tisPartial?: boolean;\n\tx?: number;\n\ty?: number;\n}\n\nexport type TextureSource =\n\t| HTMLImageElement\n\t| HTMLVideoElement\n\t| HTMLCanvasElement\n\t| OffscreenCanvas\n\t| ImageBitmap\n\t| WebGLTexture\n\t| CustomTexture\n\t| ShaderPad;\n\n// Custom textures allow partial updates starting from (x, y).\ntype UpdateTextureSource = Exclude<TextureSource, CustomTexture> | PartialCustomTexture;\n\nexport interface PluginContext {\n\tgl: WebGL2RenderingContext;\n\tcanvas: HTMLCanvasElement | OffscreenCanvas;\n\tinjectGLSL: (code: string) => void;\n\temitHook: (name: LifecycleMethod, ...args: any[]) => void;\n\tupdateTexturesInternal: (\n\t\tupdates: Record<string, UpdateTextureSource>,\n\t\toptions?: InternalUpdateTexturesOptions,\n\t) => void;\n}\n\ntype Plugin = (shaderPad: ShaderPad, context: PluginContext) => void;\n\ntype LifecycleMethod =\n\t| '_init'\n\t| 'initializeTexture'\n\t| 'initializeUniform'\n\t| 'updateTextures'\n\t| 'updateUniforms'\n\t| 'beforeStep'\n\t| 'afterStep'\n\t| 'beforeDraw'\n\t| 'afterDraw'\n\t| 'updateResolution'\n\t| 'play'\n\t| 'pause'\n\t| 'reset'\n\t| 'destroy'\n\t| `${string}:${string}`;\n\nexport type RenderTextureOptions = Omit<TextureOptions, 'preserveY'>;\n\nexport interface Options extends RenderTextureOptions {\n\tcanvas?: HTMLCanvasElement | OffscreenCanvas | { width: number; height: number } | null;\n\tplugins?: Plugin[];\n\thistory?: number;\n\tcursorTarget?: Window | Element;\n}\n\nexport interface StepOptions {\n\tskipClear?: boolean;\n\tskipHistoryWrite?: boolean;\n}\n\nexport interface UpdateTexturesOptions {\n\tskipHistoryWrite?: boolean;\n}\n\ntype InternalUpdateTexturesOptions = UpdateTexturesOptions & {\n\thistoryWriteIndex?: number | number[];\n};\n\ntype TextureUnitPool = {\n\tfree: number[];\n\tnext: number;\n\tmax: number;\n};\n\nconst HISTORY_TEXTURE_KEY = Symbol('u_history');\nconst INTERMEDIATE_TEXTURE_KEY = Symbol('__SHADERPAD_BUFFER');\n\nconst canvasRegistry = new WeakMap<\n\tHTMLCanvasElement | OffscreenCanvas,\n\t{ textureUnitPool: TextureUnitPool; instances: Set<ShaderPad> }\n>();\n\nfunction combineShaderCode(shader: string, injections: string[]): string {\n\tif (!injections?.length) return shader;\n\tconst lines = shader.split('\\n');\n\tconst insertAt =\n\t\tlines.findLastIndex(line => {\n\t\t\tconst trimmed = line.trimStart();\n\t\t\treturn trimmed.startsWith('precision ') || trimmed.startsWith('#version ');\n\t\t}) + 1;\n\tlines.splice(insertAt, 0, ...injections);\n\treturn lines.join('\\n');\n}\n\nfunction getSourceDimensions(source: TextureSource): {\n\twidth: number;\n\theight: number;\n} {\n\tif (source instanceof WebGLTexture) {\n\t\treturn { width: 0, height: 0 }; // Invalid - dimensions not readable.\n\t}\n\tif (source instanceof ShaderPad) {\n\t\treturn { width: source.canvas.width, height: source.canvas.height };\n\t}\n\tif (source instanceof HTMLVideoElement) {\n\t\treturn { width: source.videoWidth, height: source.videoHeight };\n\t}\n\tif (source instanceof HTMLImageElement) {\n\t\treturn {\n\t\t\twidth: source.naturalWidth ?? source.width,\n\t\t\theight: source.naturalHeight ?? source.height,\n\t\t};\n\t}\n\t// CustomTexture, HTMLCanvasElement, OffscreenCanvas, ImageBitmap.\n\treturn { width: source.width, height: source.height };\n}\n\nfunction stringFrom(name: string | symbol) {\n\treturn typeof name === 'symbol' ? (name.description ?? '') : name;\n}\n\nclass ShaderPad {\n\tprivate isHeadless = false;\n\tprivate isTouchDevice = false;\n\tprivate gl: WebGL2RenderingContext;\n\tprivate glHelpers!: {\n\t\ttypeToArray: Map<number, new (length: number) => ArrayBufferView>;\n\t\ttypeToInternalFormatString: Map<number, GLInternalFormatString>;\n\t\tunsignedIntTypes: Set<number>;\n\t};\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string | symbol, Texture> = new Map();\n\tprivate textureUnitPool: TextureUnitPool;\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate vao: WebGLVertexArrayObject | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tprivate animationFrameId: number | null;\n\tprivate eventListeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate startTime = Number.NaN;\n\tprivate isPlaying = false;\n\tprivate cursorPosition = [0.5, 0.5];\n\tprivate clickPosition = [0.5, 0.5];\n\tprivate isMouseDown = false;\n\tpublic canvas: HTMLCanvasElement | OffscreenCanvas;\n\tprivate resolutionObserver: MutationObserver | null = null;\n\tprivate hooks: Map<LifecycleMethod, Function[]> = new Map();\n\tprivate historyDepth = 0;\n\tprivate textureOptions: TextureOptions;\n\tprivate cursorTarget: Window | Element | undefined;\n\t// WebGL can’t read from and write to the history texture at the same time.\n\t// We write to an intermediate texture then blit to the history texture.\n\tprivate intermediateFbo: WebGLFramebuffer | null = null;\n\n\tconstructor(\n\t\tfragmentShaderSrc: string,\n\t\t{ canvas, plugins, history, cursorTarget, ...textureOptions }: Options = {},\n\t) {\n\t\tif (canvas && 'getContext' in canvas) {\n\t\t\tthis.canvas = canvas;\n\t\t} else {\n\t\t\tconst { width = 1, height = 1 } = canvas || {};\n\t\t\tthis.canvas = new OffscreenCanvas(width, height);\n\t\t\tthis.isHeadless = true;\n\t\t}\n\n\t\tconst gl = this.canvas.getContext('webgl2', {\n\t\t\tantialias: false,\n\t\t}) as WebGL2RenderingContext;\n\t\tif (!gl) {\n\t\t\tthrow spError(\n\t\t\t\t0,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tcanvasType: this.canvas.constructor.name,\n\t\t\t\t\tisHeadless: this.isHeadless,\n\t\t\t\t\tcanvasWidth: this.canvas.width,\n\t\t\t\t\tcanvasHeight: this.canvas.height,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tthis.gl = gl;\n\t\tthis.glHelpers = {\n\t\t\ttypeToArray: new Map<number, new (length: number) => ArrayBufferView>([\n\t\t\t\t[gl.FLOAT, Float32Array],\n\t\t\t\t[gl.HALF_FLOAT, Uint16Array],\n\t\t\t\t[gl.UNSIGNED_SHORT, Uint16Array],\n\t\t\t\t[gl.SHORT, Int16Array],\n\t\t\t\t[gl.BYTE, Int8Array],\n\t\t\t\t[gl.UNSIGNED_INT, Uint32Array],\n\t\t\t\t[gl.INT, Int32Array],\n\t\t\t]),\n\t\t\ttypeToInternalFormatString: new Map<number, GLInternalFormatString>([\n\t\t\t\t[gl.FLOAT, 'RGBA32F'],\n\t\t\t\t[gl.HALF_FLOAT, 'RGBA16F'],\n\t\t\t\t[gl.UNSIGNED_SHORT, 'RGBA32UI'],\n\t\t\t\t[gl.SHORT, 'RGBA32I'],\n\t\t\t\t[gl.BYTE, 'RGBA32I'],\n\t\t\t\t[gl.UNSIGNED_INT, 'RGBA32UI'],\n\t\t\t\t[gl.INT, 'RGBA32I'],\n\t\t\t]),\n\t\t\tunsignedIntTypes: new Set([gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT]),\n\t\t};\n\n\t\tlet registryEntry = canvasRegistry.get(this.canvas);\n\t\tif (!registryEntry) {\n\t\t\tregistryEntry = {\n\t\t\t\ttextureUnitPool: {\n\t\t\t\t\tfree: [],\n\t\t\t\t\tnext: 0,\n\t\t\t\t\tmax: gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),\n\t\t\t\t},\n\t\t\t\tinstances: new Set([this]),\n\t\t\t};\n\t\t\tcanvasRegistry.set(this.canvas, registryEntry);\n\t\t}\n\t\tthis.textureUnitPool = registryEntry.textureUnitPool;\n\t\tregistryEntry.instances.add(this);\n\n\t\tthis.textureOptions = textureOptions;\n\n\t\tif (history) this.historyDepth = history;\n\t\tthis.cursorTarget = cursorTarget ?? (this.canvas instanceof HTMLCanvasElement ? this.canvas : undefined);\n\t\tthis.animationFrameId = null;\n\n\t\tconst glslInjections: string[] = [];\n\t\tif (plugins) {\n\t\t\tplugins.forEach(plugin =>\n\t\t\t\tplugin(this, {\n\t\t\t\t\tgl,\n\t\t\t\t\tcanvas: this.canvas,\n\t\t\t\t\tinjectGLSL: (code: string) => {\n\t\t\t\t\t\tglslInjections.push(code);\n\t\t\t\t\t},\n\t\t\t\t\temitHook: this.emitHook.bind(this),\n\t\t\t\t\tupdateTexturesInternal: this.updateTexturesInternal.bind(this),\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst program = this.gl.createProgram();\n\t\tif (!program) {\n\t\t\tthrow spError(1);\n\t\t}\n\t\tthis.program = program;\n\n\t\tconst vertexShader = this.createShader(this.gl.VERTEX_SHADER, DEFAULT_VERTEX_SHADER_SRC);\n\t\tconst fragmentShader = this.createShader(\n\t\t\tgl.FRAGMENT_SHADER,\n\t\t\tcombineShaderCode(fragmentShaderSrc, glslInjections),\n\t\t);\n\t\tgl.attachShader(program, vertexShader);\n\t\tgl.attachShader(program, fragmentShader);\n\t\tgl.bindAttribLocation(program, 0, 'a_position');\n\t\tgl.linkProgram(program);\n\t\tgl.deleteShader(vertexShader);\n\t\tgl.deleteShader(fragmentShader);\n\n\t\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\t\tconst programInfoLog = gl.getProgramInfoLog(program);\n\t\t\tconst linkError = spError(\n\t\t\t\t2,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tprogramInfoLog,\n\t\t\t\t\tfragmentShaderLength: fragmentShaderSrc.length,\n\t\t\t\t\tglslInjectionCount: glslInjections.length,\n\t\t\t\t},\n\t\t\t);\n\t\t\tgl.deleteProgram(program);\n\t\t\tthrow linkError;\n\t\t}\n\n\t\tthis.vao = gl.createVertexArray();\n\t\tgl.bindVertexArray(this.vao);\n\t\tthis.buffer = gl.createBuffer();\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n\t\tgl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);\n\t\tgl.enableVertexAttribArray(0);\n\t\tgl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n\t\tgl.useProgram(program);\n\n\t\tif (this.canvas instanceof HTMLCanvasElement) {\n\t\t\tthis.resolutionObserver = new MutationObserver(() => this.updateResolution());\n\t\t\tthis.resolutionObserver.observe(this.canvas, {\n\t\t\t\tattributes: true,\n\t\t\t\tattributeFilter: ['width', 'height'],\n\t\t\t});\n\t\t} else {\n\t\t\tconst wrapDimension = (dimension: 'width' | 'height') => {\n\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype, dimension)!;\n\t\t\t\tconst canvas = this.canvas;\n\t\t\t\tObject.defineProperty(canvas, dimension, {\n\t\t\t\t\tget: () => descriptor.get!.call(canvas),\n\t\t\t\t\tset: v => {\n\t\t\t\t\t\tdescriptor.set!.call(canvas, v);\n\t\t\t\t\t\tconst entry = canvasRegistry.get(canvas);\n\t\t\t\t\t\tif (entry) {\n\t\t\t\t\t\t\tfor (const instance of entry.instances) {\n\t\t\t\t\t\t\t\tinstance.updateResolution();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tconfigurable: descriptor.configurable,\n\t\t\t\t\tenumerable: descriptor.enumerable,\n\t\t\t\t});\n\t\t\t};\n\t\t\twrapDimension('width');\n\t\t\twrapDimension('height');\n\t\t}\n\t\tthis.updateResolution();\n\n\t\tthis.initializeUniform('u_cursor', 'float', this.cursorPosition, { allowMissing: true });\n\t\tthis.initializeUniform('u_click', 'float', [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0], {\n\t\t\tallowMissing: true,\n\t\t});\n\t\tthis.initializeUniform('u_time', 'float', 0, { allowMissing: true });\n\t\tthis.initializeUniform('u_frame', 'int', 0, { allowMissing: true });\n\n\t\tthis._initializeTexture(INTERMEDIATE_TEXTURE_KEY, this.canvas, {\n\t\t\t...this.textureOptions,\n\t\t});\n\t\tthis.intermediateFbo = gl.createFramebuffer();\n\t\tthis.bindIntermediate();\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n\t\tif (this.historyDepth > 0) {\n\t\t\tthis._initializeTexture(HISTORY_TEXTURE_KEY, this.canvas, {\n\t\t\t\thistory: this.historyDepth,\n\t\t\t\t...this.textureOptions,\n\t\t\t});\n\t\t}\n\t\tif (this.cursorTarget) {\n\t\t\tthis.addEventListeners();\n\t\t}\n\t\tthis.emitHook('_init');\n\t}\n\n\tprivate resolveGLConstant(value: GLConstantString): number {\n\t\tconst resolved = this.gl[value];\n\t\tif (resolved === undefined) {\n\t\t\tthrow spError(3, __SHADERPAD_DEV__ && { value });\n\t\t}\n\t\treturn resolved;\n\t}\n\n\tprivate emitHook(name: LifecycleMethod, ...args: any[]) {\n\t\tthis.hooks.get(name)?.forEach(hook => hook.call(this, ...args));\n\t}\n\n\ton(name: LifecycleMethod, fn: Function) {\n\t\tif (!this.hooks.has(name)) {\n\t\t\tthis.hooks.set(name, []);\n\t\t}\n\t\tthis.hooks.get(name)!.push(fn);\n\t}\n\n\toff(name: LifecycleMethod, fn: Function) {\n\t\tconst hooks = this.hooks.get(name);\n\t\tif (hooks) {\n\t\t\tconst index = hooks.indexOf(fn);\n\t\t\tif (index >= 0) {\n\t\t\t\thooks.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst shader = this.gl.createShader(type)!;\n\t\tthis.gl.shaderSource(shader, source);\n\t\tthis.gl.compileShader(shader);\n\t\tif (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n\t\t\tconst shaderInfoLog = this.gl.getShaderInfoLog(shader);\n\t\t\tconst shaderType = type === this.gl.VERTEX_SHADER ? 'vertex' : 'fragment';\n\t\t\tconst compilationError = spError(\n\t\t\t\t4,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tshaderType,\n\t\t\t\t\tshaderInfoLog,\n\t\t\t\t\tsource,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.gl.deleteShader(shader);\n\t\t\tthrow compilationError;\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate getCursorTargetRect(): {\n\t\tleft: number;\n\t\ttop: number;\n\t\twidth: number;\n\t\theight: number;\n\t} {\n\t\tconst target = this.cursorTarget!;\n\t\tif (target === window) {\n\t\t\treturn {\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0,\n\t\t\t\twidth: window.innerWidth,\n\t\t\t\theight: window.innerHeight,\n\t\t\t};\n\t\t}\n\t\treturn (target as Element).getBoundingClientRect();\n\t}\n\n\tprivate addEventListeners() {\n\t\tif (!this.cursorTarget) return;\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('u_cursor')) return;\n\t\t\tconst rect = this.getCursorTargetRect();\n\t\t\tconst u = (x - rect.left) / rect.width;\n\t\t\tconst v = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.cursorPosition[0] = Math.max(0, Math.min(1, u));\n\t\t\tthis.cursorPosition[1] = Math.max(0, Math.min(1, v));\n\t\t\tthis.updateUniforms({ u_cursor: this.cursorPosition });\n\t\t};\n\n\t\tconst updateClick = (isMouseDown: boolean, x?: number, y?: number) => {\n\t\t\tif (!this.uniforms.has('u_click')) return;\n\t\t\tthis.isMouseDown = isMouseDown;\n\t\t\tif (isMouseDown) {\n\t\t\t\tconst rect = this.getCursorTargetRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPosition[0] = Math.max(0, Math.min(1, (xVal - rect.left) / rect.width));\n\t\t\t\tthis.clickPosition[1] = Math.max(0, Math.min(1, 1 - (yVal - rect.top) / rect.height)); // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({\n\t\t\t\tu_click: [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.eventListeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isMouseDown = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouchDevice = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.cursorTarget!.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tupdateResolution() {\n\t\tconst resolution: [number, number] = [this.gl.drawingBufferWidth, this.gl.drawingBufferHeight];\n\t\tthis.gl.viewport(0, 0, ...resolution);\n\t\tif (this.uniforms.has('u_resolution')) {\n\t\t\tthis.updateUniforms({ u_resolution: resolution });\n\t\t} else {\n\t\t\tthis.initializeUniform('u_resolution', 'float', resolution, { allowMissing: true });\n\t\t}\n\t\tthis.resizeTexture(INTERMEDIATE_TEXTURE_KEY, ...resolution);\n\t\tif (this.historyDepth > 0) {\n\t\t\tthis.resizeTexture(HISTORY_TEXTURE_KEY, ...resolution);\n\t\t}\n\t\tthis.emitHook('updateResolution', ...resolution);\n\t}\n\n\tprivate resizeTexture(name: string | symbol, width: number, height: number) {\n\t\tconst info = this.textures.get(name);\n\t\tif (!info || (info.width === width && info.height === height)) return;\n\n\t\tthis.gl.deleteTexture(info.texture);\n\t\tinfo.width = width;\n\t\tinfo.height = height;\n\t\tconst { texture } = this.createTexture(name, info);\n\t\tinfo.texture = texture;\n\t\tif (info.history) {\n\t\t\tinfo.history.writeIndex = 0;\n\t\t\tthis.clearHistoryTextureLayers(info);\n\t\t}\n\t}\n\n\tprivate reserveTextureUnit(name: string | symbol) {\n\t\tconst existing = this.textures.get(name);\n\t\tif (existing) return existing.unitIndex;\n\t\tif (this.textureUnitPool.free.length > 0) return this.textureUnitPool.free.pop()!;\n\t\tif (this.textureUnitPool.next >= this.textureUnitPool.max) {\n\t\t\tthrow spError(\n\t\t\t\t5,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\tnextTextureUnit: this.textureUnitPool.next,\n\t\t\t\t\tmaxTextureUnits: this.textureUnitPool.max,\n\t\t\t\t\tfreeTextureUnits: this.textureUnitPool.free.length,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\treturn this.textureUnitPool.next++;\n\t}\n\n\tprivate resolveTextureOptions(options?: TextureOptions): ResolvedTextureOptions {\n\t\tconst { gl } = this;\n\t\tconst internalFormatOption = options?.internalFormat;\n\t\tconst typeString = options?.type ?? typeFromInternalFormatString(internalFormatOption) ?? 'UNSIGNED_BYTE';\n\t\tconst type = this.resolveGLConstant(typeString);\n\t\tconst internalFormatString =\n\t\t\tinternalFormatOption ?? this.glHelpers.typeToInternalFormatString.get(type) ?? 'RGBA8';\n\t\tconst isIntegerColorFormat = /^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(internalFormatString);\n\t\tconst formatString = options?.format ?? (isIntegerColorFormat ? 'RGBA_INTEGER' : 'RGBA');\n\t\tconst result: ResolvedTextureOptions = {\n\t\t\ttype,\n\t\t\tformat: this.resolveGLConstant(formatString),\n\t\t\tinternalFormat: this.resolveGLConstant(internalFormatString),\n\t\t\tminFilter: this.resolveGLConstant(options?.minFilter ?? 'LINEAR'),\n\t\t\tmagFilter: this.resolveGLConstant(options?.magFilter ?? 'LINEAR'),\n\t\t\twrapS: this.resolveGLConstant(options?.wrapS ?? 'CLAMP_TO_EDGE'),\n\t\t\twrapT: this.resolveGLConstant(options?.wrapT ?? 'CLAMP_TO_EDGE'),\n\t\t\tpreserveY: options?.preserveY,\n\t\t\tisIntegerColorFormat,\n\t\t};\n\t\tconst isFloatColorFormat = result.internalFormat === gl.RGBA16F || result.internalFormat === gl.RGBA32F;\n\t\t// gl.getExtension isn’t just a check, it’s a required side-effect to enable floats.\n\t\tif (isFloatColorFormat && !gl.getExtension('EXT_color_buffer_float')) {\n\t\t\tthrow spError(\n\t\t\t\t6,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tinternalFormat: internalFormatString,\n\t\t\t\t\ttype: typeString,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate getPixelArray(type: number, size: number): ArrayBufferView {\n\t\tconst ArrayType = this.glHelpers.typeToArray.get(type) ?? Uint8Array;\n\t\treturn new ArrayType(size);\n\t}\n\n\tprivate isNotRgba(format: number): boolean {\n\t\treturn format !== this.gl.RGBA && format !== this.gl.RGBA_INTEGER;\n\t}\n\n\tprivate clearHistoryTextureLayers(textureInfo: Texture): void {\n\t\tif (!textureInfo.history) return;\n\n\t\tconst gl = this.gl;\n\t\tconst { type, format } = textureInfo.options;\n\t\tconst transparent = this.getPixelArray(type, textureInfo.width * textureInfo.height * 4);\n\t\tgl.activeTexture(gl.TEXTURE0 + textureInfo.unitIndex);\n\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, textureInfo.texture);\n\t\tconst needsAlignmentFix = this.isNotRgba(format);\n\t\tlet previousAlignment;\n\t\tif (needsAlignmentFix) {\n\t\t\tpreviousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);\n\t\t\tgl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n\t\t}\n\t\tfor (let layer = 0; layer < textureInfo.history.depth; ++layer) {\n\t\t\tgl.texSubImage3D(\n\t\t\t\tgl.TEXTURE_2D_ARRAY,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tlayer,\n\t\t\t\ttextureInfo.width,\n\t\t\t\ttextureInfo.height,\n\t\t\t\t1,\n\t\t\t\tformat,\n\t\t\t\ttype,\n\t\t\t\ttransparent,\n\t\t\t);\n\t\t}\n\t\tif (needsAlignmentFix) gl.pixelStorei(gl.UNPACK_ALIGNMENT, previousAlignment);\n\t}\n\n\tinitializeUniform(\n\t\tname: string,\n\t\ttype: Uniform['type'],\n\t\tvalue: number | number[] | (number | number[])[],\n\t\toptions?: { arrayLength?: number; allowMissing?: boolean },\n\t) {\n\t\tconst arrayLength = options?.arrayLength;\n\t\tconst allowMissing = options?.allowMissing ?? false;\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow spError(7, __SHADERPAD_DEV__ && { name, arrayLength: arrayLength ?? null });\n\t\t}\n\t\tif (!UNIFORM_TYPE_SUFFIXES[type]) {\n\t\t\tthrow spError(\n\t\t\t\t8,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tname,\n\t\t\t\t\ttype,\n\t\t\t\t\tsupportedTypes: Object.keys(UNIFORM_TYPE_SUFFIXES),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tif (arrayLength && !(Array.isArray(value) && value.length === arrayLength)) {\n\t\t\tthrow spError(\n\t\t\t\t9,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tname,\n\t\t\t\t\texpectedLength: arrayLength,\n\t\t\t\t\treceivedLength: Array.isArray(value) ? value.length : 1,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tlet location = this.gl.getUniformLocation(this.program!, name);\n\t\tif (!location && arrayLength) {\n\t\t\tlocation = this.gl.getUniformLocation(this.program!, `${name}[0]`);\n\t\t}\n\t\tif (!location) {\n\t\t\tif (allowMissing) return;\n\t\t\tthrow spError(19, __SHADERPAD_DEV__ && { name, arrayLength: arrayLength ?? null });\n\t\t}\n\n\t\tconst probeValue = arrayLength ? (value as number[] | number[][])[0] : value;\n\t\tconst length = Array.isArray(probeValue) ? (probeValue.length as 1 | 2 | 3 | 4) : 1;\n\t\tthis.uniforms.set(name, { type, length, location, arrayLength });\n\n\t\ttry {\n\t\t\tthis.updateUniforms({ [name]: value });\n\t\t} catch (error) {\n\t\t\tthis.uniforms.delete(name);\n\t\t\tthrow error;\n\t\t}\n\t\tthis.emitHook('initializeUniform', ...arguments);\n\t}\n\n\tupdateUniforms(\n\t\tupdates: Record<string, number | number[] | (number | number[])[]>,\n\t\toptions?: { startIndex?: number; allowMissing?: boolean },\n\t) {\n\t\tthis.gl.useProgram(this.program);\n\t\tObject.entries(updates).forEach(([name, newValue]) => {\n\t\t\tconst uniform = this.uniforms.get(name);\n\t\t\tif (!uniform) {\n\t\t\t\tif (options?.allowMissing) return;\n\t\t\t\tthrow spError(\n\t\t\t\t\t20,\n\t\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tstartIndex: options?.startIndex ?? null,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t\tlet glFunctionName = `uniform${uniform.length}${UNIFORM_TYPE_SUFFIXES[uniform.type]}`;\n\t\t\tif (uniform.arrayLength) {\n\t\t\t\tif (!Array.isArray(newValue)) {\n\t\t\t\t\tthrow spError(\n\t\t\t\t\t\t10,\n\t\t\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\treceivedType: typeof newValue,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst nValues = newValue.length;\n\t\t\t\tif (!nValues) return;\n\t\t\t\tif (nValues > uniform.arrayLength) {\n\t\t\t\t\tthrow spError(\n\t\t\t\t\t\t11,\n\t\t\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\treceivedLength: nValues,\n\t\t\t\t\t\t\tmaxLength: uniform.arrayLength,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (newValue.some(item => (Array.isArray(item) ? item.length : 1) !== uniform.length)) {\n\t\t\t\t\tthrow spError(\n\t\t\t\t\t\t12,\n\t\t\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\texpectedElementLength: uniform.length,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst flat = newValue.flat();\n\t\t\t\tconst typedArray =\n\t\t\t\t\tuniform.type === 'float'\n\t\t\t\t\t\t? new Float32Array(flat)\n\t\t\t\t\t\t: uniform.type === 'uint'\n\t\t\t\t\t\t\t? new Uint32Array(flat)\n\t\t\t\t\t\t\t: new Int32Array(flat);\n\t\t\t\tlet location = uniform.location;\n\t\t\t\tif (options?.startIndex) {\n\t\t\t\t\tconst newLocation = this.gl.getUniformLocation(this.program!, `${name}[${options.startIndex}]`);\n\t\t\t\t\tif (!newLocation) {\n\t\t\t\t\t\tthrow spError(\n\t\t\t\t\t\t\t13,\n\t\t\t\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\tstartIndex: options.startIndex,\n\t\t\t\t\t\t\t\tarrayLength: uniform.arrayLength,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tlocation = newLocation;\n\t\t\t\t}\n\t\t\t\t(this.gl as any)[glFunctionName + 'v'](location, typedArray);\n\t\t\t} else {\n\t\t\t\tif (!Array.isArray(newValue)) newValue = [newValue];\n\t\t\t\tconst scalarValue = newValue as number[];\n\t\t\t\tif (scalarValue.length !== uniform.length) {\n\t\t\t\t\tthrow spError(\n\t\t\t\t\t\t14,\n\t\t\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\treceivedLength: scalarValue.length,\n\t\t\t\t\t\t\texpectedLength: uniform.length,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t(this.gl as any)[glFunctionName](uniform.location, ...scalarValue);\n\t\t\t}\n\t\t});\n\t\tthis.emitHook('updateUniforms', ...arguments);\n\t}\n\n\tprivate createTexture(\n\t\tname: string | symbol,\n\t\ttextureInfo: Pick<Texture, 'width' | 'height' | 'history' | 'options'> & { unitIndex?: number },\n\t) {\n\t\tconst { width, height } = textureInfo;\n\t\tconst historyDepth = textureInfo.history?.depth ?? 0;\n\n\t\tconst texture = this.gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow spError(\n\t\t\t\t15,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\thistoryDepth,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tlet unitIndex = textureInfo.unitIndex;\n\t\tif (typeof unitIndex !== 'number') {\n\t\t\ttry {\n\t\t\t\tunitIndex = this.reserveTextureUnit(name);\n\t\t\t} catch (error) {\n\t\t\t\tthis.gl.deleteTexture(texture);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst hasHistory = historyDepth > 0;\n\t\tconst textureTarget = hasHistory ? this.gl.TEXTURE_2D_ARRAY : this.gl.TEXTURE_2D;\n\t\tconst { options } = textureInfo;\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + unitIndex);\n\t\tthis.gl.bindTexture(textureTarget, texture);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_WRAP_S, options.wrapS);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_WRAP_T, options.wrapT);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_MIN_FILTER, options.minFilter);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_MAG_FILTER, options.magFilter);\n\t\tif (hasHistory) {\n\t\t\tthis.gl.texStorage3D(textureTarget, 1, options.internalFormat, width, height, historyDepth);\n\t\t} else if (name === INTERMEDIATE_TEXTURE_KEY) {\n\t\t\tthis.gl.texImage2D(\n\t\t\t\tthis.gl.TEXTURE_2D,\n\t\t\t\t0,\n\t\t\t\toptions.internalFormat,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\t0,\n\t\t\t\toptions.format,\n\t\t\t\toptions.type,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\treturn { texture, unitIndex };\n\t}\n\n\tprivate _initializeTexture(\n\t\tname: string | symbol,\n\t\tsource: TextureSource,\n\t\toptions?: TextureOptions & { history?: number },\n\t) {\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow spError(16, __SHADERPAD_DEV__ && { name: stringFrom(name) });\n\t\t}\n\n\t\tconst { history: historyDepth = 0, ...textureOptions } = options ?? {};\n\t\tconst { width, height } = getSourceDimensions(source);\n\t\tif (!width || !height) {\n\t\t\tthrow spError(\n\t\t\t\t17,\n\t\t\t\t__SHADERPAD_DEV__ && {\n\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tsourceType: source.constructor.name,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tconst textureInfo: Pick<Texture, 'width' | 'height' | 'history' | 'options'> = {\n\t\t\twidth,\n\t\t\theight,\n\t\t\toptions:\n\t\t\t\tsource instanceof ShaderPad &&\n\t\t\t\tObject.keys(textureOptions).length === 0 &&\n\t\t\t\tsource.textures.has(INTERMEDIATE_TEXTURE_KEY)\n\t\t\t\t\t? source.textures.get(INTERMEDIATE_TEXTURE_KEY)!.options\n\t\t\t\t\t: this.resolveTextureOptions(textureOptions),\n\t\t};\n\t\tif (historyDepth > 0) {\n\t\t\ttextureInfo.history = { depth: historyDepth, writeIndex: 0 };\n\t\t}\n\t\tconst { texture, unitIndex } = this.createTexture(name, textureInfo);\n\t\tconst completeTextureInfo: Texture = {\n\t\t\ttexture,\n\t\t\tunitIndex,\n\t\t\t...textureInfo,\n\t\t};\n\t\tif (historyDepth > 0) {\n\t\t\tthis.initializeUniform(`${stringFrom(name)}FrameOffset`, 'int', 0, { allowMissing: true });\n\t\t\tthis.clearHistoryTextureLayers(completeTextureInfo);\n\t\t}\n\t\tthis.textures.set(name, completeTextureInfo);\n\t\tif (name !== INTERMEDIATE_TEXTURE_KEY && name !== HISTORY_TEXTURE_KEY) {\n\t\t\tthis.updateTexture(name, source);\n\t\t}\n\n\t\t// Set a uniform to access the texture in the fragment shader.\n\t\tthis.gl.useProgram(this.program!);\n\t\tconst uSampler = this.gl.getUniformLocation(this.program!, stringFrom(name));\n\t\tif (uSampler) {\n\t\t\tthis.gl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tinitializeTexture(name: string, source: TextureSource, options?: TextureOptions & { history?: number }) {\n\t\t// Since history[0] is the current frame, add 1 to history depth to allow history[maxHistory].\n\t\tconst opts =\n\t\t\toptions?.history != null && options.history > 0 ? { ...options, history: options.history + 1 } : options;\n\t\tthis._initializeTexture(name, source, opts);\n\t\tthis.emitHook('initializeTexture', ...arguments);\n\t}\n\n\tupdateTextures(updates: Record<string, UpdateTextureSource>, options?: UpdateTexturesOptions) {\n\t\tthis.updateTexturesInternal(updates, options);\n\t\tthis.emitHook('updateTextures', ...arguments);\n\t}\n\n\tprivate updateTexturesInternal(\n\t\tupdates: Record<string, UpdateTextureSource>,\n\t\toptions?: InternalUpdateTexturesOptions,\n\t) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tthis.updateTexture(name, source, options);\n\t\t});\n\t}\n\n\tprivate updateTexture(name: string | symbol, source: UpdateTextureSource, options?: InternalUpdateTexturesOptions) {\n\t\tconst info = this.textures.get(name);\n\t\tif (!info) {\n\t\t\tthrow spError(18, __SHADERPAD_DEV__ && { name: stringFrom(name) });\n\t\t}\n\n\t\tif (source instanceof WebGLTexture) {\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, source);\n\t\t\treturn;\n\t\t}\n\n\t\tlet nonShaderPadSource = source as Exclude<UpdateTextureSource, ShaderPad>;\n\t\tif (source instanceof ShaderPad) {\n\t\t\tconst sourceIntermediateInfo = source.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\t\tconst srcW = sourceIntermediateInfo.width;\n\t\t\tconst srcH = sourceIntermediateInfo.height;\n\n\t\t\tif (source.gl === this.gl) {\n\t\t\t\tif (!info.history) {\n\t\t\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, sourceIntermediateInfo.texture);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst { depth } = info.history;\n\t\t\t\tconst targetSlots =\n\t\t\t\t\toptions?.historyWriteIndex === undefined\n\t\t\t\t\t\t? [info.history.writeIndex]\n\t\t\t\t\t\t: Array.isArray(options?.historyWriteIndex)\n\t\t\t\t\t\t\t? options.historyWriteIndex.map(i => safeMod(i, depth))\n\t\t\t\t\t\t\t: [safeMod(options.historyWriteIndex, depth)];\n\t\t\t\tthis.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, source.intermediateFbo);\n\t\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\t\tfor (const slot of targetSlots) {\n\t\t\t\t\tthis.gl.copyTexSubImage3D(this.gl.TEXTURE_2D_ARRAY, 0, 0, 0, slot, 0, 0, srcW, srcH);\n\t\t\t\t}\n\t\t\t\tthis.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, null);\n\t\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\t\tconst frameOffsetUniformName = `${stringFrom(name)}FrameOffset`;\n\t\t\t\tthis.updateUniforms(\n\t\t\t\t\t{\n\t\t\t\t\t\t[frameOffsetUniformName]: targetSlots[targetSlots.length - 1],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tallowMissing: true,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (options?.historyWriteIndex === undefined) {\n\t\t\t\t\tinfo.history.writeIndex = (info.history.writeIndex + 1) % depth;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Different contexts - transfer via readPixels to preserve precision.\n\t\t\tconst {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\toptions: { format, type },\n\t\t\t} = sourceIntermediateInfo;\n\t\t\tconst pixels = this.getPixelArray(type, width * height * 4);\n\t\t\tsource.gl.bindFramebuffer(source.gl.FRAMEBUFFER, source.intermediateFbo);\n\t\t\tsource.gl.readPixels(0, 0, width, height, format, type, pixels);\n\t\t\tsource.gl.bindFramebuffer(source.gl.FRAMEBUFFER, null);\n\t\t\tnonShaderPadSource = { data: pixels, width, height };\n\t\t}\n\n\t\t// If dimensions changed, recreate the texture with new dimensions.\n\t\tconst { width, height } = getSourceDimensions(nonShaderPadSource);\n\t\tif (!width || !height) return;\n\n\t\tconst isPartial = 'isPartial' in nonShaderPadSource && nonShaderPadSource.isPartial;\n\t\tif (!isPartial) {\n\t\t\tthis.resizeTexture(name, width, height);\n\t\t}\n\n\t\t// UNPACK_FLIP_Y_WEBGL only works for DOM element sources, not typed arrays.\n\t\tconst isTypedArray = 'data' in nonShaderPadSource && nonShaderPadSource.data;\n\t\tconst shouldFlipY = !isTypedArray && !info.options?.preserveY;\n\t\tconst previousFlipY = this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL);\n\t\tconst needsAlignmentFix = isTypedArray && this.isNotRgba(info.options.format);\n\t\tlet previousAlignment;\n\t\tif (needsAlignmentFix) {\n\t\t\tpreviousAlignment = this.gl.getParameter(this.gl.UNPACK_ALIGNMENT);\n\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);\n\t\t}\n\n\t\tif (info.history) {\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\tif (!options?.skipHistoryWrite) {\n\t\t\t\tconst { depth } = info.history;\n\t\t\t\tconst targetSlots =\n\t\t\t\t\toptions?.historyWriteIndex === undefined\n\t\t\t\t\t\t? [info.history.writeIndex]\n\t\t\t\t\t\t: Array.isArray(options.historyWriteIndex)\n\t\t\t\t\t\t\t? options.historyWriteIndex.map(i => safeMod(i, depth))\n\t\t\t\t\t\t\t: [safeMod(options.historyWriteIndex, depth)];\n\n\t\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\t\t\t\tconst partialSource = nonShaderPadSource as PartialCustomTexture;\n\t\t\t\tconst sourceData =\n\t\t\t\t\tpartialSource.data ?? (nonShaderPadSource as Exclude<TextureSource, CustomTexture | ShaderPad>);\n\t\t\t\tconst xOffset = isPartial ? (partialSource.x ?? 0) : 0;\n\t\t\t\tconst yOffset = isPartial ? (partialSource.y ?? 0) : 0;\n\n\t\t\t\tfor (const slot of targetSlots) {\n\t\t\t\t\tthis.gl.texSubImage3D(\n\t\t\t\t\t\tthis.gl.TEXTURE_2D_ARRAY,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\txOffset,\n\t\t\t\t\t\tyOffset,\n\t\t\t\t\t\tslot,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\tinfo.options.format,\n\t\t\t\t\t\tinfo.options.type,\n\t\t\t\t\t\tsourceData as any,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\n\t\t\t\tconst frameOffsetUniformName = `${stringFrom(name)}FrameOffset`;\n\t\t\t\tthis.updateUniforms({\n\t\t\t\t\t[frameOffsetUniformName]: targetSlots[targetSlots.length - 1],\n\t\t\t\t});\n\n\t\t\t\tif (options?.historyWriteIndex === undefined) {\n\t\t\t\t\tinfo.history.writeIndex = (info.history.writeIndex + 1) % depth;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, info.texture);\n\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\n\t\t\tif (isPartial) {\n\t\t\t\tconst partialSource = nonShaderPadSource as PartialCustomTexture;\n\t\t\t\tthis.gl.texSubImage2D(\n\t\t\t\t\tthis.gl.TEXTURE_2D,\n\t\t\t\t\t0,\n\t\t\t\t\tpartialSource.x ?? 0,\n\t\t\t\t\tpartialSource.y ?? 0,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tinfo.options.format,\n\t\t\t\t\tinfo.options.type,\n\t\t\t\t\tpartialSource.data,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.gl.texImage2D(\n\t\t\t\t\tthis.gl.TEXTURE_2D,\n\t\t\t\t\t0,\n\t\t\t\t\tinfo.options.internalFormat,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\t0,\n\t\t\t\t\tinfo.options.format,\n\t\t\t\t\tinfo.options.type,\n\t\t\t\t\t((nonShaderPadSource as PartialCustomTexture).data ??\n\t\t\t\t\t\t(nonShaderPadSource as Exclude<TextureSource, CustomTexture | ShaderPad>)) as any,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t}\n\t\tif (needsAlignmentFix) this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, previousAlignment);\n\t}\n\n\tprivate bindIntermediate() {\n\t\tconst gl = this.gl;\n\t\tconst intermediateInfo = this.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, this.intermediateFbo);\n\t\tgl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, intermediateInfo.texture, 0);\n\t}\n\n\tclear() {\n\t\tthis.bindIntermediate();\n\t\tconst gl = this.gl;\n\t\tconst intermediateInfo = this.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\tif (intermediateInfo.options.isIntegerColorFormat) {\n\t\t\tconst t = intermediateInfo.options.type;\n\t\t\tif (this.glHelpers.unsignedIntTypes.has(t)) {\n\t\t\t\tgl.clearBufferuiv(gl.COLOR, 0, new Uint32Array(4));\n\t\t\t} else {\n\t\t\t\tgl.clearBufferiv(gl.COLOR, 0, new Int32Array(4));\n\t\t\t}\n\t\t} else {\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT);\n\t\t}\n\t}\n\n\tdraw(options?: StepOptions) {\n\t\tthis.emitHook('beforeDraw', ...arguments);\n\t\tconst gl = this.gl;\n\t\tconst w = gl.drawingBufferWidth;\n\t\tconst h = gl.drawingBufferHeight;\n\n\t\tif (options?.skipClear) {\n\t\t\tthis.bindIntermediate();\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tgl.useProgram(this.program);\n\t\tgl.bindVertexArray(this.vao);\n\t\tgl.viewport(0, 0, w, h);\n\t\tgl.drawArrays(gl.TRIANGLES, 0, 3);\n\n\t\tif (!this.isHeadless) {\n\t\t\tconst intermediateInfo = this.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\t\tif (!intermediateInfo.options.isIntegerColorFormat) {\n\t\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.intermediateFbo);\n\t\t\t\tgl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n\t\t\t\tgl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST);\n\t\t\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\t\t\t}\n\t\t}\n\t\tthis.emitHook('afterDraw', ...arguments);\n\t}\n\n\tstep(options?: StepOptions) {\n\t\tif (!Number.isFinite(this.startTime)) {\n\t\t\tthis.startTime = performance.now();\n\t\t}\n\t\tthis._step((performance.now() - this.startTime) / 1000, options);\n\t}\n\n\tprivate _step(time: number, options?: StepOptions) {\n\t\tthis.emitHook('beforeStep', time, this.frame, options);\n\t\tconst updates: Record<string, number> = {};\n\t\tif (this.uniforms.has('u_time')) updates.u_time = time;\n\t\tif (this.uniforms.has('u_frame')) updates.u_frame = this.frame;\n\t\tthis.updateUniforms(updates);\n\t\tthis.draw(options);\n\t\tconst historyInfo = this.textures.get(HISTORY_TEXTURE_KEY);\n\t\tif (historyInfo && !options?.skipHistoryWrite) {\n\t\t\tconst { writeIndex, depth } = historyInfo.history!;\n\t\t\tconst gl = this.gl;\n\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.intermediateFbo);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, historyInfo.texture);\n\t\t\tgl.copyTexSubImage3D(\n\t\t\t\tgl.TEXTURE_2D_ARRAY,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\twriteIndex,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tgl.drawingBufferWidth,\n\t\t\t\tgl.drawingBufferHeight,\n\t\t\t);\n\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);\n\t\t\tconst nextWriteIndex = (writeIndex + 1) % depth;\n\t\t\tthis.updateUniforms(\n\t\t\t\t{\n\t\t\t\t\t[`${stringFrom(HISTORY_TEXTURE_KEY)}FrameOffset`]: nextWriteIndex,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tallowMissing: true,\n\t\t\t\t},\n\t\t\t);\n\t\t\thistoryInfo.history!.writeIndex = nextWriteIndex;\n\t\t}\n\t\t++this.frame;\n\t\tthis.emitHook('afterStep', time, this.frame, options);\n\t}\n\n\tplay(onBeforeStep?: (time: number, frame: number) => StepOptions | void) {\n\t\tthis._pause();\n\t\tif (!Number.isFinite(this.startTime)) {\n\t\t\tthis.startTime = performance.now();\n\t\t}\n\t\tthis.isPlaying = true;\n\t\tconst loop = (time: number) => {\n\t\t\ttime = (time - this.startTime) / 1000; // Convert from milliseconds to seconds.\n\t\t\tconst options = onBeforeStep?.(time, this.frame) ?? undefined;\n\t\t\tthis._step(time, options);\n\t\t\tif (this.isPlaying) this.animationFrameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t\tthis.emitHook('play');\n\t}\n\n\tprivate _pause() {\n\t\tconst wasPlaying = this.isPlaying;\n\t\tthis.isPlaying = false;\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\t\treturn wasPlaying;\n\t}\n\n\tpause() {\n\t\tif (this._pause()) {\n\t\t\tthis.emitHook('pause');\n\t\t}\n\t}\n\n\tresetFrame() {\n\t\tthis.frame = 0;\n\t\tthis.startTime = performance.now();\n\t}\n\n\treset() {\n\t\tthis.resetFrame();\n\t\tthis.textures.forEach(texture => {\n\t\t\tif (texture.history) {\n\t\t\t\ttexture.history.writeIndex = 0;\n\t\t\t\tthis.clearHistoryTextureLayers(texture);\n\t\t\t}\n\t\t});\n\t\tthis.clear();\n\t\tthis.emitHook('reset');\n\t}\n\n\tdestroy() {\n\t\tthis.emitHook('destroy');\n\n\t\tthis._pause();\n\n\t\tif (this.cursorTarget) {\n\t\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\t\tthis.cursorTarget!.removeEventListener(event, listener);\n\t\t\t});\n\t\t\tthis.eventListeners.clear();\n\t\t}\n\n\t\tif (this.resolutionObserver) {\n\t\t\tthis.resolutionObserver.disconnect();\n\t\t\tthis.resolutionObserver = null;\n\t\t}\n\n\t\tif (this.program) {\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t\tthis.program = null;\n\t\t}\n\n\t\tif (this.intermediateFbo) {\n\t\t\tthis.gl.deleteFramebuffer(this.intermediateFbo);\n\t\t\tthis.intermediateFbo = null;\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.textureUnitPool.free.push(texture.unitIndex);\n\t\t\tthis.gl.deleteTexture(texture.texture);\n\t\t});\n\t\tthis.textures.clear();\n\t\tconst entry = canvasRegistry.get(this.canvas);\n\t\tif (entry) {\n\t\t\tentry.instances.delete(this);\n\t\t\tif (entry.instances.size === 0) {\n\t\t\t\tcanvasRegistry.delete(this.canvas);\n\t\t\t}\n\t\t}\n\n\t\tif (this.vao) {\n\t\t\tthis.gl.deleteVertexArray(this.vao);\n\t\t\tthis.vao = null;\n\t\t}\n\n\t\tif (this.buffer) {\n\t\t\tthis.gl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tthis.uniforms.clear();\n\t\tthis.hooks.clear();\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"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","names":["DEFAULT_VERTEX_SHADER_SRC","FORMAT_TYPE_SUFFIXES","UNIFORM_TYPE_SUFFIXES","typeFromInternalFormatString","internalFormatString","suffix","HISTORY_TEXTURE_KEY","INTERMEDIATE_TEXTURE_KEY","canvasRegistry","combineShaderCode","shader","injections","lines","insertAt","line","trimmed","getSourceDimensions","source","ShaderPad","stringFrom","name","_ShaderPad","fragmentShaderSrc","canvas","plugins","history","cursorTarget","textureOptions","width","height","gl","spError","registryEntry","glslInjections","plugin","code","program","vertexShader","fragmentShader","programInfoLog","linkError","wrapDimension","dimension","descriptor","v","entry","instance","value","resolved","args","hook","fn","hooks","index","type","shaderInfoLog","shaderType","compilationError","target","updateCursor","x","y","rect","u","updateClick","isMouseDown","xVal","yVal","event","mouseEvent","touchEvent","listener","resolution","info","texture","existing","options","internalFormatOption","typeString","isIntegerColorFormat","formatString","result","size","ArrayType","format","textureInfo","transparent","needsAlignmentFix","previousAlignment","layer","arrayLength","allowMissing","location","probeValue","length","error","updates","newValue","uniform","glFunctionName","nValues","item","flat","typedArray","newLocation","scalarValue","historyDepth","unitIndex","hasHistory","textureTarget","completeTextureInfo","uSampler","opts","nonShaderPadSource","sourceIntermediateInfo","srcW","srcH","depth","targetSlots","i","safeMod","slot","frameOffsetUniformName","pixels","isPartial","isTypedArray","shouldFlipY","previousFlipY","partialSource","sourceData","xOffset","yOffset","intermediateInfo","t","w","h","time","historyInfo","writeIndex","nextWriteIndex","onBeforeStep","loop","wasPlaying","index_default"]}
@@ -0,0 +1,2 @@
1
+ var t="https://rileyjshaw.com/shaderpad/e/";function o(r){return`${t}${r}`}function d(r,e){let n=new Error(r);return n.code=e,n}function i(r,e){return d(`ShaderPad error: ${o(r)}`,r)}export{i as a};
2
+ //# sourceMappingURL=chunk-N45SWDLN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/error-codes.gen.ts","../src/internal/spError.ts"],"sourcesContent":["// Generated by scripts/generate-error-code-artifacts.mjs. Do not edit manually.\nexport type ErrorCode = number;\n\nexport const ERROR_DOCS_BASE_URL = 'https://rileyjshaw.com/shaderpad/e/';\n\nexport function errorUrl(code: ErrorCode) {\n\treturn `${ERROR_DOCS_BASE_URL}${code}`;\n}\n","import { errorUrl, type ErrorCode } from './error-codes.gen.js';\nimport { DEV_ERRORS } from './error-codes.dev.gen.js';\n\ntype DevContext = Record<string, unknown> | false | undefined;\ntype ShaderPadError = Error & { code: ErrorCode };\n\nfunction withCode(message: string, code: ErrorCode): ShaderPadError {\n\tconst error = new Error(message) as ShaderPadError;\n\terror.code = code;\n\treturn error;\n}\n\nfunction renderContext(context: Record<string, unknown>) {\n\tconst lines = ['Context:'];\n\n\tfor (const [key, value] of Object.entries(context)) {\n\t\tif (value === undefined) continue;\n\n\t\tconst rendered =\n\t\t\ttypeof value === 'string'\n\t\t\t\t? value\n\t\t\t\t: (JSON.stringify(value, null, 2) ??\n\t\t\t\t\t(typeof value === 'bigint' ||\n\t\t\t\t\ttypeof value === 'number' ||\n\t\t\t\t\ttypeof value === 'boolean' ||\n\t\t\t\t\tvalue == null\n\t\t\t\t\t\t? String(value)\n\t\t\t\t\t\t: ''));\n\n\t\tif (!rendered) continue;\n\t\tlines.push(rendered.includes('\\n') ? `${key}:\\n${rendered}` : `${key}: ${rendered}`);\n\t}\n\n\treturn lines.length > 1 ? lines.join('\\n') : '';\n}\n\nfunction renderDevMessage(code: ErrorCode, context?: DevContext) {\n\tconst error = DEV_ERRORS?.[code];\n\tconst parts = error\n\t\t? [`[ShaderPad ${code}] ${error.title}`, error.summary, `Docs: ${errorUrl(code)}`]\n\t\t: [`[ShaderPad ${code}] ${errorUrl(code)}`];\n\n\tif (context) {\n\t\tconst renderedContext = renderContext(context);\n\t\tif (renderedContext) parts.push(renderedContext);\n\t}\n\n\treturn parts.join('\\n\\n');\n}\n\nexport default function spError(code: ErrorCode, context?: DevContext) {\n\treturn withCode(__SHADERPAD_DEV__ ? renderDevMessage(code, context) : `ShaderPad error: ${errorUrl(code)}`, code);\n}\n"],"mappings":"AAGO,IAAMA,EAAsB,sCAE5B,SAASC,EAASC,EAAiB,CACzC,MAAO,GAAGF,CAAmB,GAAGE,CAAI,EACrC,CCDA,SAASC,EAASC,EAAiBC,EAAiC,CACnE,IAAMC,EAAQ,IAAI,MAAMF,CAAO,EAC/B,OAAAE,EAAM,KAAOD,EACNC,CACR,CAwCe,SAARC,EAAyBC,EAAiBC,EAAsB,CACtE,OAAOC,EAA+D,oBAAoBC,EAASH,CAAI,CAAC,GAAIA,CAAI,CACjH","names":["ERROR_DOCS_BASE_URL","errorUrl","code","withCode","message","code","error","spError","code","context","withCode","errorUrl"]}
package/dist/index.d.mts CHANGED
@@ -50,7 +50,6 @@ interface Options extends RenderTextureOptions {
50
50
  } | null;
51
51
  plugins?: Plugin[];
52
52
  history?: number;
53
- debug?: boolean;
54
53
  cursorTarget?: Window | Element;
55
54
  }
56
55
  interface StepOptions {
@@ -87,10 +86,9 @@ declare class ShaderPad {
87
86
  private hooks;
88
87
  private historyDepth;
89
88
  private textureOptions;
90
- private debug;
91
89
  private cursorTarget;
92
90
  private intermediateFbo;
93
- constructor(fragmentShaderSrc: string, { canvas, plugins, history, debug, cursorTarget, ...textureOptions }?: Options);
91
+ constructor(fragmentShaderSrc: string, { canvas, plugins, history, cursorTarget, ...textureOptions }?: Options);
94
92
  private resolveGLConstant;
95
93
  private emitHook;
96
94
  on(name: LifecycleMethod, fn: Function): void;
@@ -107,10 +105,11 @@ declare class ShaderPad {
107
105
  private clearHistoryTextureLayers;
108
106
  initializeUniform(name: string, type: Uniform['type'], value: number | number[] | (number | number[])[], options?: {
109
107
  arrayLength?: number;
108
+ allowMissing?: boolean;
110
109
  }): void;
111
- private log;
112
110
  updateUniforms(updates: Record<string, number | number[] | (number | number[])[]>, options?: {
113
111
  startIndex?: number;
112
+ allowMissing?: boolean;
114
113
  }): void;
115
114
  private createTexture;
116
115
  private _initializeTexture;
package/dist/index.d.ts CHANGED
@@ -50,7 +50,6 @@ interface Options extends RenderTextureOptions {
50
50
  } | null;
51
51
  plugins?: Plugin[];
52
52
  history?: number;
53
- debug?: boolean;
54
53
  cursorTarget?: Window | Element;
55
54
  }
56
55
  interface StepOptions {
@@ -87,10 +86,9 @@ declare class ShaderPad {
87
86
  private hooks;
88
87
  private historyDepth;
89
88
  private textureOptions;
90
- private debug;
91
89
  private cursorTarget;
92
90
  private intermediateFbo;
93
- constructor(fragmentShaderSrc: string, { canvas, plugins, history, debug, cursorTarget, ...textureOptions }?: Options);
91
+ constructor(fragmentShaderSrc: string, { canvas, plugins, history, cursorTarget, ...textureOptions }?: Options);
94
92
  private resolveGLConstant;
95
93
  private emitHook;
96
94
  on(name: LifecycleMethod, fn: Function): void;
@@ -107,10 +105,11 @@ declare class ShaderPad {
107
105
  private clearHistoryTextureLayers;
108
106
  initializeUniform(name: string, type: Uniform['type'], value: number | number[] | (number | number[])[], options?: {
109
107
  arrayLength?: number;
108
+ allowMissing?: boolean;
110
109
  }): void;
111
- private log;
112
110
  updateUniforms(updates: Record<string, number | number[] | (number | number[])[]>, options?: {
113
111
  startIndex?: number;
112
+ allowMissing?: boolean;
114
113
  }): void;
115
114
  private createTexture;
116
115
  private _initializeTexture;
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- "use strict";var w=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var M=(h,t)=>{for(var e in t)w(h,e,{get:t[e],enumerable:!0})},B=(h,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of D(t))!C.call(h,i)&&i!==e&&w(h,i,{get:()=>t[i],enumerable:!(r=N(t,i))||r.enumerable});return h};var H=h=>B(w({},"__esModule",{value:!0}),h);var z={};M(z,{default:()=>$});module.exports=H(z);function F(h,t){return(h%t+t)%t}var W=`#version 300 es
1
+ "use strict";var w=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var B=(o,t)=>{for(var e in t)w(o,e,{get:t[e],enumerable:!0})},W=(o,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of M(t))!N.call(o,r)&&r!==e&&w(o,r,{get:()=>t[r],enumerable:!(i=H(t,r))||i.enumerable});return o};var k=o=>W(w({},"__esModule",{value:!0}),o);var q={};B(q,{default:()=>K});module.exports=k(q);function R(o,t){return(o%t+t)%t}var X="https://rileyjshaw.com/shaderpad/e/";function P(o){return`${X}${o}`}function Y(o,t){let e=new Error(o);return e.code=t,e}function u(o,t){return Y(`ShaderPad error: ${P(o)}`,o)}var V=`#version 300 es
2
2
  in vec2 a_position;
3
3
  out vec2 v_uv;
4
4
  void main() {
5
5
  gl_Position = vec4(a_position, 0.0, 1.0);
6
6
  v_uv = a_position * 0.5 + 0.5;
7
- }`,k=[["8UI","UNSIGNED_BYTE"],["8I","BYTE"],["16UI","UNSIGNED_SHORT"],["16I","SHORT"],["16F","HALF_FLOAT"],["32UI","UNSIGNED_INT"],["32I","INT"],["32F","FLOAT"],["8","UNSIGNED_BYTE"]],G={float:"f",int:"i",uint:"ui"};function X(h){return h&&k.find(([t])=>h.endsWith(t))?.[1]}var I=Symbol("u_history"),p=Symbol("__SHADERPAD_BUFFER"),A=new WeakMap;function Y(h,t){if(!t?.length)return h;let e=h.split(`
8
- `),r=e.findLastIndex(i=>{let s=i.trimStart();return s.startsWith("precision ")||s.startsWith("#version ")})+1;return e.splice(r,0,...t),e.join(`
9
- `)}function P(h){return h instanceof WebGLTexture?{width:0,height:0}:h instanceof _?{width:h.canvas.width,height:h.canvas.height}:h instanceof HTMLVideoElement?{width:h.videoWidth,height:h.videoHeight}:h instanceof HTMLImageElement?{width:h.naturalWidth??h.width,height:h.naturalHeight??h.height}:{width:h.width,height:h.height}}function E(h){return typeof h=="symbol"?h.description??"":h}var _=class h{isHeadless=!1;isTouchDevice=!1;gl;glHelpers;uniforms=new Map;textures=new Map;textureUnitPool;buffer=null;vao=null;program=null;animationFrameId;eventListeners=new Map;frame=0;startTime=Number.NaN;isPlaying=!1;cursorPosition=[.5,.5];clickPosition=[.5,.5];isMouseDown=!1;canvas;resolutionObserver=null;hooks=new Map;historyDepth=0;textureOptions;debug;cursorTarget;intermediateFbo=null;constructor(t,{canvas:e,plugins:r,history:i,debug:s,cursorTarget:a,...o}={}){if(e&&"getContext"in e)this.canvas=e;else{let{width:f=1,height:c=1}=e||{};this.canvas=new OffscreenCanvas(f,c),this.isHeadless=!0}let n=this.canvas.getContext("webgl2",{antialias:!1});if(!n)throw new Error("WebGL2 not supported. Please use a browser that supports WebGL2.");this.gl=n,this.glHelpers={typeToArray:new Map([[n.FLOAT,Float32Array],[n.HALF_FLOAT,Uint16Array],[n.UNSIGNED_SHORT,Uint16Array],[n.SHORT,Int16Array],[n.BYTE,Int8Array],[n.UNSIGNED_INT,Uint32Array],[n.INT,Int32Array]]),typeToInternalFormatString:new Map([[n.FLOAT,"RGBA32F"],[n.HALF_FLOAT,"RGBA16F"],[n.UNSIGNED_SHORT,"RGBA32UI"],[n.SHORT,"RGBA32I"],[n.BYTE,"RGBA32I"],[n.UNSIGNED_INT,"RGBA32UI"],[n.INT,"RGBA32I"]]),unsignedIntTypes:new Set([n.UNSIGNED_BYTE,n.UNSIGNED_SHORT,n.UNSIGNED_INT])};let u=A.get(this.canvas);u||(u={textureUnitPool:{free:[],next:0,max:n.getParameter(n.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},instances:new Set([this])},A.set(this.canvas,u)),this.textureUnitPool=u.textureUnitPool,u.instances.add(this),this.textureOptions=o,i&&(this.historyDepth=i),this.debug=s??(typeof process<"u"&&!1),this.cursorTarget=a??(this.canvas instanceof HTMLCanvasElement?this.canvas:void 0),this.animationFrameId=null;let g=[];r&&r.forEach(f=>f(this,{gl:n,canvas:this.canvas,injectGLSL:c=>{g.push(c)},emitHook:this.emitHook.bind(this),updateTexturesInternal:this.updateTexturesInternal.bind(this)}));let l=this.gl.createProgram();if(!l)throw new Error("Failed to create WebGL program");this.program=l;let T=this.createShader(this.gl.VERTEX_SHADER,W),R=this.createShader(n.FRAGMENT_SHADER,Y(t,g));if(n.attachShader(l,T),n.attachShader(l,R),n.bindAttribLocation(l,0,"a_position"),n.linkProgram(l),n.deleteShader(T),n.deleteShader(R),!n.getProgramParameter(l,n.LINK_STATUS))throw console.error("Program link error:",n.getProgramInfoLog(l)),n.deleteProgram(l),new Error("Failed to link WebGL program");if(this.vao=n.createVertexArray(),n.bindVertexArray(this.vao),this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,this.buffer),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),n.STATIC_DRAW),n.enableVertexAttribArray(0),n.vertexAttribPointer(0,2,n.FLOAT,!1,0,0),n.viewport(0,0,n.drawingBufferWidth,n.drawingBufferHeight),n.useProgram(l),this.canvas instanceof HTMLCanvasElement)this.resolutionObserver=new MutationObserver(()=>this.updateResolution()),this.resolutionObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]});else{let f=c=>{let m=Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype,c),d=this.canvas;Object.defineProperty(d,c,{get:()=>m.get.call(d),set:x=>{m.set.call(d,x);let b=A.get(d);if(b)for(let y of b.instances)y.updateResolution()},configurable:m.configurable,enumerable:m.enumerable})};f("width"),f("height")}this.updateResolution(),this.initializeUniform("u_cursor","float",this.cursorPosition),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0]),this.initializeUniform("u_time","float",0),this.initializeUniform("u_frame","int",0),this._initializeTexture(p,this.canvas,{...this.textureOptions}),this.intermediateFbo=n.createFramebuffer(),this.bindIntermediate(),n.bindFramebuffer(n.FRAMEBUFFER,null),this.historyDepth>0&&this._initializeTexture(I,this.canvas,{history:this.historyDepth,...this.textureOptions}),this.cursorTarget&&this.addEventListeners(),this.emitHook("_init")}resolveGLConstant(t){let e=this.gl[t];if(e===void 0)throw new Error(`Unknown GL constant: ${t}`);return e}emitHook(t,...e){this.hooks.get(t)?.forEach(r=>r.call(this,...e))}on(t,e){this.hooks.has(t)||this.hooks.set(t,[]),this.hooks.get(t).push(e)}off(t,e){let r=this.hooks.get(t);if(r){let i=r.indexOf(e);i>=0&&r.splice(i,1)}}createShader(t,e){let r=this.gl.createShader(t);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS))throw console.error("Shader compilation failed:",e),console.error(this.gl.getShaderInfoLog(r)),this.gl.deleteShader(r),new Error("Shader compilation failed");return r}getCursorTargetRect(){let t=this.cursorTarget;return t===window?{left:0,top:0,width:window.innerWidth,height:window.innerHeight}:t.getBoundingClientRect()}addEventListeners(){if(!this.cursorTarget)return;let t=(r,i)=>{if(!this.uniforms.has("u_cursor"))return;let s=this.getCursorTargetRect(),a=(r-s.left)/s.width,o=1-(i-s.top)/s.height;this.cursorPosition[0]=Math.max(0,Math.min(1,a)),this.cursorPosition[1]=Math.max(0,Math.min(1,o)),this.updateUniforms({u_cursor:this.cursorPosition})},e=(r,i,s)=>{if(this.uniforms.has("u_click")){if(this.isMouseDown=r,r){let a=this.getCursorTargetRect(),o=i,n=s;this.clickPosition[0]=Math.max(0,Math.min(1,(o-a.left)/a.width)),this.clickPosition[1]=Math.max(0,Math.min(1,1-(n-a.top)/a.height))}this.updateUniforms({u_click:[...this.clickPosition,this.isMouseDown?1:0]})}};this.eventListeners.set("mousemove",r=>{let i=r;this.isTouchDevice||t(i.clientX,i.clientY)}),this.eventListeners.set("mousedown",r=>{let i=r;this.isTouchDevice||i.button===0&&(this.isMouseDown=!0,e(!0,i.clientX,i.clientY))}),this.eventListeners.set("mouseup",r=>{let i=r;this.isTouchDevice||i.button===0&&e(!1)}),this.eventListeners.set("touchmove",r=>{let i=r;i.touches.length>0&&t(i.touches[0].clientX,i.touches[0].clientY)}),this.eventListeners.set("touchstart",r=>{let i=r;this.isTouchDevice=!0,i.touches.length>0&&(t(i.touches[0].clientX,i.touches[0].clientY),e(!0,i.touches[0].clientX,i.touches[0].clientY))}),this.eventListeners.set("touchend",r=>{r.touches.length===0&&e(!1)}),this.eventListeners.forEach((r,i)=>{this.cursorTarget.addEventListener(i,r)})}updateResolution(){let t=[this.gl.drawingBufferWidth,this.gl.drawingBufferHeight];this.gl.viewport(0,0,...t),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:t}):this.initializeUniform("u_resolution","float",t),this.resizeTexture(p,...t),this.historyDepth>0&&this.resizeTexture(I,...t),this.emitHook("updateResolution",...t)}resizeTexture(t,e,r){let i=this.textures.get(t);if(!i||i.width===e&&i.height===r)return;this.gl.deleteTexture(i.texture),i.width=e,i.height=r;let{texture:s}=this.createTexture(t,i);i.texture=s,i.history&&(i.history.writeIndex=0,this.clearHistoryTextureLayers(i))}reserveTextureUnit(t){let e=this.textures.get(t);if(e)return e.unitIndex;if(this.textureUnitPool.free.length>0)return this.textureUnitPool.free.pop();if(this.textureUnitPool.next>=this.textureUnitPool.max)throw new Error("Exceeded the available texture units for this device.");return this.textureUnitPool.next++}resolveTextureOptions(t){let{gl:e}=this,r=t?.internalFormat,i=t?.type??X(r)??"UNSIGNED_BYTE",s=this.resolveGLConstant(i),a=r??this.glHelpers.typeToInternalFormatString.get(s)??"RGBA8",o=/^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(a),n=t?.format??(o?"RGBA_INTEGER":"RGBA"),u={type:s,format:this.resolveGLConstant(n),internalFormat:this.resolveGLConstant(a),minFilter:this.resolveGLConstant(t?.minFilter??"LINEAR"),magFilter:this.resolveGLConstant(t?.magFilter??"LINEAR"),wrapS:this.resolveGLConstant(t?.wrapS??"CLAMP_TO_EDGE"),wrapT:this.resolveGLConstant(t?.wrapT??"CLAMP_TO_EDGE"),preserveY:t?.preserveY,isIntegerColorFormat:o};if((u.internalFormat===e.RGBA16F||u.internalFormat===e.RGBA32F)&&!e.getExtension("EXT_color_buffer_float"))throw new Error("Missing EXT_color_buffer_float.");return u}getPixelArray(t,e){let r=this.glHelpers.typeToArray.get(t)??Uint8Array;return new r(e)}isNotRgba(t){return t!==this.gl.RGBA&&t!==this.gl.RGBA_INTEGER}clearHistoryTextureLayers(t){if(!t.history)return;let e=this.gl,{type:r,format:i}=t.options,s=this.getPixelArray(r,t.width*t.height*4);e.activeTexture(e.TEXTURE0+t.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,t.texture);let a=this.isNotRgba(i),o;a&&(o=e.getParameter(e.UNPACK_ALIGNMENT),e.pixelStorei(e.UNPACK_ALIGNMENT,1));for(let n=0;n<t.history.depth;++n)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,n,t.width,t.height,1,i,r,s);a&&e.pixelStorei(e.UNPACK_ALIGNMENT,o)}initializeUniform(t,e,r,i){let s=i?.arrayLength;if(this.uniforms.has(t))throw new Error(`${t} is already initialized.`);if(!G[e])throw new Error(`Invalid uniform type: ${e}. Expected one of: ${Object.keys(G).join(", ")}.`);if(s&&!(Array.isArray(r)&&r.length===s))throw new Error(`${t} array length mismatch: must initialize with ${s} elements.`);let a=this.gl.getUniformLocation(this.program,t);if(!a&&s&&(a=this.gl.getUniformLocation(this.program,`${t}[0]`)),!a){this.log(`${t} not in shader. Skipping initialization.`);return}let o=s?r[0]:r,n=Array.isArray(o)?o.length:1;this.uniforms.set(t,{type:e,length:n,location:a,arrayLength:s});try{this.updateUniforms({[t]:r})}catch(u){throw this.uniforms.delete(t),u}this.emitHook("initializeUniform",...arguments)}log(...t){this.debug&&console.debug(...t)}updateUniforms(t,e){this.gl.useProgram(this.program),Object.entries(t).forEach(([r,i])=>{let s=this.uniforms.get(r);if(!s){this.log(`${r} not in shader. Skipping update.`);return}let a=`uniform${s.length}${G[s.type]}`;if(s.arrayLength){if(!Array.isArray(i))throw new Error(`${r} is an array, but the value passed to updateUniforms is not an array.`);let o=i.length;if(!o)return;if(o>s.arrayLength)throw new Error(`${r} received ${o} values, but maximum length is ${s.arrayLength}.`);if(i.some(l=>(Array.isArray(l)?l.length:1)!==s.length))throw new Error(`Tried to update ${r} with some elements that are not length ${s.length}.`);let n=i.flat(),u=s.type==="float"?new Float32Array(n):s.type==="uint"?new Uint32Array(n):new Int32Array(n),g=s.location;if(e?.startIndex){let l=this.gl.getUniformLocation(this.program,`${r}[${e.startIndex}]`);if(!l)throw new Error(`${r}[${e.startIndex}] not in shader. Did you pass an invalid startIndex?`);g=l}this.gl[a+"v"](g,u)}else{if(Array.isArray(i)||(i=[i]),i.length!==s.length)throw new Error(`Invalid uniform value length: ${i.length}. Expected ${s.length}.`);this.gl[a](s.location,...i)}}),this.emitHook("updateUniforms",...arguments)}createTexture(t,e){let{width:r,height:i}=e,s=e.history?.depth??0,a=this.gl.createTexture();if(!a)throw new Error("Failed to create texture");let o=e.unitIndex;if(typeof o!="number")try{o=this.reserveTextureUnit(t)}catch(l){throw this.gl.deleteTexture(a),l}let n=s>0,u=n?this.gl.TEXTURE_2D_ARRAY:this.gl.TEXTURE_2D,{options:g}=e;return this.gl.activeTexture(this.gl.TEXTURE0+o),this.gl.bindTexture(u,a),this.gl.texParameteri(u,this.gl.TEXTURE_WRAP_S,g.wrapS),this.gl.texParameteri(u,this.gl.TEXTURE_WRAP_T,g.wrapT),this.gl.texParameteri(u,this.gl.TEXTURE_MIN_FILTER,g.minFilter),this.gl.texParameteri(u,this.gl.TEXTURE_MAG_FILTER,g.magFilter),n?this.gl.texStorage3D(u,1,g.internalFormat,r,i,s):t===p&&this.gl.texImage2D(this.gl.TEXTURE_2D,0,g.internalFormat,r,i,0,g.format,g.type,null),{texture:a,unitIndex:o}}_initializeTexture(t,e,r){if(this.textures.has(t))throw new Error(`Texture '${E(t)}' is already initialized.`);let{history:i=0,...s}=r??{},{width:a,height:o}=P(e);if(!a||!o)throw new Error("Texture source must have valid dimensions");let n={width:a,height:o,options:e instanceof h&&Object.keys(s).length===0&&e.textures.has(p)?e.textures.get(p).options:this.resolveTextureOptions(s)};i>0&&(n.history={depth:i,writeIndex:0});let{texture:u,unitIndex:g}=this.createTexture(t,n),l={texture:u,unitIndex:g,...n};i>0&&(this.initializeUniform(`${E(t)}FrameOffset`,"int",0),this.clearHistoryTextureLayers(l)),this.textures.set(t,l),t!==p&&t!==I&&this.updateTexture(t,e),this.gl.useProgram(this.program);let T=this.gl.getUniformLocation(this.program,E(t));T&&this.gl.uniform1i(T,g)}initializeTexture(t,e,r){let i=r?.history!=null&&r.history>0?{...r,history:r.history+1}:r;this._initializeTexture(t,e,i),this.emitHook("initializeTexture",...arguments)}updateTextures(t,e){this.updateTexturesInternal(t,e),this.emitHook("updateTextures",...arguments)}updateTexturesInternal(t,e){Object.entries(t).forEach(([r,i])=>{this.updateTexture(r,i,e)})}updateTexture(t,e,r){let i=this.textures.get(t);if(!i)throw new Error(`Texture '${E(t)}' is not initialized.`);if(e instanceof WebGLTexture){this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,e);return}let s=e;if(e instanceof h){let f=e.textures.get(p),c=f.width,m=f.height;if(e.gl===this.gl){if(!i.history){this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,f.texture);return}let{depth:L}=i.history,U=r?.historyWriteIndex===void 0?[i.history.writeIndex]:Array.isArray(r?.historyWriteIndex)?r.historyWriteIndex.map(S=>F(S,L)):[F(r.historyWriteIndex,L)];this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER,e.intermediateFbo),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture);for(let S of U)this.gl.copyTexSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,S,0,0,c,m);this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER,null),this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture);let O=`${E(t)}FrameOffset`;this.updateUniforms({[O]:U[U.length-1]}),r?.historyWriteIndex===void 0&&(i.history.writeIndex=(i.history.writeIndex+1)%L);return}let{width:d,height:x,options:{format:b,type:y}}=f,v=this.getPixelArray(y,d*x*4);e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,e.intermediateFbo),e.gl.readPixels(0,0,d,x,b,y,v),e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,null),s={data:v,width:d,height:x}}let{width:a,height:o}=P(s);if(!a||!o)return;let n="isPartial"in s&&s.isPartial;n||this.resizeTexture(t,a,o);let u="data"in s&&s.data,g=!u&&!i.options?.preserveY,l=this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL),T=u&&this.isNotRgba(i.options.format),R;if(T&&(R=this.gl.getParameter(this.gl.UNPACK_ALIGNMENT),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1)),i.history){if(this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture),!r?.skipHistoryWrite){let{depth:f}=i.history,c=r?.historyWriteIndex===void 0?[i.history.writeIndex]:Array.isArray(r.historyWriteIndex)?r.historyWriteIndex.map(v=>F(v,f)):[F(r.historyWriteIndex,f)];this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,g);let m=s,d=m.data??s,x=n?m.x??0:0,b=n?m.y??0:0;for(let v of c)this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,x,b,v,a,o,1,i.options.format,i.options.type,d);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,l);let y=`${E(t)}FrameOffset`;this.updateUniforms({[y]:c[c.length-1]}),r?.historyWriteIndex===void 0&&(i.history.writeIndex=(i.history.writeIndex+1)%f)}}else{if(this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,i.texture),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,g),n){let f=s;this.gl.texSubImage2D(this.gl.TEXTURE_2D,0,f.x??0,f.y??0,a,o,i.options.format,i.options.type,f.data)}else this.gl.texImage2D(this.gl.TEXTURE_2D,0,i.options.internalFormat,a,o,0,i.options.format,i.options.type,s.data??s);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,l)}T&&this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,R)}bindIntermediate(){let t=this.gl,e=this.textures.get(p);t.bindFramebuffer(t.FRAMEBUFFER,this.intermediateFbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,e.texture,0)}clear(){this.bindIntermediate();let t=this.gl,e=this.textures.get(p);if(e.options.isIntegerColorFormat){let r=e.options.type;this.glHelpers.unsignedIntTypes.has(r)?t.clearBufferuiv(t.COLOR,0,new Uint32Array(4)):t.clearBufferiv(t.COLOR,0,new Int32Array(4))}else t.clear(t.COLOR_BUFFER_BIT)}draw(t){this.emitHook("beforeDraw",...arguments);let e=this.gl,r=e.drawingBufferWidth,i=e.drawingBufferHeight;t?.skipClear?this.bindIntermediate():this.clear(),e.useProgram(this.program),e.bindVertexArray(this.vao),e.viewport(0,0,r,i),e.drawArrays(e.TRIANGLES,0,3),this.isHeadless||this.textures.get(p).options.isIntegerColorFormat||(e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,r,i,0,0,r,i,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null)),this.emitHook("afterDraw",...arguments)}step(t){Number.isFinite(this.startTime)||(this.startTime=performance.now()),this._step((performance.now()-this.startTime)/1e3,t)}_step(t,e){this.emitHook("beforeStep",t,this.frame,e);let r={};this.uniforms.has("u_time")&&(r.u_time=t),this.uniforms.has("u_frame")&&(r.u_frame=this.frame),this.updateUniforms(r),this.draw(e);let i=this.textures.get(I);if(i&&!e?.skipHistoryWrite){let{writeIndex:s,depth:a}=i.history,o=this.gl;o.bindFramebuffer(o.READ_FRAMEBUFFER,this.intermediateFbo),o.bindTexture(o.TEXTURE_2D_ARRAY,i.texture),o.copyTexSubImage3D(o.TEXTURE_2D_ARRAY,0,0,0,s,0,0,o.drawingBufferWidth,o.drawingBufferHeight),o.bindFramebuffer(o.READ_FRAMEBUFFER,null);let n=(s+1)%a;this.updateUniforms({[`${E(I)}FrameOffset`]:n}),i.history.writeIndex=n}++this.frame,this.emitHook("afterStep",t,this.frame,e)}play(t){this._pause(),Number.isFinite(this.startTime)||(this.startTime=performance.now()),this.isPlaying=!0;let e=r=>{r=(r-this.startTime)/1e3;let i=t?.(r,this.frame)??void 0;this._step(r,i),this.isPlaying&&(this.animationFrameId=requestAnimationFrame(e))};this.animationFrameId=requestAnimationFrame(e),this.emitHook("play")}_pause(){let t=this.isPlaying;return this.isPlaying=!1,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),t}pause(){this._pause()&&this.emitHook("pause")}resetFrame(){this.frame=0,this.startTime=performance.now()}reset(){this.resetFrame(),this.textures.forEach(t=>{t.history&&(t.history.writeIndex=0,this.clearHistoryTextureLayers(t))}),this.clear(),this.emitHook("reset")}destroy(){this.emitHook("destroy"),this._pause(),this.cursorTarget&&(this.eventListeners.forEach((e,r)=>{this.cursorTarget.removeEventListener(r,e)}),this.eventListeners.clear()),this.resolutionObserver&&(this.resolutionObserver.disconnect(),this.resolutionObserver=null),this.program&&(this.gl.deleteProgram(this.program),this.program=null),this.intermediateFbo&&(this.gl.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(e=>{this.textureUnitPool.free.push(e.unitIndex),this.gl.deleteTexture(e.texture)}),this.textures.clear();let t=A.get(this.canvas);t&&(t.instances.delete(this),t.instances.size===0&&A.delete(this.canvas)),this.vao&&(this.gl.deleteVertexArray(this.vao),this.vao=null),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.uniforms.clear(),this.hooks.clear()}},$=_;
7
+ }`,$=[["8UI","UNSIGNED_BYTE"],["8I","BYTE"],["16UI","UNSIGNED_SHORT"],["16I","SHORT"],["16F","HALF_FLOAT"],["32UI","UNSIGNED_INT"],["32I","INT"],["32F","FLOAT"],["8","UNSIGNED_BYTE"]],G={float:"f",int:"i",uint:"ui"};function z(o){return o&&$.find(([t])=>o.endsWith(t))?.[1]}var A=Symbol("u_history"),T=Symbol("__SHADERPAD_BUFFER"),v=new WeakMap;function j(o,t){if(!t?.length)return o;let e=o.split(`
8
+ `),i=e.findLastIndex(r=>{let s=r.trimStart();return s.startsWith("precision ")||s.startsWith("#version ")})+1;return e.splice(i,0,...t),e.join(`
9
+ `)}function O(o){return o instanceof WebGLTexture?{width:0,height:0}:o instanceof I?{width:o.canvas.width,height:o.canvas.height}:o instanceof HTMLVideoElement?{width:o.videoWidth,height:o.videoHeight}:o instanceof HTMLImageElement?{width:o.naturalWidth??o.width,height:o.naturalHeight??o.height}:{width:o.width,height:o.height}}function F(o){return typeof o=="symbol"?o.description??"":o}var I=class o{isHeadless=!1;isTouchDevice=!1;gl;glHelpers;uniforms=new Map;textures=new Map;textureUnitPool;buffer=null;vao=null;program=null;animationFrameId;eventListeners=new Map;frame=0;startTime=Number.NaN;isPlaying=!1;cursorPosition=[.5,.5];clickPosition=[.5,.5];isMouseDown=!1;canvas;resolutionObserver=null;hooks=new Map;historyDepth=0;textureOptions;cursorTarget;intermediateFbo=null;constructor(t,{canvas:e,plugins:i,history:r,cursorTarget:s,...a}={}){if(e&&"getContext"in e)this.canvas=e;else{let{width:f=1,height:m=1}=e||{};this.canvas=new OffscreenCanvas(f,m),this.isHeadless=!0}let n=this.canvas.getContext("webgl2",{antialias:!1});if(!n)throw u(0,!1);this.gl=n,this.glHelpers={typeToArray:new Map([[n.FLOAT,Float32Array],[n.HALF_FLOAT,Uint16Array],[n.UNSIGNED_SHORT,Uint16Array],[n.SHORT,Int16Array],[n.BYTE,Int8Array],[n.UNSIGNED_INT,Uint32Array],[n.INT,Int32Array]]),typeToInternalFormatString:new Map([[n.FLOAT,"RGBA32F"],[n.HALF_FLOAT,"RGBA16F"],[n.UNSIGNED_SHORT,"RGBA32UI"],[n.SHORT,"RGBA32I"],[n.BYTE,"RGBA32I"],[n.UNSIGNED_INT,"RGBA32UI"],[n.INT,"RGBA32I"]]),unsignedIntTypes:new Set([n.UNSIGNED_BYTE,n.UNSIGNED_SHORT,n.UNSIGNED_INT])};let h=v.get(this.canvas);h||(h={textureUnitPool:{free:[],next:0,max:n.getParameter(n.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},instances:new Set([this])},v.set(this.canvas,h)),this.textureUnitPool=h.textureUnitPool,h.instances.add(this),this.textureOptions=a,r&&(this.historyDepth=r),this.cursorTarget=s??(this.canvas instanceof HTMLCanvasElement?this.canvas:void 0),this.animationFrameId=null;let g=[];i&&i.forEach(f=>f(this,{gl:n,canvas:this.canvas,injectGLSL:m=>{g.push(m)},emitHook:this.emitHook.bind(this),updateTexturesInternal:this.updateTexturesInternal.bind(this)}));let l=this.gl.createProgram();if(!l)throw u(1);this.program=l;let c=this.createShader(this.gl.VERTEX_SHADER,V),E=this.createShader(n.FRAGMENT_SHADER,j(t,g));if(n.attachShader(l,c),n.attachShader(l,E),n.bindAttribLocation(l,0,"a_position"),n.linkProgram(l),n.deleteShader(c),n.deleteShader(E),!n.getProgramParameter(l,n.LINK_STATUS)){let f=n.getProgramInfoLog(l),m=u(2,!1);throw n.deleteProgram(l),m}if(this.vao=n.createVertexArray(),n.bindVertexArray(this.vao),this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,this.buffer),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),n.STATIC_DRAW),n.enableVertexAttribArray(0),n.vertexAttribPointer(0,2,n.FLOAT,!1,0,0),n.viewport(0,0,n.drawingBufferWidth,n.drawingBufferHeight),n.useProgram(l),this.canvas instanceof HTMLCanvasElement)this.resolutionObserver=new MutationObserver(()=>this.updateResolution()),this.resolutionObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]});else{let f=m=>{let d=Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype,m),p=this.canvas;Object.defineProperty(p,m,{get:()=>d.get.call(p),set:_=>{d.set.call(p,_);let x=v.get(p);if(x)for(let b of x.instances)b.updateResolution()},configurable:d.configurable,enumerable:d.enumerable})};f("width"),f("height")}this.updateResolution(),this.initializeUniform("u_cursor","float",this.cursorPosition,{allowMissing:!0}),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0],{allowMissing:!0}),this.initializeUniform("u_time","float",0,{allowMissing:!0}),this.initializeUniform("u_frame","int",0,{allowMissing:!0}),this._initializeTexture(T,this.canvas,{...this.textureOptions}),this.intermediateFbo=n.createFramebuffer(),this.bindIntermediate(),n.bindFramebuffer(n.FRAMEBUFFER,null),this.historyDepth>0&&this._initializeTexture(A,this.canvas,{history:this.historyDepth,...this.textureOptions}),this.cursorTarget&&this.addEventListeners(),this.emitHook("_init")}resolveGLConstant(t){let e=this.gl[t];if(e===void 0)throw u(3,!1);return e}emitHook(t,...e){this.hooks.get(t)?.forEach(i=>i.call(this,...e))}on(t,e){this.hooks.has(t)||this.hooks.set(t,[]),this.hooks.get(t).push(e)}off(t,e){let i=this.hooks.get(t);if(i){let r=i.indexOf(e);r>=0&&i.splice(r,1)}}createShader(t,e){let i=this.gl.createShader(t);if(this.gl.shaderSource(i,e),this.gl.compileShader(i),!this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS)){let r=this.gl.getShaderInfoLog(i),s=t===this.gl.VERTEX_SHADER?"vertex":"fragment",a=u(4,!1);throw this.gl.deleteShader(i),a}return i}getCursorTargetRect(){let t=this.cursorTarget;return t===window?{left:0,top:0,width:window.innerWidth,height:window.innerHeight}:t.getBoundingClientRect()}addEventListeners(){if(!this.cursorTarget)return;let t=(i,r)=>{if(!this.uniforms.has("u_cursor"))return;let s=this.getCursorTargetRect(),a=(i-s.left)/s.width,n=1-(r-s.top)/s.height;this.cursorPosition[0]=Math.max(0,Math.min(1,a)),this.cursorPosition[1]=Math.max(0,Math.min(1,n)),this.updateUniforms({u_cursor:this.cursorPosition})},e=(i,r,s)=>{if(this.uniforms.has("u_click")){if(this.isMouseDown=i,i){let a=this.getCursorTargetRect(),n=r,h=s;this.clickPosition[0]=Math.max(0,Math.min(1,(n-a.left)/a.width)),this.clickPosition[1]=Math.max(0,Math.min(1,1-(h-a.top)/a.height))}this.updateUniforms({u_click:[...this.clickPosition,this.isMouseDown?1:0]})}};this.eventListeners.set("mousemove",i=>{let r=i;this.isTouchDevice||t(r.clientX,r.clientY)}),this.eventListeners.set("mousedown",i=>{let r=i;this.isTouchDevice||r.button===0&&(this.isMouseDown=!0,e(!0,r.clientX,r.clientY))}),this.eventListeners.set("mouseup",i=>{let r=i;this.isTouchDevice||r.button===0&&e(!1)}),this.eventListeners.set("touchmove",i=>{let r=i;r.touches.length>0&&t(r.touches[0].clientX,r.touches[0].clientY)}),this.eventListeners.set("touchstart",i=>{let r=i;this.isTouchDevice=!0,r.touches.length>0&&(t(r.touches[0].clientX,r.touches[0].clientY),e(!0,r.touches[0].clientX,r.touches[0].clientY))}),this.eventListeners.set("touchend",i=>{i.touches.length===0&&e(!1)}),this.eventListeners.forEach((i,r)=>{this.cursorTarget.addEventListener(r,i)})}updateResolution(){let t=[this.gl.drawingBufferWidth,this.gl.drawingBufferHeight];this.gl.viewport(0,0,...t),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:t}):this.initializeUniform("u_resolution","float",t,{allowMissing:!0}),this.resizeTexture(T,...t),this.historyDepth>0&&this.resizeTexture(A,...t),this.emitHook("updateResolution",...t)}resizeTexture(t,e,i){let r=this.textures.get(t);if(!r||r.width===e&&r.height===i)return;this.gl.deleteTexture(r.texture),r.width=e,r.height=i;let{texture:s}=this.createTexture(t,r);r.texture=s,r.history&&(r.history.writeIndex=0,this.clearHistoryTextureLayers(r))}reserveTextureUnit(t){let e=this.textures.get(t);if(e)return e.unitIndex;if(this.textureUnitPool.free.length>0)return this.textureUnitPool.free.pop();if(this.textureUnitPool.next>=this.textureUnitPool.max)throw u(5,!1);return this.textureUnitPool.next++}resolveTextureOptions(t){let{gl:e}=this,i=t?.internalFormat,r=t?.type??z(i)??"UNSIGNED_BYTE",s=this.resolveGLConstant(r),a=i??this.glHelpers.typeToInternalFormatString.get(s)??"RGBA8",n=/^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(a),h=t?.format??(n?"RGBA_INTEGER":"RGBA"),g={type:s,format:this.resolveGLConstant(h),internalFormat:this.resolveGLConstant(a),minFilter:this.resolveGLConstant(t?.minFilter??"LINEAR"),magFilter:this.resolveGLConstant(t?.magFilter??"LINEAR"),wrapS:this.resolveGLConstant(t?.wrapS??"CLAMP_TO_EDGE"),wrapT:this.resolveGLConstant(t?.wrapT??"CLAMP_TO_EDGE"),preserveY:t?.preserveY,isIntegerColorFormat:n};if((g.internalFormat===e.RGBA16F||g.internalFormat===e.RGBA32F)&&!e.getExtension("EXT_color_buffer_float"))throw u(6,!1);return g}getPixelArray(t,e){let i=this.glHelpers.typeToArray.get(t)??Uint8Array;return new i(e)}isNotRgba(t){return t!==this.gl.RGBA&&t!==this.gl.RGBA_INTEGER}clearHistoryTextureLayers(t){if(!t.history)return;let e=this.gl,{type:i,format:r}=t.options,s=this.getPixelArray(i,t.width*t.height*4);e.activeTexture(e.TEXTURE0+t.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,t.texture);let a=this.isNotRgba(r),n;a&&(n=e.getParameter(e.UNPACK_ALIGNMENT),e.pixelStorei(e.UNPACK_ALIGNMENT,1));for(let h=0;h<t.history.depth;++h)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,h,t.width,t.height,1,r,i,s);a&&e.pixelStorei(e.UNPACK_ALIGNMENT,n)}initializeUniform(t,e,i,r){let s=r?.arrayLength,a=r?.allowMissing??!1;if(this.uniforms.has(t))throw u(7,!1);if(!G[e])throw u(8,!1);if(s&&!(Array.isArray(i)&&i.length===s))throw u(9,!1);let n=this.gl.getUniformLocation(this.program,t);if(!n&&s&&(n=this.gl.getUniformLocation(this.program,`${t}[0]`)),!n){if(a)return;throw u(19,!1)}let h=s?i[0]:i,g=Array.isArray(h)?h.length:1;this.uniforms.set(t,{type:e,length:g,location:n,arrayLength:s});try{this.updateUniforms({[t]:i})}catch(l){throw this.uniforms.delete(t),l}this.emitHook("initializeUniform",...arguments)}updateUniforms(t,e){this.gl.useProgram(this.program),Object.entries(t).forEach(([i,r])=>{let s=this.uniforms.get(i);if(!s){if(e?.allowMissing)return;throw u(20,!1)}let a=`uniform${s.length}${G[s.type]}`;if(s.arrayLength){if(!Array.isArray(r))throw u(10,!1);let n=r.length;if(!n)return;if(n>s.arrayLength)throw u(11,!1);if(r.some(c=>(Array.isArray(c)?c.length:1)!==s.length))throw u(12,!1);let h=r.flat(),g=s.type==="float"?new Float32Array(h):s.type==="uint"?new Uint32Array(h):new Int32Array(h),l=s.location;if(e?.startIndex){let c=this.gl.getUniformLocation(this.program,`${i}[${e.startIndex}]`);if(!c)throw u(13,!1);l=c}this.gl[a+"v"](l,g)}else{Array.isArray(r)||(r=[r]);let n=r;if(n.length!==s.length)throw u(14,!1);this.gl[a](s.location,...n)}}),this.emitHook("updateUniforms",...arguments)}createTexture(t,e){let{width:i,height:r}=e,s=e.history?.depth??0,a=this.gl.createTexture();if(!a)throw u(15,!1);let n=e.unitIndex;if(typeof n!="number")try{n=this.reserveTextureUnit(t)}catch(c){throw this.gl.deleteTexture(a),c}let h=s>0,g=h?this.gl.TEXTURE_2D_ARRAY:this.gl.TEXTURE_2D,{options:l}=e;return this.gl.activeTexture(this.gl.TEXTURE0+n),this.gl.bindTexture(g,a),this.gl.texParameteri(g,this.gl.TEXTURE_WRAP_S,l.wrapS),this.gl.texParameteri(g,this.gl.TEXTURE_WRAP_T,l.wrapT),this.gl.texParameteri(g,this.gl.TEXTURE_MIN_FILTER,l.minFilter),this.gl.texParameteri(g,this.gl.TEXTURE_MAG_FILTER,l.magFilter),h?this.gl.texStorage3D(g,1,l.internalFormat,i,r,s):t===T&&this.gl.texImage2D(this.gl.TEXTURE_2D,0,l.internalFormat,i,r,0,l.format,l.type,null),{texture:a,unitIndex:n}}_initializeTexture(t,e,i){if(this.textures.has(t))throw u(16,!1);let{history:r=0,...s}=i??{},{width:a,height:n}=O(e);if(!a||!n)throw u(17,!1);let h={width:a,height:n,options:e instanceof o&&Object.keys(s).length===0&&e.textures.has(T)?e.textures.get(T).options:this.resolveTextureOptions(s)};r>0&&(h.history={depth:r,writeIndex:0});let{texture:g,unitIndex:l}=this.createTexture(t,h),c={texture:g,unitIndex:l,...h};r>0&&(this.initializeUniform(`${F(t)}FrameOffset`,"int",0,{allowMissing:!0}),this.clearHistoryTextureLayers(c)),this.textures.set(t,c),t!==T&&t!==A&&this.updateTexture(t,e),this.gl.useProgram(this.program);let E=this.gl.getUniformLocation(this.program,F(t));E&&this.gl.uniform1i(E,l)}initializeTexture(t,e,i){let r=i?.history!=null&&i.history>0?{...i,history:i.history+1}:i;this._initializeTexture(t,e,r),this.emitHook("initializeTexture",...arguments)}updateTextures(t,e){this.updateTexturesInternal(t,e),this.emitHook("updateTextures",...arguments)}updateTexturesInternal(t,e){Object.entries(t).forEach(([i,r])=>{this.updateTexture(i,r,e)})}updateTexture(t,e,i){let r=this.textures.get(t);if(!r)throw u(18,!1);if(e instanceof WebGLTexture){this.gl.activeTexture(this.gl.TEXTURE0+r.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,e);return}let s=e;if(e instanceof o){let m=e.textures.get(T),d=m.width,p=m.height;if(e.gl===this.gl){if(!r.history){this.gl.activeTexture(this.gl.TEXTURE0+r.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,m.texture);return}let{depth:L}=r.history,U=i?.historyWriteIndex===void 0?[r.history.writeIndex]:Array.isArray(i?.historyWriteIndex)?i.historyWriteIndex.map(D=>R(D,L)):[R(i.historyWriteIndex,L)];this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER,e.intermediateFbo),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,r.texture);for(let D of U)this.gl.copyTexSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,D,0,0,d,p);this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER,null),this.gl.activeTexture(this.gl.TEXTURE0+r.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,r.texture);let C=`${F(t)}FrameOffset`;this.updateUniforms({[C]:U[U.length-1]},{allowMissing:!0}),i?.historyWriteIndex===void 0&&(r.history.writeIndex=(r.history.writeIndex+1)%L);return}let{width:_,height:x,options:{format:b,type:S}}=m,y=this.getPixelArray(S,_*x*4);e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,e.intermediateFbo),e.gl.readPixels(0,0,_,x,b,S,y),e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,null),s={data:y,width:_,height:x}}let{width:a,height:n}=O(s);if(!a||!n)return;let h="isPartial"in s&&s.isPartial;h||this.resizeTexture(t,a,n);let g="data"in s&&s.data,l=!g&&!r.options?.preserveY,c=this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL),E=g&&this.isNotRgba(r.options.format),f;if(E&&(f=this.gl.getParameter(this.gl.UNPACK_ALIGNMENT),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1)),r.history){if(this.gl.activeTexture(this.gl.TEXTURE0+r.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,r.texture),!i?.skipHistoryWrite){let{depth:m}=r.history,d=i?.historyWriteIndex===void 0?[r.history.writeIndex]:Array.isArray(i.historyWriteIndex)?i.historyWriteIndex.map(y=>R(y,m)):[R(i.historyWriteIndex,m)];this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,l);let p=s,_=p.data??s,x=h?p.x??0:0,b=h?p.y??0:0;for(let y of d)this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,x,b,y,a,n,1,r.options.format,r.options.type,_);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c);let S=`${F(t)}FrameOffset`;this.updateUniforms({[S]:d[d.length-1]}),i?.historyWriteIndex===void 0&&(r.history.writeIndex=(r.history.writeIndex+1)%m)}}else{if(this.gl.activeTexture(this.gl.TEXTURE0+r.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,r.texture),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,l),h){let m=s;this.gl.texSubImage2D(this.gl.TEXTURE_2D,0,m.x??0,m.y??0,a,n,r.options.format,r.options.type,m.data)}else this.gl.texImage2D(this.gl.TEXTURE_2D,0,r.options.internalFormat,a,n,0,r.options.format,r.options.type,s.data??s);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c)}E&&this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,f)}bindIntermediate(){let t=this.gl,e=this.textures.get(T);t.bindFramebuffer(t.FRAMEBUFFER,this.intermediateFbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,e.texture,0)}clear(){this.bindIntermediate();let t=this.gl,e=this.textures.get(T);if(e.options.isIntegerColorFormat){let i=e.options.type;this.glHelpers.unsignedIntTypes.has(i)?t.clearBufferuiv(t.COLOR,0,new Uint32Array(4)):t.clearBufferiv(t.COLOR,0,new Int32Array(4))}else t.clear(t.COLOR_BUFFER_BIT)}draw(t){this.emitHook("beforeDraw",...arguments);let e=this.gl,i=e.drawingBufferWidth,r=e.drawingBufferHeight;t?.skipClear?this.bindIntermediate():this.clear(),e.useProgram(this.program),e.bindVertexArray(this.vao),e.viewport(0,0,i,r),e.drawArrays(e.TRIANGLES,0,3),this.isHeadless||this.textures.get(T).options.isIntegerColorFormat||(e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,i,r,0,0,i,r,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null)),this.emitHook("afterDraw",...arguments)}step(t){Number.isFinite(this.startTime)||(this.startTime=performance.now()),this._step((performance.now()-this.startTime)/1e3,t)}_step(t,e){this.emitHook("beforeStep",t,this.frame,e);let i={};this.uniforms.has("u_time")&&(i.u_time=t),this.uniforms.has("u_frame")&&(i.u_frame=this.frame),this.updateUniforms(i),this.draw(e);let r=this.textures.get(A);if(r&&!e?.skipHistoryWrite){let{writeIndex:s,depth:a}=r.history,n=this.gl;n.bindFramebuffer(n.READ_FRAMEBUFFER,this.intermediateFbo),n.bindTexture(n.TEXTURE_2D_ARRAY,r.texture),n.copyTexSubImage3D(n.TEXTURE_2D_ARRAY,0,0,0,s,0,0,n.drawingBufferWidth,n.drawingBufferHeight),n.bindFramebuffer(n.READ_FRAMEBUFFER,null);let h=(s+1)%a;this.updateUniforms({[`${F(A)}FrameOffset`]:h},{allowMissing:!0}),r.history.writeIndex=h}++this.frame,this.emitHook("afterStep",t,this.frame,e)}play(t){this._pause(),Number.isFinite(this.startTime)||(this.startTime=performance.now()),this.isPlaying=!0;let e=i=>{i=(i-this.startTime)/1e3;let r=t?.(i,this.frame)??void 0;this._step(i,r),this.isPlaying&&(this.animationFrameId=requestAnimationFrame(e))};this.animationFrameId=requestAnimationFrame(e),this.emitHook("play")}_pause(){let t=this.isPlaying;return this.isPlaying=!1,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),t}pause(){this._pause()&&this.emitHook("pause")}resetFrame(){this.frame=0,this.startTime=performance.now()}reset(){this.resetFrame(),this.textures.forEach(t=>{t.history&&(t.history.writeIndex=0,this.clearHistoryTextureLayers(t))}),this.clear(),this.emitHook("reset")}destroy(){this.emitHook("destroy"),this._pause(),this.cursorTarget&&(this.eventListeners.forEach((e,i)=>{this.cursorTarget.removeEventListener(i,e)}),this.eventListeners.clear()),this.resolutionObserver&&(this.resolutionObserver.disconnect(),this.resolutionObserver=null),this.program&&(this.gl.deleteProgram(this.program),this.program=null),this.intermediateFbo&&(this.gl.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(e=>{this.textureUnitPool.free.push(e.unitIndex),this.gl.deleteTexture(e.texture)}),this.textures.clear();let t=v.get(this.canvas);t&&(t.instances.delete(this),t.instances.size===0&&v.delete(this.canvas)),this.vao&&(this.gl.deleteVertexArray(this.vao),this.vao=null),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.uniforms.clear(),this.hooks.clear()}},K=I;
10
10
  //# sourceMappingURL=index.js.map