shaderpad 1.0.0-beta.82 → 1.0.0-beta.83
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.
- package/CHANGELOG.md +6 -0
- package/README.md +19 -2
- package/dist/chunk-4UKNQUGK.mjs +5 -0
- package/dist/chunk-4UKNQUGK.mjs.map +1 -0
- package/dist/chunk-FVO6LH2F.mjs +2 -0
- package/dist/chunk-FVO6LH2F.mjs.map +1 -0
- package/dist/dev/{chunk-YN3AO6HP.mjs → chunk-UOFU6ODR.mjs} +3 -2
- package/dist/dev/chunk-UOFU6ODR.mjs.map +1 -0
- package/dist/dev/{chunk-TTKZ43JC.mjs → chunk-YB3GMXKV.mjs} +15 -7
- package/dist/dev/chunk-YB3GMXKV.mjs.map +1 -0
- package/dist/dev/index.js +14 -6
- package/dist/dev/index.js.map +1 -1
- package/dist/dev/index.mjs +1 -1
- package/dist/dev/plugins/pose.js +14 -6
- package/dist/dev/plugins/pose.js.map +1 -1
- package/dist/dev/plugins/pose.mjs +1 -1
- package/dist/dev/plugins/segmenter.js +14 -6
- package/dist/dev/plugins/segmenter.js.map +1 -1
- package/dist/dev/plugins/segmenter.mjs +1 -1
- package/dist/dev/react.js +16 -7
- package/dist/dev/react.js.map +1 -1
- package/dist/dev/react.mjs +2 -2
- package/dist/dev/web-component.js +16 -7
- package/dist/dev/web-component.js.map +1 -1
- package/dist/dev/web-component.mjs +2 -2
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/plugins/pose.js +29 -29
- package/dist/plugins/pose.js.map +1 -1
- package/dist/plugins/pose.mjs +1 -1
- package/dist/plugins/segmenter.js +10 -10
- package/dist/plugins/segmenter.js.map +1 -1
- package/dist/plugins/segmenter.mjs +1 -1
- package/dist/react.js +3 -3
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1 -1
- package/dist/web-component.js +4 -4
- package/dist/web-component.js.map +1 -1
- package/dist/web-component.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-B3EEZDUT.mjs +0 -5
- package/dist/chunk-B3EEZDUT.mjs.map +0 -1
- package/dist/chunk-O3TAD633.mjs +0 -2
- package/dist/chunk-O3TAD633.mjs.map +0 -1
- package/dist/dev/chunk-TTKZ43JC.mjs.map +0 -1
- package/dist/dev/chunk-YN3AO6HP.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -222,6 +222,7 @@ shader.initializeTexture('u_canvas', canvasElement, { preserveY: true });
|
|
|
222
222
|
- `magFilter?: string` - Magnification filter (default: `'LINEAR'`). Examples: `'LINEAR'`, `'NEAREST'`
|
|
223
223
|
- `wrapS?: string` - Wrap mode for S coordinate (default: `'CLAMP_TO_EDGE'`). Examples: `'CLAMP_TO_EDGE'`, `'REPEAT'`, `'MIRRORED_REPEAT'`
|
|
224
224
|
- `wrapT?: string` - Wrap mode for T coordinate (default: `'CLAMP_TO_EDGE'`). Examples: `'CLAMP_TO_EDGE'`, `'REPEAT'`, `'MIRRORED_REPEAT'`
|
|
225
|
+
- `colorSpace?: 'srgb' | 'display-p3'` - Color space for DOM texture upload conversion where supported
|
|
225
226
|
|
|
226
227
|
**Note:** For typed array sources (`CustomTexture`), you must provide data in bottom-up orientation (WebGL convention). The `preserveY` option is ignored for typed arrays.
|
|
227
228
|
|
|
@@ -314,7 +315,7 @@ shader.destroy(); // Clean up resources.
|
|
|
314
315
|
### Type exports
|
|
315
316
|
|
|
316
317
|
`shaderpad` exports `Options`, `StepOptions`, `TextureOptions`, `InitializeTextureOptions`, `TextureSource`,
|
|
317
|
-
`UpdateTextureSource`, `CustomTexture`, `PartialCustomTexture`, `Plugin`, `PluginContext`, `ShaderPadEventName`, and
|
|
318
|
+
`UpdateTextureSource`, `CustomTexture`, `PartialCustomTexture`, `Plugin`, `PluginContext`, `ShaderPadEventName`, `ColorSpace`, and
|
|
318
319
|
the GL literal string types. `shaderpad/util` exports `ToBlobOptions` and `SaveOptions`.
|
|
319
320
|
|
|
320
321
|
### Event Listeners
|
|
@@ -388,7 +389,7 @@ examples, browse the
|
|
|
388
389
|
ShaderPad’s constructor accepts an optional `options` object.
|
|
389
390
|
|
|
390
391
|
In addition to the fields below, constructor options also accept texture storage/filter/wrap settings such as
|
|
391
|
-
`internalFormat`, `format`, `type`, `minFilter`, `magFilter`, `wrapS`, and `
|
|
392
|
+
`internalFormat`, `format`, `type`, `minFilter`, `magFilter`, `wrapS`, `wrapT`, and `colorSpace`. These configure ShaderPad’s
|
|
392
393
|
internal render targets and history buffers, which is mainly useful for float/integer pipelines and chained shaders.
|
|
393
394
|
|
|
394
395
|
### canvas
|
|
@@ -464,6 +465,22 @@ float zIndex = historyZ(u_webcam, u_webcamFrameOffset, nFramesAgo);
|
|
|
464
465
|
vec4 historyColor = texture(u_webcam, vec3(v_uv, zIndex));
|
|
465
466
|
```
|
|
466
467
|
|
|
468
|
+
### colorSpace
|
|
469
|
+
|
|
470
|
+
Opt into browser color management for wide-gamut work.
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
const shader = new ShaderPad(fragmentShaderSrc, {
|
|
474
|
+
colorSpace: 'display-p3',
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
shader.initializeTexture('u_image', imageElement, {
|
|
478
|
+
colorSpace: 'display-p3',
|
|
479
|
+
});
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
On the constructor, `colorSpace` applies to the WebGL drawing buffer and ShaderPad’s internal render texture. On `initializeTexture()`, it applies while uploading DOM image-like sources such as images, videos, canvases, and `ImageBitmap`. Typed-array textures are not color-converted.
|
|
483
|
+
|
|
467
484
|
### plugins
|
|
468
485
|
|
|
469
486
|
ShaderPad adds additional functionality through plugins, which keeps bundle sizes small.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{a as m,b as S}from"./chunk-QROQ7JVO.mjs";var C=`#version 300 es
|
|
2
|
+
in vec2 a_position;out vec2 v_uv;void main(){gl_Position=vec4(a_position,0.,1.);v_uv=a_position*.5+.5;}`,M=[["8UI","UNSIGNED_BYTE"],["8I","BYTE"],["16UI","UNSIGNED_SHORT"],["16I","SHORT"],["16F","HALF_FLOAT"],["32UI","UNSIGNED_INT"],["32I","INT"],["32F","FLOAT"],["8","UNSIGNED_BYTE"]],N={float:"f",int:"i",uint:"ui"};function B(l){return l&&M.find(([r])=>l.endsWith(r))?.[1]}var v=Symbol("u_history"),g=Symbol("__SHADERPAD_BUFFER"),F=new WeakMap;function H(l,r){if(!r?.length)return l;let e=l.split(`
|
|
3
|
+
`),i=e.findLastIndex(t=>{let s=t.trimStart();return s.startsWith("precision ")||s.startsWith("#version ")})+1;return e.splice(i,0,...r),e.join(`
|
|
4
|
+
`)}function O(l){return l instanceof WebGLTexture?{width:0,height:0}:l instanceof I?{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 P(l){return typeof l=="symbol"?l.description??"":l}var I=class l{isHeadless=!1;isTouch=!1;uniforms=new Map;textures=new Map;buffer=null;vao=null;program=null;listeners=new Map;frame=0;tElapsed=0;tStart=NaN;cursorPos=[.5,.5];clickPos=[.5,.5];isClicked=!1;resObserver=null;hooks=new Map;historyDepth=0;intermediateFbo=null;constructor(r,{canvas:e,plugins:i,history:t,cursorTarget:s,...a}={}){if(e&&"getContext"in e)this.canvas=e;else{let{width:f=1,height:E=1}=e||{};this.canvas=new OffscreenCanvas(f,E),this.isHeadless=!0}let n=this.canvas.getContext("webgl2",{antialias:!1});if(!n)throw m(0);a.colorSpace&&"drawingBufferColorSpace"in n&&(n.drawingBufferColorSpace=a.colorSpace),this.gl=n,this.typeArrays=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]]),this.typeFormats=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"]]),this.uintTypes=new Set([n.UNSIGNED_BYTE,n.UNSIGNED_SHORT,n.UNSIGNED_INT]);let o=F.get(this.canvas);o||(o={texPool:{free:[],next:0,max:n.getParameter(n.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},instances:new Set([this])},F.set(this.canvas,o)),this.texPool=o.texPool,o.instances.add(this),this.texOptions=a,t&&(this.historyDepth=t),this.cursorTgt=s??(this.canvas instanceof HTMLCanvasElement?this.canvas:void 0),this.frameId=null;let h=[];i&&i.forEach(f=>f(this,{injectGLSL:E=>{h.push(E)},emit:this.emit.bind(this),updateTexture:this.updateTex.bind(this)}));let u=n.createProgram();if(!u)throw m(1);this.program=u;let c=this.createShader(n.VERTEX_SHADER,C),p=this.createShader(n.FRAGMENT_SHADER,H(r,h));if(n.attachShader(u,c),n.attachShader(u,p),n.bindAttribLocation(u,0,"a_position"),n.linkProgram(u),n.deleteShader(c),n.deleteShader(p),!n.getProgramParameter(u,n.LINK_STATUS)){let f=m(2);throw n.deleteProgram(u),f}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(u),this.canvas instanceof HTMLCanvasElement)this.resObserver=new MutationObserver(()=>this.syncRes()),this.resObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]});else{let f=E=>{let b=Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype,E),x=this.canvas;Object.defineProperty(x,E,{get:()=>b.get.call(x),set:d=>{b.set.call(x,d);let T=F.get(x);if(T)for(let _ of T.instances)_.syncRes()},configurable:b.configurable,enumerable:b.enumerable})};f("width"),f("height")}this.syncRes(),this.initializeUniform("u_cursor","float",this.cursorPos,{allowMissing:!0}),this.initializeUniform("u_click","float",[...this.clickPos,this.isClicked?1:0],{allowMissing:!0}),this.initializeUniform("u_time","float",0,{allowMissing:!0}),this.initializeUniform("u_frame","int",0,{allowMissing:!0}),this.initTex(g,this.canvas,{...this.texOptions}),this.intermediateFbo=n.createFramebuffer(),this.bindIntermediate(),n.bindFramebuffer(n.FRAMEBUFFER,null),this.historyDepth>0&&this.initTex(v,this.canvas,{history:this.historyDepth,...this.texOptions}),this.addListeners(),this.emit("_init")}resolveGLConst(r){let i=this.gl[r];if(i===void 0)throw m(3);return i}emit(r,...e){this.hooks.get(r)?.forEach(i=>i.call(this,...e))}on(r,e){this.hooks.has(r)||this.hooks.set(r,[]),this.hooks.get(r).push(e)}off(r,e){let i=this.hooks.get(r);if(i){let t=i.indexOf(e);t>=0&&i.splice(t,1)}}createShader(r,e){let i=this.gl,t=i.createShader(r);if(i.shaderSource(t,e),i.compileShader(t),!i.getShaderParameter(t,i.COMPILE_STATUS)){console.error(i.getShaderInfoLog(t));let s=m(4);throw i.deleteShader(t),s}return t}getCursorTgtRect(){let r=this.cursorTgt;return r===window?{left:0,top:0,width:window.innerWidth,height:window.innerHeight}:r.getBoundingClientRect()}addListeners(){if(!this.cursorTgt)return;let r=(i,t)=>{if(!this.uniforms.has("u_cursor"))return;let s=this.getCursorTgtRect(),a=(i-s.left)/s.width,n=1-(t-s.top)/s.height;this.cursorPos[0]=Math.max(0,Math.min(1,a)),this.cursorPos[1]=Math.max(0,Math.min(1,n)),this.updateUniforms({u_cursor:this.cursorPos})},e=(i,t,s)=>{if(this.uniforms.has("u_click")){if(this.isClicked=i,i){let a=this.getCursorTgtRect(),n=t,o=s;this.clickPos[0]=Math.max(0,Math.min(1,(n-a.left)/a.width)),this.clickPos[1]=Math.max(0,Math.min(1,1-(o-a.top)/a.height))}this.updateUniforms({u_click:[...this.clickPos,this.isClicked?1:0]})}};this.listeners.set("mousemove",i=>{let t=i;this.isTouch||r(t.clientX,t.clientY)}),this.listeners.set("mousedown",i=>{let t=i;this.isTouch||t.button===0&&(this.isClicked=!0,e(!0,t.clientX,t.clientY))}),this.listeners.set("mouseup",i=>{let t=i;this.isTouch||t.button===0&&e(!1)}),this.listeners.set("touchmove",i=>{let t=i;t.touches.length>0&&r(t.touches[0].clientX,t.touches[0].clientY)}),this.listeners.set("touchstart",i=>{let t=i;this.isTouch=!0,t.touches.length>0&&(r(t.touches[0].clientX,t.touches[0].clientY),e(!0,t.touches[0].clientX,t.touches[0].clientY))}),this.listeners.set("touchend",i=>{i.touches.length===0&&e(!1)}),this.listeners.forEach((i,t)=>{this.cursorTgt.addEventListener(t,i)})}syncRes(){let r=this.gl,e=[r.drawingBufferWidth,r.drawingBufferHeight];r.viewport(0,0,...e),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:e}):this.initializeUniform("u_resolution","float",e,{allowMissing:!0}),this.resizeTex(g,...e),this.historyDepth>0&&this.resizeTex(v,...e),this.emit("updateResolution",...e)}resizeTex(r,e,i){let t=this.textures.get(r);if(!t||t.width===e&&t.height===i)return;this.gl.deleteTexture(t.texture),t.width=e,t.height=i;let{texture:a}=this.createTex(r,t);t.texture=a,this.resetHist(r,t)}reserveTex(r){let e=this.textures.get(r);if(e)return e.unitIndex;if(this.texPool.free.length>0)return this.texPool.free.pop();if(this.texPool.next>=this.texPool.max)throw m(5);return this.texPool.next++}resolveTexOpts(r){let{gl:e}=this,i=r?.internalFormat,t=r?.type??B(i)??"UNSIGNED_BYTE",s=this.resolveGLConst(t),a=i??this.typeFormats.get(s)??"RGBA8",n=/^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(a),o=r?.format??(n?"RGBA_INTEGER":"RGBA"),h={type:s,format:this.resolveGLConst(o),internalFormat:this.resolveGLConst(a),minFilter:this.resolveGLConst(r?.minFilter??"LINEAR"),magFilter:this.resolveGLConst(r?.magFilter??"LINEAR"),wrapS:this.resolveGLConst(r?.wrapS??"CLAMP_TO_EDGE"),wrapT:this.resolveGLConst(r?.wrapT??"CLAMP_TO_EDGE"),colorSpace:r?.colorSpace,preserveY:r?.preserveY,isIntegerColorFormat:n};if((h.internalFormat===e.RGBA16F||h.internalFormat===e.RGBA32F)&&!e.getExtension("EXT_color_buffer_float"))throw m(6);return h}getPxArray(r,e){let i=this.typeArrays.get(r)??Uint8Array;return new i(e)}isRgba(r){let e=this.gl;return r===e.RGBA||r===e.RGBA_INTEGER}clearHistTexLayers(r){if(!r.history)return;let e=this.gl,{type:i,format:t}=r.options,s=this.getPxArray(i,r.width*r.height*4);e.activeTexture(e.TEXTURE0+r.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,r.texture);let a=!this.isRgba(t),n;a&&(n=e.getParameter(e.UNPACK_ALIGNMENT),e.pixelStorei(e.UNPACK_ALIGNMENT,1));for(let o=0;o<r.history.depth;++o)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,o,r.width,r.height,1,t,i,s);a&&e.pixelStorei(e.UNPACK_ALIGNMENT,n)}updateFrameOffset(r,e,i){this.updateUniforms({[`${P(r)}FrameOffset`]:e},i)}resetHist(r,e){e.history&&(e.history.writeIndex=0,this.clearHistTexLayers(e),this.updateFrameOffset(r,0,{allowMissing:!0}))}initializeUniform(r,e,i,t){let s=t?.arrayLength,a=t?.allowMissing??!1;if(this.uniforms.has(r))throw m(7);if(!N[e])throw m(8);if(s&&!(Array.isArray(i)&&i.length===s))throw m(9);let n=this.gl,o=n.getUniformLocation(this.program,r);if(!o&&s&&(o=n.getUniformLocation(this.program,`${r}[0]`)),!o){if(a)return;throw m(19)}let h=s?i[0]:i,u=Array.isArray(h)?h.length:1;this.uniforms.set(r,{type:e,length:u,location:o,arrayLength:s});try{this.updateUniforms({[r]:i})}catch(c){throw this.uniforms.delete(r),c}this.emit("initializeUniform",...arguments)}updateUniforms(r,e){let i=this.gl;i.useProgram(this.program),Object.entries(r).forEach(([t,s])=>{let a=this.uniforms.get(t);if(!a){if(e?.allowMissing)return;throw m(20)}let n=`uniform${a.length}${N[a.type]}`;if(a.arrayLength){if(!Array.isArray(s))throw m(10);let o=s.length;if(!o)return;if(o>a.arrayLength)throw m(11);if(s.some(p=>(Array.isArray(p)?p.length:1)!==a.length))throw m(12);let h=s.flat(),u=a.type==="float"?new Float32Array(h):a.type==="uint"?new Uint32Array(h):new Int32Array(h),c=a.location;if(e?.startIndex){let p=i.getUniformLocation(this.program,`${t}[${e.startIndex}]`);if(!p)throw m(13);c=p}i[n+"v"](c,u)}else{Array.isArray(s)||(s=[s]);let o=s;if(o.length!==a.length)throw m(14);i[n](a.location,...o)}}),this.emit("updateUniforms",...arguments)}createTex(r,e){let i=this.gl,{width:t,height:s}=e,a=e.history?.depth??0,n=i.createTexture();if(!n)throw m(15);let o=e.unitIndex;if(typeof o!="number")try{o=this.reserveTex(r)}catch(p){throw i.deleteTexture(n),p}let h=a>0,u=h?i.TEXTURE_2D_ARRAY:i.TEXTURE_2D,{options:c}=e;return i.activeTexture(i.TEXTURE0+o),i.bindTexture(u,n),i.texParameteri(u,i.TEXTURE_WRAP_S,c.wrapS),i.texParameteri(u,i.TEXTURE_WRAP_T,c.wrapT),i.texParameteri(u,i.TEXTURE_MIN_FILTER,c.minFilter),i.texParameteri(u,i.TEXTURE_MAG_FILTER,c.magFilter),h?i.texStorage3D(u,1,c.internalFormat,t,s,a):r===g&&i.texImage2D(i.TEXTURE_2D,0,c.internalFormat,t,s,0,c.format,c.type,null),{texture:n,unitIndex:o}}initTex(r,e,i){let t=this.gl;if(this.textures.has(r))throw m(16);let{history:s=0,...a}=i??{},{width:n,height:o}=O(e);if(!n||!o)throw m(17);let h={width:n,height:o,options:e instanceof l&&Object.keys(a).length===0&&e.textures.has(g)?e.textures.get(g).options:this.resolveTexOpts(a)};s>0&&(h.history={depth:s,writeIndex:0});let{texture:u,unitIndex:c}=this.createTex(r,h),p={texture:u,unitIndex:c,...h};s>0&&(this.initializeUniform(`${P(r)}FrameOffset`,"int",0,{allowMissing:!0}),this.clearHistTexLayers(p)),this.textures.set(r,p),r!==g&&r!==v&&this.updateTex(r,e),t.useProgram(this.program);let f=t.getUniformLocation(this.program,P(r));f&&t.uniform1i(f,c)}initializeTexture(r,e,i){let t=i?.history!=null&&i.history>0?{...i,history:i.history+1}:i;this.initTex(r,e,t),this.emit("initializeTexture",...arguments)}updateTextures(r){Object.entries(r).forEach(([e,i])=>{this.updateTex(e,i)}),this.emit("updateTextures",...arguments)}updateTex(r,e,i){let t=this.gl,s=this.textures.get(r);if(!s)throw m(18);if(e instanceof WebGLTexture){t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D,e);return}let a=e;if(e instanceof l){let d=e.textures.get(g),T=d.width,_=d.height;if(e.gl===t){if(!s.history){t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D,d.texture);return}let{depth:w}=s.history,D=i===void 0?[s.history.writeIndex]:Array.isArray(i)?i.map(U=>S(U,w)):[S(i,w)];t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D_ARRAY,s.texture),t.bindFramebuffer(t.READ_FRAMEBUFFER,e.intermediateFbo);for(let U of D)t.copyTexSubImage3D(t.TEXTURE_2D_ARRAY,0,0,0,U,0,0,T,_);t.bindFramebuffer(t.READ_FRAMEBUFFER,null),this.updateFrameOffset(r,D[D.length-1],{allowMissing:!0}),i===void 0&&(s.history.writeIndex=(s.history.writeIndex+1)%w);return}let{width:y,height:R,options:{format:L,type:A}}=d,G=this.getPxArray(A,y*R*4);e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,e.intermediateFbo),e.gl.readPixels(0,0,y,R,L,A,G),e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,null),a={data:G,width:y,height:R}}let{width:n,height:o}=O(a);if(!n||!o)return;let h="isPartial"in a&&a.isPartial;h||this.resizeTex(r,n,o);let u="data"in a&&a.data,c=!u&&!s.options?.preserveY,p=t.getParameter(t.UNPACK_FLIP_Y_WEBGL),f=u&&!this.isRgba(s.options.format),E=!u&&s.options.colorSpace&&"unpackColorSpace"in t,b=t.unpackColorSpace,x;if(f&&(x=t.getParameter(t.UNPACK_ALIGNMENT),t.pixelStorei(t.UNPACK_ALIGNMENT,1)),E&&(t.unpackColorSpace=s.options.colorSpace),s.history){t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D_ARRAY,s.texture);let{depth:d}=s.history,T=i===void 0?[s.history.writeIndex]:Array.isArray(i)?i.map(A=>S(A,d)):[S(i,d)];t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,c);let _=a,y=_.data??a,R=h?_.x??0:0,L=h?_.y??0:0;for(let A of T)t.texSubImage3D(t.TEXTURE_2D_ARRAY,0,R,L,A,n,o,1,s.options.format,s.options.type,y);t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,p),this.updateFrameOffset(r,T[T.length-1]),i===void 0&&(s.history.writeIndex=(s.history.writeIndex+1)%d)}else{if(t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D,s.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,c),h){let d=a;t.texSubImage2D(t.TEXTURE_2D,0,d.x??0,d.y??0,n,o,s.options.format,s.options.type,d.data)}else t.texImage2D(t.TEXTURE_2D,0,s.options.internalFormat,n,o,0,s.options.format,s.options.type,a.data??a);t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,p)}E&&(t.unpackColorSpace=b),f&&t.pixelStorei(t.UNPACK_ALIGNMENT,x)}bindIntermediate(){let r=this.gl,e=this.textures.get(g);r.bindFramebuffer(r.FRAMEBUFFER,this.intermediateFbo),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,e.texture,0)}clear(){this.bindIntermediate();let r=this.gl,e=this.textures.get(g);if(e.options.isIntegerColorFormat){let i=e.options.type;this.uintTypes.has(i)?r.clearBufferuiv(r.COLOR,0,new Uint32Array(4)):r.clearBufferiv(r.COLOR,0,new Int32Array(4))}else r.clear(r.COLOR_BUFFER_BIT)}draw(r){this.emit("preDraw",...arguments);let e=this.gl,i=e.drawingBufferWidth,t=e.drawingBufferHeight;r?.skipClear?this.bindIntermediate():this.clear(),e.useProgram(this.program),e.bindVertexArray(this.vao),e.viewport(0,0,i,t),e.drawArrays(e.TRIANGLES,0,3),this.isHeadless||this.textures.get(g).options.isIntegerColorFormat||(e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,i,t,0,0,i,t,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null)),this.emit("postDraw",...arguments)}step(r){this._step(performance.now(),r)}tick(){let r={};this.uniforms.has("u_time")&&(r.u_time=this.tElapsed),this.uniforms.has("u_frame")&&(r.u_frame=this.frame),Object.keys(r).length&&this.updateUniforms(r)}_step(r,e){let i=this.getElapsed(r);this.tElapsed=i,this.tStart=r;let t=typeof e=="function"?e(i,this.frame):e;this.emit("preStep",i,this.frame,t),this.tick(),this.draw(t);let s=this.textures.get(v);if(s&&!t?.skipHistory){let{writeIndex:a,depth:n}=s.history,o=this.gl;o.bindFramebuffer(o.READ_FRAMEBUFFER,this.intermediateFbo),o.bindTexture(o.TEXTURE_2D_ARRAY,s.texture),o.copyTexSubImage3D(o.TEXTURE_2D_ARRAY,0,0,0,a,0,0,o.drawingBufferWidth,o.drawingBufferHeight),o.bindFramebuffer(o.READ_FRAMEBUFFER,null);let h=(a+1)%n;this.updateFrameOffset(v,h,{allowMissing:!0}),s.history.writeIndex=h}++this.frame,this.emit("postStep",i,this.frame,t)}play(r){this._pause();let e=i=>{this._step(i,r),this.frameId!=null&&(this.frameId=requestAnimationFrame(e))};this.frameId=requestAnimationFrame(e),this.emit("play")}getElapsed(r){return isNaN(this.tStart)?this.tElapsed:this.tElapsed+(r-this.tStart)/1e3}_pause(){if(!(isNaN(this.tStart)&&this.frameId==null))return this.frameId!=null&&(cancelAnimationFrame(this.frameId),this.frameId=null),this.tElapsed=this.getElapsed(performance.now()),this.tStart=NaN,!0}pause(){this._pause()&&this.emit("pause")}rewind(){this.frame=0,this.tElapsed=0,this.tStart=NaN,this.tick()}reset(){this.rewind(),this.textures.forEach((r,e)=>{this.resetHist(e,r)}),this.clear(),this.emit("reset")}destroy(){this.emit("destroy"),this._pause();let r=this.gl;this.cursorTgt&&(this.listeners.forEach((i,t)=>{this.cursorTgt.removeEventListener(t,i)}),this.listeners.clear()),this.resObserver&&(this.resObserver.disconnect(),this.resObserver=null),this.program&&(r.deleteProgram(this.program),this.program=null),this.intermediateFbo&&(r.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(i=>{this.texPool.free.push(i.unitIndex),r.deleteTexture(i.texture)}),this.textures.clear();let e=F.get(this.canvas);e&&(e.instances.delete(this),e.instances.size===0&&F.delete(this.canvas)),this.vao&&(r.deleteVertexArray(this.vao),this.vao=null),this.buffer&&(r.deleteBuffer(this.buffer),this.buffer=null),this.uniforms.clear(),this.hooks.clear()}},Y=I;export{Y as a};
|
|
5
|
+
//# sourceMappingURL=chunk-4UKNQUGK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { safeMod, spError } from './internal/util';\n\nconst DEFAULT_VERTEX_SHADER_SRC = `#version 300 es\nin vec2 a_position;out vec2 v_uv;void main(){gl_Position=vec4(a_position,0.,1.);v_uv=a_position*.5+.5;}`;\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';\nexport type ColorSpace = PredefinedColorSpace;\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\tcolorSpace?: ColorSpace;\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\tcolorSpace?: ColorSpace;\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 interface InitializeTextureOptions extends TextureOptions {\n\thistory?: 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).\nexport type UpdateTextureSource = Exclude<TextureSource, CustomTexture> | PartialCustomTexture;\n\nexport interface PluginContext {\n\tinjectGLSL: (code: string) => void;\n\temit: (name: ShaderPadEventName, ...args: any[]) => void;\n\tupdateTexture: (name: string, source: UpdateTextureSource, historySlots?: HistorySlots) => void;\n}\n\nexport type Plugin = (shaderPad: ShaderPad, context: PluginContext) => void;\n\nexport type ShaderPadEventName =\n\t| '_init'\n\t| 'initializeTexture'\n\t| 'initializeUniform'\n\t| 'updateTextures'\n\t| 'updateUniforms'\n\t| 'preStep'\n\t| 'postStep'\n\t| 'preDraw'\n\t| 'postDraw'\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\tskipHistory?: boolean;\n}\n\ntype HistorySlots = number | number[];\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{ texPool: 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 isTouch = false;\n\tdeclare public readonly gl: WebGL2RenderingContext;\n\tdeclare private typeArrays: Map<number, new (length: number) => ArrayBufferView>;\n\tdeclare private typeFormats: Map<number, GLInternalFormatString>;\n\tdeclare private uintTypes: Set<number>;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string | symbol, Texture> = new Map();\n\tdeclare private texPool: TextureUnitPool;\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate vao: WebGLVertexArrayObject | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tdeclare private frameId: number | null;\n\tprivate listeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate tElapsed = 0;\n\tprivate tStart = NaN;\n\tprivate cursorPos = [0.5, 0.5];\n\tprivate clickPos = [0.5, 0.5];\n\tprivate isClicked = false;\n\tdeclare public canvas: HTMLCanvasElement | OffscreenCanvas;\n\tprivate resObserver: MutationObserver | null = null;\n\tprivate hooks: Map<ShaderPadEventName, Function[]> = new Map();\n\tprivate historyDepth = 0;\n\tdeclare private texOptions: TextureOptions;\n\tdeclare private cursorTgt: 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(fragmentShaderSrc: string, { canvas, plugins, history, cursorTarget, ...texOptions }: Options = {}) {\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 __SHADERPAD_DEV__\n\t\t\t\t? spError(0, {\n\t\t\t\t\t\tcanvasType: this.canvas.constructor.name,\n\t\t\t\t\t\tisHeadless: this.isHeadless,\n\t\t\t\t\t\tcanvasWidth: this.canvas.width,\n\t\t\t\t\t\tcanvasHeight: this.canvas.height,\n\t\t\t\t\t})\n\t\t\t\t: spError(0);\n\t\t}\n\t\tif (texOptions.colorSpace && 'drawingBufferColorSpace' in gl) {\n\t\t\tgl.drawingBufferColorSpace = texOptions.colorSpace;\n\t\t}\n\t\tthis.gl = gl;\n\t\tthis.typeArrays = new Map<number, new (length: number) => ArrayBufferView>([\n\t\t\t[gl.FLOAT, Float32Array],\n\t\t\t[gl.HALF_FLOAT, Uint16Array],\n\t\t\t[gl.UNSIGNED_SHORT, Uint16Array],\n\t\t\t[gl.SHORT, Int16Array],\n\t\t\t[gl.BYTE, Int8Array],\n\t\t\t[gl.UNSIGNED_INT, Uint32Array],\n\t\t\t[gl.INT, Int32Array],\n\t\t]);\n\t\tthis.typeFormats = new Map<number, GLInternalFormatString>([\n\t\t\t[gl.FLOAT, 'RGBA32F'],\n\t\t\t[gl.HALF_FLOAT, 'RGBA16F'],\n\t\t\t[gl.UNSIGNED_SHORT, 'RGBA32UI'],\n\t\t\t[gl.SHORT, 'RGBA32I'],\n\t\t\t[gl.BYTE, 'RGBA32I'],\n\t\t\t[gl.UNSIGNED_INT, 'RGBA32UI'],\n\t\t\t[gl.INT, 'RGBA32I'],\n\t\t]);\n\t\tthis.uintTypes = new Set([gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT]);\n\n\t\tlet registryEntry = canvasRegistry.get(this.canvas);\n\t\tif (!registryEntry) {\n\t\t\tregistryEntry = {\n\t\t\t\ttexPool: {\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.texPool = registryEntry.texPool;\n\t\tregistryEntry.instances.add(this);\n\n\t\tthis.texOptions = texOptions;\n\n\t\tif (history) this.historyDepth = history;\n\t\tthis.cursorTgt = cursorTarget ?? (this.canvas instanceof HTMLCanvasElement ? this.canvas : undefined);\n\t\tthis.frameId = 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\tinjectGLSL: (code: string) => {\n\t\t\t\t\t\tglslInjections.push(code);\n\t\t\t\t\t},\n\t\t\t\t\temit: this.emit.bind(this),\n\t\t\t\t\tupdateTexture: this.updateTex.bind(this),\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst program = 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(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 linkError = __SHADERPAD_DEV__\n\t\t\t\t? spError(2, {\n\t\t\t\t\t\tprogramInfoLog: gl.getProgramInfoLog(program),\n\t\t\t\t\t\tfragmentShaderLength: fragmentShaderSrc.length,\n\t\t\t\t\t\tglslInjectionCount: glslInjections.length,\n\t\t\t\t\t})\n\t\t\t\t: spError(2);\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.resObserver = new MutationObserver(() => this.syncRes());\n\t\t\tthis.resObserver.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.syncRes();\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.syncRes();\n\n\t\tthis.initializeUniform('u_cursor', 'float', this.cursorPos, { allowMissing: true });\n\t\tthis.initializeUniform('u_click', 'float', [...this.clickPos, this.isClicked ? 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.initTex(INTERMEDIATE_TEXTURE_KEY, this.canvas, {\n\t\t\t...this.texOptions,\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.initTex(HISTORY_TEXTURE_KEY, this.canvas, {\n\t\t\t\thistory: this.historyDepth,\n\t\t\t\t...this.texOptions,\n\t\t\t});\n\t\t}\n\t\tthis.addListeners();\n\t\tthis.emit('_init');\n\t}\n\n\tprivate resolveGLConst(value: GLConstantString): number {\n\t\tconst gl = this.gl;\n\t\tconst resolved = gl[value];\n\t\tif (resolved === undefined) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(3, { value }) : spError(3);\n\t\t}\n\t\treturn resolved;\n\t}\n\n\tprivate emit(name: ShaderPadEventName, ...args: any[]) {\n\t\tthis.hooks.get(name)?.forEach(hook => hook.call(this, ...args));\n\t}\n\n\ton(name: ShaderPadEventName, 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: ShaderPadEventName, 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 gl = this.gl;\n\t\tconst shader = gl.createShader(type)!;\n\t\tgl.shaderSource(shader, source);\n\t\tgl.compileShader(shader);\n\t\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\t\tconsole.error(gl.getShaderInfoLog(shader));\n\t\t\tconst compilationError = __SHADERPAD_DEV__\n\t\t\t\t? spError(4, {\n\t\t\t\t\t\tshaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment',\n\t\t\t\t\t\tsource,\n\t\t\t\t\t})\n\t\t\t\t: spError(4);\n\t\t\tgl.deleteShader(shader);\n\t\t\tthrow compilationError;\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate getCursorTgtRect(): {\n\t\tleft: number;\n\t\ttop: number;\n\t\twidth: number;\n\t\theight: number;\n\t} {\n\t\tconst target = this.cursorTgt!;\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 addListeners() {\n\t\tif (!this.cursorTgt) 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.getCursorTgtRect();\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.cursorPos[0] = Math.max(0, Math.min(1, u));\n\t\t\tthis.cursorPos[1] = Math.max(0, Math.min(1, v));\n\t\t\tthis.updateUniforms({ u_cursor: this.cursorPos });\n\t\t};\n\n\t\tconst updateClick = (isClicked: boolean, x?: number, y?: number) => {\n\t\t\tif (!this.uniforms.has('u_click')) return;\n\t\t\tthis.isClicked = isClicked;\n\t\t\tif (isClicked) {\n\t\t\t\tconst rect = this.getCursorTgtRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPos[0] = Math.max(0, Math.min(1, (xVal - rect.left) / rect.width));\n\t\t\t\tthis.clickPos[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.clickPos, this.isClicked ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.listeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouch) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouch) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isClicked = 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.listeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouch) {\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.listeners.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.listeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouch = 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.listeners.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.listeners.forEach((listener, event) => {\n\t\t\tthis.cursorTgt!.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tprivate syncRes() {\n\t\tconst gl = this.gl;\n\t\tconst resolution: [number, number] = [gl.drawingBufferWidth, gl.drawingBufferHeight];\n\t\tgl.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.resizeTex(INTERMEDIATE_TEXTURE_KEY, ...resolution);\n\t\tif (this.historyDepth > 0) {\n\t\t\tthis.resizeTex(HISTORY_TEXTURE_KEY, ...resolution);\n\t\t}\n\t\tthis.emit('updateResolution', ...resolution);\n\t}\n\n\tprivate resizeTex(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\tconst gl = this.gl;\n\t\tgl.deleteTexture(info.texture);\n\t\tinfo.width = width;\n\t\tinfo.height = height;\n\t\tconst { texture } = this.createTex(name, info);\n\t\tinfo.texture = texture;\n\t\tthis.resetHist(name, info);\n\t}\n\n\tprivate reserveTex(name: string | symbol) {\n\t\tconst existing = this.textures.get(name);\n\t\tif (existing) return existing.unitIndex;\n\t\tif (this.texPool.free.length > 0) return this.texPool.free.pop()!;\n\t\tif (this.texPool.next >= this.texPool.max) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(5, {\n\t\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\t\tnextTextureUnit: this.texPool.next,\n\t\t\t\t\t\tmaxTextureUnits: this.texPool.max,\n\t\t\t\t\t\tfreeTextureUnits: this.texPool.free.length,\n\t\t\t\t\t})\n\t\t\t\t: spError(5);\n\t\t}\n\t\treturn this.texPool.next++;\n\t}\n\n\tprivate resolveTexOpts(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.resolveGLConst(typeString);\n\t\tconst internalFormatString = internalFormatOption ?? this.typeFormats.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.resolveGLConst(formatString),\n\t\t\tinternalFormat: this.resolveGLConst(internalFormatString),\n\t\t\tminFilter: this.resolveGLConst(options?.minFilter ?? 'LINEAR'),\n\t\t\tmagFilter: this.resolveGLConst(options?.magFilter ?? 'LINEAR'),\n\t\t\twrapS: this.resolveGLConst(options?.wrapS ?? 'CLAMP_TO_EDGE'),\n\t\t\twrapT: this.resolveGLConst(options?.wrapT ?? 'CLAMP_TO_EDGE'),\n\t\t\tcolorSpace: options?.colorSpace,\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 __SHADERPAD_DEV__\n\t\t\t\t? spError(6, {\n\t\t\t\t\t\tinternalFormat: internalFormatString,\n\t\t\t\t\t\ttype: typeString,\n\t\t\t\t\t})\n\t\t\t\t: spError(6);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate getPxArray(type: number, size: number): ArrayBufferView {\n\t\tconst ArrayType = this.typeArrays.get(type) ?? Uint8Array;\n\t\treturn new ArrayType(size);\n\t}\n\n\tprivate isRgba(format: number): boolean {\n\t\tconst gl = this.gl;\n\t\treturn format === gl.RGBA || format === gl.RGBA_INTEGER;\n\t}\n\n\tprivate clearHistTexLayers(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.getPxArray(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.isRgba(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\tprivate updateFrameOffset(\n\t\tname: string | symbol,\n\t\tframeOffset: number,\n\t\toptions?: {\n\t\t\tallowMissing?: boolean;\n\t\t},\n\t) {\n\t\tthis.updateUniforms(\n\t\t\t{\n\t\t\t\t[`${stringFrom(name)}FrameOffset`]: frameOffset,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\tprivate resetHist(name: string | symbol, textureInfo: Texture) {\n\t\tif (!textureInfo.history) return;\n\t\ttextureInfo.history.writeIndex = 0;\n\t\tthis.clearHistTexLayers(textureInfo);\n\t\tthis.updateFrameOffset(name, 0, { allowMissing: true });\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 __SHADERPAD_DEV__ ? spError(7, { name, arrayLength: arrayLength ?? null }) : spError(7);\n\t\t}\n\t\tif (!UNIFORM_TYPE_SUFFIXES[type]) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(8, {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tsupportedTypes: Object.keys(UNIFORM_TYPE_SUFFIXES),\n\t\t\t\t\t})\n\t\t\t\t: spError(8);\n\t\t}\n\t\tif (arrayLength && !(Array.isArray(value) && value.length === arrayLength)) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(9, {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\texpectedLength: arrayLength,\n\t\t\t\t\t\treceivedLength: Array.isArray(value) ? value.length : 1,\n\t\t\t\t\t})\n\t\t\t\t: spError(9);\n\t\t}\n\n\t\tconst gl = this.gl;\n\t\tlet location = gl.getUniformLocation(this.program!, name);\n\t\tif (!location && arrayLength) {\n\t\t\tlocation = gl.getUniformLocation(this.program!, `${name}[0]`);\n\t\t}\n\t\tif (!location) {\n\t\t\tif (allowMissing) return;\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(19, { name, arrayLength: arrayLength ?? null }) : spError(19);\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.emit('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\tconst gl = this.gl;\n\t\tgl.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 __SHADERPAD_DEV__\n\t\t\t\t\t? spError(20, {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tstartIndex: options?.startIndex ?? null,\n\t\t\t\t\t\t})\n\t\t\t\t\t: spError(20);\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 __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(10, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\treceivedType: typeof newValue,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(10);\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 __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(11, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\treceivedLength: nValues,\n\t\t\t\t\t\t\t\tmaxLength: uniform.arrayLength,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(11);\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 __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(12, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\texpectedElementLength: uniform.length,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(12);\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 = gl.getUniformLocation(this.program!, `${name}[${options.startIndex}]`);\n\t\t\t\t\tif (!newLocation) {\n\t\t\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t\t\t? spError(13, {\n\t\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\t\tstartIndex: options.startIndex,\n\t\t\t\t\t\t\t\t\tarrayLength: uniform.arrayLength,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t: spError(13);\n\t\t\t\t\t}\n\t\t\t\t\tlocation = newLocation;\n\t\t\t\t}\n\t\t\t\t(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 __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(14, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\treceivedLength: scalarValue.length,\n\t\t\t\t\t\t\t\texpectedLength: uniform.length,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(14);\n\t\t\t\t}\n\t\t\t\t(gl as any)[glFunctionName](uniform.location, ...scalarValue);\n\t\t\t}\n\t\t});\n\t\tthis.emit('updateUniforms', ...arguments);\n\t}\n\n\tprivate createTex(\n\t\tname: string | symbol,\n\t\ttextureInfo: Pick<Texture, 'width' | 'height' | 'history' | 'options'> & { unitIndex?: number },\n\t) {\n\t\tconst gl = this.gl;\n\t\tconst { width, height } = textureInfo;\n\t\tconst historyDepth = textureInfo.history?.depth ?? 0;\n\n\t\tconst texture = gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(15, {\n\t\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\thistoryDepth,\n\t\t\t\t\t})\n\t\t\t\t: spError(15);\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.reserveTex(name);\n\t\t\t} catch (error) {\n\t\t\t\tgl.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 ? gl.TEXTURE_2D_ARRAY : gl.TEXTURE_2D;\n\t\tconst { options } = textureInfo;\n\t\tgl.activeTexture(gl.TEXTURE0 + unitIndex);\n\t\tgl.bindTexture(textureTarget, texture);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, options.wrapS);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, options.wrapT);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, options.minFilter);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, options.magFilter);\n\t\tif (hasHistory) {\n\t\t\tgl.texStorage3D(textureTarget, 1, options.internalFormat, width, height, historyDepth);\n\t\t} else if (name === INTERMEDIATE_TEXTURE_KEY) {\n\t\t\tgl.texImage2D(\n\t\t\t\tgl.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 initTex(name: string | symbol, source: TextureSource, options?: InitializeTextureOptions) {\n\t\tconst gl = this.gl;\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(16, { name: stringFrom(name) }) : spError(16);\n\t\t}\n\n\t\tconst { history: historyDepth = 0, ...texOptions } = options ?? {};\n\t\tconst { width, height } = getSourceDimensions(source);\n\t\tif (!width || !height) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(17, {\n\t\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\tsourceType: source.constructor.name,\n\t\t\t\t\t})\n\t\t\t\t: spError(17);\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(texOptions).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.resolveTexOpts(texOptions),\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.createTex(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.clearHistTexLayers(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.updateTex(name, source);\n\t\t}\n\n\t\t// Set a uniform to access the texture in the fragment shader.\n\t\tgl.useProgram(this.program!);\n\t\tconst uSampler = gl.getUniformLocation(this.program!, stringFrom(name));\n\t\tif (uSampler) {\n\t\t\tgl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tinitializeTexture(name: string, source: TextureSource, options?: InitializeTextureOptions) {\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.initTex(name, source, opts);\n\t\tthis.emit('initializeTexture', ...arguments);\n\t}\n\n\tupdateTextures(updates: Record<string, UpdateTextureSource>) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tthis.updateTex(name, source);\n\t\t});\n\t\tthis.emit('updateTextures', ...arguments);\n\t}\n\n\tprivate updateTex(name: string | symbol, source: UpdateTextureSource, historySlots?: HistorySlots) {\n\t\tconst gl = this.gl;\n\t\tconst info = this.textures.get(name);\n\t\tif (!info) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(18, { name: stringFrom(name) }) : spError(18);\n\t\t}\n\n\t\tif (source instanceof WebGLTexture) {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\tgl.bindTexture(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 === gl) {\n\t\t\t\tif (!info.history) {\n\t\t\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\t\t\tgl.bindTexture(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\thistorySlots === undefined\n\t\t\t\t\t\t? [info.history.writeIndex]\n\t\t\t\t\t\t: Array.isArray(historySlots)\n\t\t\t\t\t\t\t? historySlots.map(i => safeMod(i, depth))\n\t\t\t\t\t\t\t: [safeMod(historySlots, depth)];\n\t\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, source.intermediateFbo);\n\t\t\t\tfor (const slot of targetSlots) {\n\t\t\t\t\tgl.copyTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, slot, 0, 0, srcW, srcH);\n\t\t\t\t}\n\t\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);\n\t\t\t\tthis.updateFrameOffset(name, targetSlots[targetSlots.length - 1], { allowMissing: true });\n\t\t\t\tif (historySlots === 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.getPxArray(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.resizeTex(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 isCustomTexture = 'data' in nonShaderPadSource && nonShaderPadSource.data;\n\t\tconst shouldFlipY = !isCustomTexture && !info.options?.preserveY;\n\t\tconst previousFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);\n\t\tconst needsAlignmentFix = isCustomTexture && !this.isRgba(info.options.format);\n\t\tconst shouldConvertColorSpace = !isCustomTexture && info.options.colorSpace && 'unpackColorSpace' in gl;\n\t\tconst previousColorSpace = gl.unpackColorSpace;\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\tif (shouldConvertColorSpace) gl.unpackColorSpace = info.options.colorSpace!;\n\n\t\tif (info.history) {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\tconst { depth } = info.history;\n\t\t\tconst targetSlots =\n\t\t\t\thistorySlots === undefined\n\t\t\t\t\t? [info.history.writeIndex]\n\t\t\t\t\t: Array.isArray(historySlots)\n\t\t\t\t\t\t? historySlots.map(i => safeMod(i, depth))\n\t\t\t\t\t\t: [safeMod(historySlots, depth)];\n\n\t\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\t\t\tconst partialSource = nonShaderPadSource as PartialCustomTexture;\n\t\t\tconst sourceData =\n\t\t\t\tpartialSource.data ?? (nonShaderPadSource as Exclude<TextureSource, CustomTexture | ShaderPad>);\n\t\t\tconst xOffset = isPartial ? (partialSource.x ?? 0) : 0;\n\t\t\tconst yOffset = isPartial ? (partialSource.y ?? 0) : 0;\n\n\t\t\tfor (const slot of targetSlots) {\n\t\t\t\tgl.texSubImage3D(\n\t\t\t\t\tgl.TEXTURE_2D_ARRAY,\n\t\t\t\t\t0,\n\t\t\t\t\txOffset,\n\t\t\t\t\tyOffset,\n\t\t\t\t\tslot,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\t1,\n\t\t\t\t\tinfo.options.format,\n\t\t\t\t\tinfo.options.type,\n\t\t\t\t\tsourceData as any,\n\t\t\t\t);\n\t\t\t}\n\t\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t\tthis.updateFrameOffset(name, targetSlots[targetSlots.length - 1]);\n\t\t\tif (historySlots === undefined) {\n\t\t\t\tinfo.history.writeIndex = (info.history.writeIndex + 1) % depth;\n\t\t\t}\n\t\t} else {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D, info.texture);\n\t\t\tgl.pixelStorei(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\tgl.texSubImage2D(\n\t\t\t\t\tgl.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\tgl.texImage2D(\n\t\t\t\t\tgl.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\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t}\n\n\t\tif (shouldConvertColorSpace) gl.unpackColorSpace = previousColorSpace;\n\t\tif (needsAlignmentFix) gl.pixelStorei(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.uintTypes.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 | void) {\n\t\tthis.emit('preDraw', ...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.emit('postDraw', ...arguments);\n\t}\n\n\tstep(options?: StepOptions) {\n\t\tthis._step(performance.now(), options);\n\t}\n\n\tprivate tick() {\n\t\tconst updates: Record<string, number> = {};\n\t\tif (this.uniforms.has('u_time')) updates.u_time = this.tElapsed;\n\t\tif (this.uniforms.has('u_frame')) updates.u_frame = this.frame;\n\t\tif (Object.keys(updates).length) this.updateUniforms(updates);\n\t}\n\n\tprivate _step(now: number, opts?: StepOptions | ((time: number, frame: number) => StepOptions | void)) {\n\t\tconst t = this.getElapsed(now);\n\t\tthis.tElapsed = t;\n\t\tthis.tStart = now;\n\t\tconst options = typeof opts === 'function' ? opts(t, this.frame) : opts;\n\t\tthis.emit('preStep', t, this.frame, options);\n\t\tthis.tick();\n\t\tthis.draw(options);\n\t\tconst historyInfo = this.textures.get(HISTORY_TEXTURE_KEY);\n\t\tif (historyInfo && !options?.skipHistory) {\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.updateFrameOffset(HISTORY_TEXTURE_KEY, nextWriteIndex, { allowMissing: true });\n\t\t\thistoryInfo.history!.writeIndex = nextWriteIndex;\n\t\t}\n\t\t++this.frame;\n\t\tthis.emit('postStep', t, this.frame, options);\n\t}\n\n\tplay(onPreStep?: (time: number, frame: number) => StepOptions | void) {\n\t\tthis._pause();\n\t\tconst loop = (now: number) => {\n\t\t\tthis._step(now, onPreStep);\n\t\t\tif (this.frameId != null) this.frameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.frameId = requestAnimationFrame(loop);\n\t\tthis.emit('play');\n\t}\n\n\tprivate getElapsed(time: number) {\n\t\tif (isNaN(this.tStart)) return this.tElapsed;\n\t\treturn this.tElapsed + (time - this.tStart) / 1000;\n\t}\n\n\tprivate _pause() {\n\t\tif (isNaN(this.tStart) && this.frameId == null) return;\n\t\tif (this.frameId != null) {\n\t\t\tcancelAnimationFrame(this.frameId);\n\t\t\tthis.frameId = null;\n\t\t}\n\t\tthis.tElapsed = this.getElapsed(performance.now());\n\t\tthis.tStart = NaN;\n\t\treturn true;\n\t}\n\n\tpause() {\n\t\tif (this._pause()) this.emit('pause');\n\t}\n\n\trewind() {\n\t\tthis.frame = 0;\n\t\tthis.tElapsed = 0;\n\t\tthis.tStart = NaN;\n\t\tthis.tick();\n\t}\n\n\treset() {\n\t\tthis.rewind();\n\t\tthis.textures.forEach((texture, name) => {\n\t\t\tthis.resetHist(name, texture);\n\t\t});\n\t\tthis.clear();\n\t\tthis.emit('reset');\n\t}\n\n\tdestroy() {\n\t\tthis.emit('destroy');\n\n\t\tthis._pause();\n\t\tconst gl = this.gl;\n\n\t\tif (this.cursorTgt) {\n\t\t\tthis.listeners.forEach((listener, event) => {\n\t\t\t\tthis.cursorTgt!.removeEventListener(event, listener);\n\t\t\t});\n\t\t\tthis.listeners.clear();\n\t\t}\n\n\t\tif (this.resObserver) {\n\t\t\tthis.resObserver.disconnect();\n\t\t\tthis.resObserver = null;\n\t\t}\n\n\t\tif (this.program) {\n\t\t\tgl.deleteProgram(this.program);\n\t\t\tthis.program = null;\n\t\t}\n\n\t\tif (this.intermediateFbo) {\n\t\t\tgl.deleteFramebuffer(this.intermediateFbo);\n\t\t\tthis.intermediateFbo = null;\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.texPool.free.push(texture.unitIndex);\n\t\t\tgl.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\tgl.deleteVertexArray(this.vao);\n\t\t\tthis.vao = null;\n\t\t}\n\n\t\tif (this.buffer) {\n\t\t\tgl.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","texOptions","width","height","gl","spError","registryEntry","glslInjections","plugin","code","program","vertexShader","fragmentShader","linkError","wrapDimension","dimension","descriptor","v","entry","instance","value","resolved","args","hook","fn","hooks","index","type","compilationError","target","updateCursor","x","y","rect","u","updateClick","isClicked","xVal","yVal","event","mouseEvent","touchEvent","listener","resolution","info","texture","existing","options","internalFormatOption","typeString","isIntegerColorFormat","formatString","result","size","ArrayType","format","textureInfo","transparent","needsAlignmentFix","previousAlignment","layer","frameOffset","arrayLength","allowMissing","location","probeValue","length","error","updates","newValue","uniform","glFunctionName","nValues","item","flat","typedArray","newLocation","scalarValue","historyDepth","unitIndex","hasHistory","textureTarget","completeTextureInfo","uSampler","opts","historySlots","nonShaderPadSource","sourceIntermediateInfo","srcW","srcH","depth","targetSlots","i","safeMod","slot","pixels","isPartial","isCustomTexture","shouldFlipY","previousFlipY","shouldConvertColorSpace","previousColorSpace","partialSource","sourceData","xOffset","yOffset","intermediateInfo","t","w","h","now","historyInfo","writeIndex","nextWriteIndex","onPreStep","loop","time","index_default"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function T(e){let t=e.ownerDocument.defaultView??window,n=e.getBoundingClientRect();return n.width>0&&n.height>0&&n.bottom>0&&n.right>0&&n.top<t.innerHeight&&n.left<t.innerWidth}function M({target:e,autoplay:t,autopause:n,isPlaying:a,play:s,pause:i,onVisibilityChange:u}){let o=e.ownerDocument,l=t,f=n,p=o.visibilityState==="visible",m=T(e),c=!1,v=null,h=()=>p&&(typeof IntersectionObserver=="function"?m:T(e))&&e.isConnected,d=()=>{let r=h();if(v!==r&&(v=r,u?.(r)),!l){c&&a()&&i(),c=!1;return}if(!f||r){a()||s(),c=!0;return}c&&a()&&i(),c=!1},E=()=>{p=o.visibilityState==="visible",d()};o.addEventListener("visibilitychange",E);let b=typeof IntersectionObserver=="function"?new IntersectionObserver(r=>{m=r.some(x=>x.isIntersecting),d()}):null;return b?.observe(e),{sync:d,update(r){l=r.autoplay,f=r.autopause,d()},destroy(){b?.disconnect(),o.removeEventListener("visibilitychange",E)}}}var V=[["internal-format","internalFormat"],["format","format"],["type","type"],["min-filter","minFilter"],["mag-filter","magFilter"],["wrap-s","wrapS"],["wrap-t","wrapT"],["color-space","colorSpace"]];function y(e){if(!(e==null||e===!1))return String(e)}function g(e,t){if(e==null)return t;if(typeof e=="boolean")return e;switch(String(e).trim().toLowerCase()){case"false":case"0":case"no":case"off":return!1;default:return!0}}function w(e,t=""){let n={},a=y(e(`${t}history`));if(a!=null){let i=Number.parseInt(a,10);Number.isFinite(i)&&i>=0&&(n.history=i)}let s=e(`${t}preserve-y`);s!=null&&(n.preserveY=g(s,!0));for(let[i,u]of V){let o=y(e(`${t}${i}`));o&&(n[u]=o)}return n}function D(e,t=""){return w(n=>e.getAttribute(n),t)}function S(e){return e instanceof HTMLImageElement||e instanceof HTMLVideoElement||e instanceof HTMLCanvasElement}function O(e){return!(e instanceof HTMLImageElement)}function L(e,t){let n={once:!0};return new Promise((a,s)=>{let i=()=>{e.removeEventListener(t,u),e.removeEventListener("error",o)},u=l=>{i(),a(l)},o=l=>{i(),s(l)};e.addEventListener(t,u,n),e.addEventListener("error",o,n)})}async function H(e){return e.complete&&e.naturalWidth>0&&e.naturalHeight>0||await L(e,"load"),e}async function I(e){return e.videoWidth>0&&e.videoHeight>0||await L(e,"loadedmetadata"),e}async function P(e){if(e instanceof HTMLImageElement)return H(e);if(e instanceof HTMLVideoElement)return I(e);if(e.width<=0||e.height<=0)throw new Error("Texture canvas elements must have a positive width and height.");return e}function k(e){if(e instanceof HTMLVideoElement)return e.videoWidth>0&&e.videoHeight>0?e:void 0;if(e instanceof HTMLCanvasElement)return e.width>0&&e.height>0?e:void 0}function A(e,t){if(e instanceof HTMLImageElement)return e.addEventListener("load",t),()=>e.removeEventListener("load",t);if(e instanceof HTMLVideoElement)return e.addEventListener("loadedmetadata",t),()=>e.removeEventListener("loadedmetadata",t)}export{M as a,g as b,w as c,D as d,S as e,O as f,P as g,k as h,A as i};
|
|
2
|
+
//# sourceMappingURL=chunk-FVO6LH2F.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/autoplay.ts","../src/internal/declarative-textures.ts"],"sourcesContent":["export type PlaybackVisibilityController = {\n\tsync: () => void;\n\tupdate: (options: { autoplay: boolean; autopause: boolean }) => void;\n\tdestroy: () => void;\n};\n\ntype PlaybackVisibilityOptions = {\n\ttarget: HTMLElement;\n\tautoplay: boolean;\n\tautopause: boolean;\n\tisPlaying: () => boolean;\n\tplay: () => void;\n\tpause: () => void;\n\tonVisibilityChange?: (isVisible: boolean) => void;\n};\n\nfunction isElementInViewport(element: HTMLElement) {\n\tconst view = element.ownerDocument.defaultView ?? window;\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.width > 0 &&\n\t\trect.height > 0 &&\n\t\trect.bottom > 0 &&\n\t\trect.right > 0 &&\n\t\trect.top < view.innerHeight &&\n\t\trect.left < view.innerWidth\n\t);\n}\n\nexport function createPlaybackVisibilityController({\n\ttarget,\n\tautoplay,\n\tautopause,\n\tisPlaying,\n\tplay,\n\tpause,\n\tonVisibilityChange,\n}: PlaybackVisibilityOptions): PlaybackVisibilityController {\n\tconst documentRef = target.ownerDocument;\n\tlet currentAutoplay = autoplay;\n\tlet currentAutopause = autopause;\n\tlet isDocumentVisible = documentRef.visibilityState === 'visible';\n\tlet isIntersecting = isElementInViewport(target);\n\tlet isManagedPlayback = false;\n\tlet lastVisible: boolean | null = null;\n\n\tconst getIsVisible = () =>\n\t\tisDocumentVisible &&\n\t\t(typeof IntersectionObserver === 'function' ? isIntersecting : isElementInViewport(target)) &&\n\t\ttarget.isConnected;\n\n\tconst sync = () => {\n\t\tconst isVisible = getIsVisible();\n\t\tif (lastVisible !== isVisible) {\n\t\t\tlastVisible = isVisible;\n\t\t\tonVisibilityChange?.(isVisible);\n\t\t}\n\n\t\tif (!currentAutoplay) {\n\t\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\t\tpause();\n\t\t\t}\n\t\t\tisManagedPlayback = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!currentAutopause || isVisible) {\n\t\t\tif (!isPlaying()) {\n\t\t\t\tplay();\n\t\t\t}\n\t\t\tisManagedPlayback = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\tpause();\n\t\t}\n\t\tisManagedPlayback = false;\n\t};\n\n\tconst handleVisibilityChange = () => {\n\t\tisDocumentVisible = documentRef.visibilityState === 'visible';\n\t\tsync();\n\t};\n\tdocumentRef.addEventListener('visibilitychange', handleVisibilityChange);\n\n\tconst intersectionObserver =\n\t\ttypeof IntersectionObserver === 'function'\n\t\t\t? new IntersectionObserver(entries => {\n\t\t\t\t\tisIntersecting = entries.some(entry => entry.isIntersecting);\n\t\t\t\t\tsync();\n\t\t\t\t})\n\t\t\t: null;\n\tintersectionObserver?.observe(target);\n\n\treturn {\n\t\tsync,\n\t\tupdate(options) {\n\t\t\tcurrentAutoplay = options.autoplay;\n\t\t\tcurrentAutopause = options.autopause;\n\t\t\tsync();\n\t\t},\n\t\tdestroy() {\n\t\t\tintersectionObserver?.disconnect();\n\t\t\tdocumentRef.removeEventListener('visibilitychange', handleVisibilityChange);\n\t\t},\n\t};\n}\n","import type CoreShaderPad from '..';\nimport type { InitializeTextureOptions } from '..';\n\nexport type DomTextureElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;\nexport type LiveTextureSource = HTMLVideoElement | HTMLCanvasElement | CoreShaderPad;\n\nconst TEXTURE_OPTION_ATTRIBUTES = [\n\t['internal-format', 'internalFormat'],\n\t['format', 'format'],\n\t['type', 'type'],\n\t['min-filter', 'minFilter'],\n\t['mag-filter', 'magFilter'],\n\t['wrap-s', 'wrapS'],\n\t['wrap-t', 'wrapT'],\n\t['color-space', 'colorSpace'],\n] as const;\n\ntype AttributeValue = string | number | boolean | null | undefined;\n\nfunction stringFromAttribute(value: AttributeValue) {\n\tif (value == null || value === false) return undefined;\n\treturn String(value);\n}\n\nexport function parseBooleanLikeValue(value: AttributeValue, defaultValue: boolean) {\n\tif (value == null) return defaultValue;\n\tif (typeof value === 'boolean') return value;\n\n\tswitch (String(value).trim().toLowerCase()) {\n\t\tcase 'false':\n\t\tcase '0':\n\t\tcase 'no':\n\t\tcase 'off':\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n\nexport function parseTextureOptionsFromAttributes(\n\treadAttribute: (name: string) => AttributeValue,\n\tprefix = '',\n): InitializeTextureOptions {\n\tconst options: InitializeTextureOptions = {};\n\n\tconst historyValue = stringFromAttribute(readAttribute(`${prefix}history`));\n\tif (historyValue != null) {\n\t\tconst parsed = Number.parseInt(historyValue, 10);\n\t\tif (Number.isFinite(parsed) && parsed >= 0) options.history = parsed;\n\t}\n\n\tconst preserveYValue = readAttribute(`${prefix}preserve-y`);\n\tif (preserveYValue != null) {\n\t\toptions.preserveY = parseBooleanLikeValue(preserveYValue, true);\n\t}\n\n\tfor (const [attribute, option] of TEXTURE_OPTION_ATTRIBUTES) {\n\t\tconst value = stringFromAttribute(readAttribute(`${prefix}${attribute}`));\n\t\tif (value) (options as Record<string, unknown>)[option] = value;\n\t}\n\n\treturn options;\n}\n\nexport function parseTextureOptions(element: Element, prefix = '') {\n\treturn parseTextureOptionsFromAttributes(name => element.getAttribute(name), prefix);\n}\n\nexport function isDomTextureElement(element: Element): element is DomTextureElement {\n\treturn (\n\t\telement instanceof HTMLImageElement ||\n\t\telement instanceof HTMLVideoElement ||\n\t\telement instanceof HTMLCanvasElement\n\t);\n}\n\nexport function isLiveDomTextureElement(element: DomTextureElement) {\n\treturn !(element instanceof HTMLImageElement);\n}\n\nfunction onceEvent<T extends Event>(target: EventTarget, type: string): Promise<T> {\n\tconst options = { once: true };\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst cleanup = () => {\n\t\t\ttarget.removeEventListener(type, onResolve);\n\t\t\ttarget.removeEventListener('error', onReject as EventListener);\n\t\t};\n\n\t\tconst onResolve = (event: Event) => {\n\t\t\tcleanup();\n\t\t\tresolve(event as T);\n\t\t};\n\n\t\tconst onReject = (event: Event) => {\n\t\t\tcleanup();\n\t\t\treject(event);\n\t\t};\n\n\t\ttarget.addEventListener(type, onResolve, options);\n\t\ttarget.addEventListener('error', onReject as EventListener, options);\n\t});\n}\n\nasync function loadImageSource(image: HTMLImageElement) {\n\tif (image.complete && image.naturalWidth > 0 && image.naturalHeight > 0) return image;\n\tawait onceEvent(image, 'load');\n\treturn image;\n}\n\nasync function loadVideoSource(video: HTMLVideoElement) {\n\tif (video.videoWidth > 0 && video.videoHeight > 0) return video;\n\tawait onceEvent(video, 'loadedmetadata');\n\treturn video;\n}\n\nexport async function loadDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLImageElement) return loadImageSource(element);\n\tif (element instanceof HTMLVideoElement) return loadVideoSource(element);\n\tif (element.width <= 0 || element.height <= 0) {\n\t\tthrow new Error('Texture canvas elements must have a positive width and height.');\n\t}\n\treturn element;\n}\n\nexport function getLiveDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLVideoElement) {\n\t\treturn element.videoWidth > 0 && element.videoHeight > 0 ? element : undefined;\n\t}\n\tif (element instanceof HTMLCanvasElement) {\n\t\treturn element.width > 0 && element.height > 0 ? element : undefined;\n\t}\n\treturn undefined;\n}\n\nexport function addDomTextureRefreshListener(element: DomTextureElement, listener: () => void) {\n\tif (element instanceof HTMLImageElement) {\n\t\telement.addEventListener('load', listener);\n\t\treturn () => element.removeEventListener('load', listener);\n\t}\n\tif (element instanceof HTMLVideoElement) {\n\t\telement.addEventListener('loadedmetadata', listener);\n\t\treturn () => element.removeEventListener('loadedmetadata', listener);\n\t}\n\treturn undefined;\n}\n"],"mappings":"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","names":["isElementInViewport","element","view","rect","createPlaybackVisibilityController","target","autoplay","autopause","isPlaying","play","pause","onVisibilityChange","documentRef","currentAutoplay","currentAutopause","isDocumentVisible","isIntersecting","isManagedPlayback","lastVisible","getIsVisible","sync","isVisible","handleVisibilityChange","intersectionObserver","entries","entry","options","TEXTURE_OPTION_ATTRIBUTES","stringFromAttribute","value","parseBooleanLikeValue","defaultValue","parseTextureOptionsFromAttributes","readAttribute","prefix","options","historyValue","parsed","preserveYValue","attribute","option","parseTextureOptions","element","name","isDomTextureElement","isLiveDomTextureElement","onceEvent","target","type","resolve","reject","cleanup","onResolve","onReject","event","loadImageSource","image","loadVideoSource","video","loadDomTextureSource","getLiveDomTextureSource","addDomTextureRefreshListener","listener"]}
|
|
@@ -78,7 +78,8 @@ var TEXTURE_OPTION_ATTRIBUTES = [
|
|
|
78
78
|
["min-filter", "minFilter"],
|
|
79
79
|
["mag-filter", "magFilter"],
|
|
80
80
|
["wrap-s", "wrapS"],
|
|
81
|
-
["wrap-t", "wrapT"]
|
|
81
|
+
["wrap-t", "wrapT"],
|
|
82
|
+
["color-space", "colorSpace"]
|
|
82
83
|
];
|
|
83
84
|
function stringFromAttribute(value) {
|
|
84
85
|
if (value == null || value === false) return void 0;
|
|
@@ -192,4 +193,4 @@ export {
|
|
|
192
193
|
getLiveDomTextureSource,
|
|
193
194
|
addDomTextureRefreshListener
|
|
194
195
|
};
|
|
195
|
-
//# sourceMappingURL=chunk-
|
|
196
|
+
//# sourceMappingURL=chunk-UOFU6ODR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internal/autoplay.ts","../../src/internal/declarative-textures.ts"],"sourcesContent":["export type PlaybackVisibilityController = {\n\tsync: () => void;\n\tupdate: (options: { autoplay: boolean; autopause: boolean }) => void;\n\tdestroy: () => void;\n};\n\ntype PlaybackVisibilityOptions = {\n\ttarget: HTMLElement;\n\tautoplay: boolean;\n\tautopause: boolean;\n\tisPlaying: () => boolean;\n\tplay: () => void;\n\tpause: () => void;\n\tonVisibilityChange?: (isVisible: boolean) => void;\n};\n\nfunction isElementInViewport(element: HTMLElement) {\n\tconst view = element.ownerDocument.defaultView ?? window;\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.width > 0 &&\n\t\trect.height > 0 &&\n\t\trect.bottom > 0 &&\n\t\trect.right > 0 &&\n\t\trect.top < view.innerHeight &&\n\t\trect.left < view.innerWidth\n\t);\n}\n\nexport function createPlaybackVisibilityController({\n\ttarget,\n\tautoplay,\n\tautopause,\n\tisPlaying,\n\tplay,\n\tpause,\n\tonVisibilityChange,\n}: PlaybackVisibilityOptions): PlaybackVisibilityController {\n\tconst documentRef = target.ownerDocument;\n\tlet currentAutoplay = autoplay;\n\tlet currentAutopause = autopause;\n\tlet isDocumentVisible = documentRef.visibilityState === 'visible';\n\tlet isIntersecting = isElementInViewport(target);\n\tlet isManagedPlayback = false;\n\tlet lastVisible: boolean | null = null;\n\n\tconst getIsVisible = () =>\n\t\tisDocumentVisible &&\n\t\t(typeof IntersectionObserver === 'function' ? isIntersecting : isElementInViewport(target)) &&\n\t\ttarget.isConnected;\n\n\tconst sync = () => {\n\t\tconst isVisible = getIsVisible();\n\t\tif (lastVisible !== isVisible) {\n\t\t\tlastVisible = isVisible;\n\t\t\tonVisibilityChange?.(isVisible);\n\t\t}\n\n\t\tif (!currentAutoplay) {\n\t\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\t\tpause();\n\t\t\t}\n\t\t\tisManagedPlayback = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!currentAutopause || isVisible) {\n\t\t\tif (!isPlaying()) {\n\t\t\t\tplay();\n\t\t\t}\n\t\t\tisManagedPlayback = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\tpause();\n\t\t}\n\t\tisManagedPlayback = false;\n\t};\n\n\tconst handleVisibilityChange = () => {\n\t\tisDocumentVisible = documentRef.visibilityState === 'visible';\n\t\tsync();\n\t};\n\tdocumentRef.addEventListener('visibilitychange', handleVisibilityChange);\n\n\tconst intersectionObserver =\n\t\ttypeof IntersectionObserver === 'function'\n\t\t\t? new IntersectionObserver(entries => {\n\t\t\t\t\tisIntersecting = entries.some(entry => entry.isIntersecting);\n\t\t\t\t\tsync();\n\t\t\t\t})\n\t\t\t: null;\n\tintersectionObserver?.observe(target);\n\n\treturn {\n\t\tsync,\n\t\tupdate(options) {\n\t\t\tcurrentAutoplay = options.autoplay;\n\t\t\tcurrentAutopause = options.autopause;\n\t\t\tsync();\n\t\t},\n\t\tdestroy() {\n\t\t\tintersectionObserver?.disconnect();\n\t\t\tdocumentRef.removeEventListener('visibilitychange', handleVisibilityChange);\n\t\t},\n\t};\n}\n","import type CoreShaderPad from '..';\nimport type { InitializeTextureOptions } from '..';\n\nexport type DomTextureElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;\nexport type LiveTextureSource = HTMLVideoElement | HTMLCanvasElement | CoreShaderPad;\n\nconst TEXTURE_OPTION_ATTRIBUTES = [\n\t['internal-format', 'internalFormat'],\n\t['format', 'format'],\n\t['type', 'type'],\n\t['min-filter', 'minFilter'],\n\t['mag-filter', 'magFilter'],\n\t['wrap-s', 'wrapS'],\n\t['wrap-t', 'wrapT'],\n\t['color-space', 'colorSpace'],\n] as const;\n\ntype AttributeValue = string | number | boolean | null | undefined;\n\nfunction stringFromAttribute(value: AttributeValue) {\n\tif (value == null || value === false) return undefined;\n\treturn String(value);\n}\n\nexport function parseBooleanLikeValue(value: AttributeValue, defaultValue: boolean) {\n\tif (value == null) return defaultValue;\n\tif (typeof value === 'boolean') return value;\n\n\tswitch (String(value).trim().toLowerCase()) {\n\t\tcase 'false':\n\t\tcase '0':\n\t\tcase 'no':\n\t\tcase 'off':\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n\nexport function parseTextureOptionsFromAttributes(\n\treadAttribute: (name: string) => AttributeValue,\n\tprefix = '',\n): InitializeTextureOptions {\n\tconst options: InitializeTextureOptions = {};\n\n\tconst historyValue = stringFromAttribute(readAttribute(`${prefix}history`));\n\tif (historyValue != null) {\n\t\tconst parsed = Number.parseInt(historyValue, 10);\n\t\tif (Number.isFinite(parsed) && parsed >= 0) options.history = parsed;\n\t}\n\n\tconst preserveYValue = readAttribute(`${prefix}preserve-y`);\n\tif (preserveYValue != null) {\n\t\toptions.preserveY = parseBooleanLikeValue(preserveYValue, true);\n\t}\n\n\tfor (const [attribute, option] of TEXTURE_OPTION_ATTRIBUTES) {\n\t\tconst value = stringFromAttribute(readAttribute(`${prefix}${attribute}`));\n\t\tif (value) (options as Record<string, unknown>)[option] = value;\n\t}\n\n\treturn options;\n}\n\nexport function parseTextureOptions(element: Element, prefix = '') {\n\treturn parseTextureOptionsFromAttributes(name => element.getAttribute(name), prefix);\n}\n\nexport function isDomTextureElement(element: Element): element is DomTextureElement {\n\treturn (\n\t\telement instanceof HTMLImageElement ||\n\t\telement instanceof HTMLVideoElement ||\n\t\telement instanceof HTMLCanvasElement\n\t);\n}\n\nexport function isLiveDomTextureElement(element: DomTextureElement) {\n\treturn !(element instanceof HTMLImageElement);\n}\n\nfunction onceEvent<T extends Event>(target: EventTarget, type: string): Promise<T> {\n\tconst options = { once: true };\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst cleanup = () => {\n\t\t\ttarget.removeEventListener(type, onResolve);\n\t\t\ttarget.removeEventListener('error', onReject as EventListener);\n\t\t};\n\n\t\tconst onResolve = (event: Event) => {\n\t\t\tcleanup();\n\t\t\tresolve(event as T);\n\t\t};\n\n\t\tconst onReject = (event: Event) => {\n\t\t\tcleanup();\n\t\t\treject(event);\n\t\t};\n\n\t\ttarget.addEventListener(type, onResolve, options);\n\t\ttarget.addEventListener('error', onReject as EventListener, options);\n\t});\n}\n\nasync function loadImageSource(image: HTMLImageElement) {\n\tif (image.complete && image.naturalWidth > 0 && image.naturalHeight > 0) return image;\n\tawait onceEvent(image, 'load');\n\treturn image;\n}\n\nasync function loadVideoSource(video: HTMLVideoElement) {\n\tif (video.videoWidth > 0 && video.videoHeight > 0) return video;\n\tawait onceEvent(video, 'loadedmetadata');\n\treturn video;\n}\n\nexport async function loadDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLImageElement) return loadImageSource(element);\n\tif (element instanceof HTMLVideoElement) return loadVideoSource(element);\n\tif (element.width <= 0 || element.height <= 0) {\n\t\tthrow new Error('Texture canvas elements must have a positive width and height.');\n\t}\n\treturn element;\n}\n\nexport function getLiveDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLVideoElement) {\n\t\treturn element.videoWidth > 0 && element.videoHeight > 0 ? element : undefined;\n\t}\n\tif (element instanceof HTMLCanvasElement) {\n\t\treturn element.width > 0 && element.height > 0 ? element : undefined;\n\t}\n\treturn undefined;\n}\n\nexport function addDomTextureRefreshListener(element: DomTextureElement, listener: () => void) {\n\tif (element instanceof HTMLImageElement) {\n\t\telement.addEventListener('load', listener);\n\t\treturn () => element.removeEventListener('load', listener);\n\t}\n\tif (element instanceof HTMLVideoElement) {\n\t\telement.addEventListener('loadedmetadata', listener);\n\t\treturn () => element.removeEventListener('loadedmetadata', listener);\n\t}\n\treturn undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -99,6 +99,9 @@ var ShaderPad = class _ShaderPad {
|
|
|
99
99
|
canvasHeight: this.canvas.height
|
|
100
100
|
}) : spError(0);
|
|
101
101
|
}
|
|
102
|
+
if (texOptions.colorSpace && "drawingBufferColorSpace" in gl) {
|
|
103
|
+
gl.drawingBufferColorSpace = texOptions.colorSpace;
|
|
104
|
+
}
|
|
102
105
|
this.gl = gl;
|
|
103
106
|
this.typeArrays = /* @__PURE__ */ new Map([
|
|
104
107
|
[gl.FLOAT, Float32Array],
|
|
@@ -415,6 +418,7 @@ var ShaderPad = class _ShaderPad {
|
|
|
415
418
|
magFilter: this.resolveGLConst(options?.magFilter ?? "LINEAR"),
|
|
416
419
|
wrapS: this.resolveGLConst(options?.wrapS ?? "CLAMP_TO_EDGE"),
|
|
417
420
|
wrapT: this.resolveGLConst(options?.wrapT ?? "CLAMP_TO_EDGE"),
|
|
421
|
+
colorSpace: options?.colorSpace,
|
|
418
422
|
preserveY: options?.preserveY,
|
|
419
423
|
isIntegerColorFormat
|
|
420
424
|
};
|
|
@@ -431,9 +435,9 @@ var ShaderPad = class _ShaderPad {
|
|
|
431
435
|
const ArrayType = this.typeArrays.get(type) ?? Uint8Array;
|
|
432
436
|
return new ArrayType(size);
|
|
433
437
|
}
|
|
434
|
-
|
|
438
|
+
isRgba(format) {
|
|
435
439
|
const gl = this.gl;
|
|
436
|
-
return format
|
|
440
|
+
return format === gl.RGBA || format === gl.RGBA_INTEGER;
|
|
437
441
|
}
|
|
438
442
|
clearHistTexLayers(textureInfo) {
|
|
439
443
|
if (!textureInfo.history) return;
|
|
@@ -442,7 +446,7 @@ var ShaderPad = class _ShaderPad {
|
|
|
442
446
|
const transparent = this.getPxArray(type, textureInfo.width * textureInfo.height * 4);
|
|
443
447
|
gl.activeTexture(gl.TEXTURE0 + textureInfo.unitIndex);
|
|
444
448
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureInfo.texture);
|
|
445
|
-
const needsAlignmentFix = this.
|
|
449
|
+
const needsAlignmentFix = !this.isRgba(format);
|
|
446
450
|
let previousAlignment;
|
|
447
451
|
if (needsAlignmentFix) {
|
|
448
452
|
previousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);
|
|
@@ -740,15 +744,18 @@ var ShaderPad = class _ShaderPad {
|
|
|
740
744
|
if (!isPartial) {
|
|
741
745
|
this.resizeTex(name, width, height);
|
|
742
746
|
}
|
|
743
|
-
const
|
|
744
|
-
const shouldFlipY = !
|
|
747
|
+
const isCustomTexture = "data" in nonShaderPadSource && nonShaderPadSource.data;
|
|
748
|
+
const shouldFlipY = !isCustomTexture && !info.options?.preserveY;
|
|
745
749
|
const previousFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);
|
|
746
|
-
const needsAlignmentFix =
|
|
750
|
+
const needsAlignmentFix = isCustomTexture && !this.isRgba(info.options.format);
|
|
751
|
+
const shouldConvertColorSpace = !isCustomTexture && info.options.colorSpace && "unpackColorSpace" in gl;
|
|
752
|
+
const previousColorSpace = gl.unpackColorSpace;
|
|
747
753
|
let previousAlignment;
|
|
748
754
|
if (needsAlignmentFix) {
|
|
749
755
|
previousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);
|
|
750
756
|
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
751
757
|
}
|
|
758
|
+
if (shouldConvertColorSpace) gl.unpackColorSpace = info.options.colorSpace;
|
|
752
759
|
if (info.history) {
|
|
753
760
|
gl.activeTexture(gl.TEXTURE0 + info.unitIndex);
|
|
754
761
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, info.texture);
|
|
@@ -811,6 +818,7 @@ var ShaderPad = class _ShaderPad {
|
|
|
811
818
|
}
|
|
812
819
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);
|
|
813
820
|
}
|
|
821
|
+
if (shouldConvertColorSpace) gl.unpackColorSpace = previousColorSpace;
|
|
814
822
|
if (needsAlignmentFix) gl.pixelStorei(gl.UNPACK_ALIGNMENT, previousAlignment);
|
|
815
823
|
}
|
|
816
824
|
bindIntermediate() {
|
|
@@ -992,4 +1000,4 @@ var index_default = ShaderPad;
|
|
|
992
1000
|
export {
|
|
993
1001
|
index_default
|
|
994
1002
|
};
|
|
995
|
-
//# sourceMappingURL=chunk-
|
|
1003
|
+
//# sourceMappingURL=chunk-YB3GMXKV.mjs.map
|