(function(c,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(c=typeof globalThis<"u"?globalThis:c||self,l(c["image-effect-renderer"]={}))})(this,function(c){"use strict";class g{gl;_program;vs;fs;initialized=!1;ext;type=0;vsSource="";fsSource="";uniformLocations={};attributeLocations={};_compiled=!1;constructor(e,i){this.gl=e;const t=e.context;this.ext=t.getExtension("KHR_parallel_shader_compile"),this._program=t.createProgram(),this.vs=t.createShader(t.VERTEX_SHADER),this.fs=t.createShader(t.FRAGMENT_SHADER),this.type=this.detectType(i),this.vsSource=this.getVertexShader(this.type),t.shaderSource(this.vs,this.vsSource),t.compileShader(this.vs),this.fsSource=`${this.getFragmentShader(this.type)}${i}`,t.shaderSource(this.fs,this.fsSource),t.compileShader(this.fs),t.attachShader(this._program,this.vs),t.attachShader(this._program,this.fs),t.linkProgram(this._program)}get program(){if(this.initialized)return this._program;this.initialized=!0;const e=this.gl.context;let i=e.getShaderParameter(this.vs,e.COMPILE_STATUS);if(!i)throw console.table(this.vsSource.split(` `)),new Error(`ImageEffectRenderer: Vertex shader compilation failed: ${e.getShaderInfoLog(this.vs)}`);if(i=e.getShaderParameter(this.fs,e.COMPILE_STATUS),!i)throw console.table(this.fsSource.split(` `)),new Error(`ImageEffectRenderer: Shader compilation failed: ${e.getShaderInfoLog(this.fs)}`);if(i=e.getProgramParameter(this._program,e.LINK_STATUS),!i)throw new Error(`ImageEffectRenderer: Program linking failed: ${e.getProgramInfoLog(this._program)}`);return this._program}get shaderCompiled(){return this._compiled=this._compiled||!this.ext||this.gl.context.getProgramParameter(this._program,this.ext.COMPLETION_STATUS_KHR),this._compiled}use(){this.gl.context.useProgram(this.program)}getUniformLocation(e){return this.uniformLocations[e]!==void 0?this.uniformLocations[e]:this.uniformLocations[e]=this.gl.context.getUniformLocation(this._program,e)}getAttributeLocation(e){return this.attributeLocations[e]!==void 0?this.attributeLocations[e]:(this.gl.context.useProgram(this.program),this.attributeLocations[e]=this.gl.context.getAttribLocation(this._program,e))}detectType(e){const i=/mainImage/gmi,t=/^#version[\s]+300[\s]+es[\s]+/gmi;return i.exec(e)?0:t.exec(e)?3:2}getFragmentShader(e){switch(e){case 0:return`#version 300 es precision highp float; ${this.getUniformShader()} in vec2 vUV0; out vec4 outFragColor; void mainImage(out vec4, vec2); vec4 texture2D(sampler2D tex, vec2 uv) { return texture(tex, uv); } void main(void) { outFragColor = vec4(0.0, 0.0, 0.0, 1.0); mainImage(outFragColor, vUV0 * iResolution.xy); } `;default:return""}}getVertexShader(e){switch(e){case 0:return`#version 300 es in vec2 aPos; in vec2 aUV; out vec2 vUV0; void main(void) { vUV0 = aUV; gl_Position = vec4(aPos, 0.0, 1.0); } `;case 2:return`attribute vec3 aPos; attribute vec2 aUV; uniform float iAspect; varying vec2 vScreen; varying vec2 vUV0; void main(void) { vUV0 = aUV; vScreen = aPos.xy; vScreen.x *= iAspect; gl_Position = vec4(aPos, 1.0); }`;case 3:default:return`#version 300 es in vec3 aPos; in vec2 aUV; uniform float iAspect; out vec2 vScreen; out vec2 vUV0; void main(void) { vUV0 = aUV; vScreen = aPos.xy; vScreen.x *= iAspect; gl_Position = vec4(aPos, 1.0); }`}}getUniformShader(){return` uniform vec2 iResolution; uniform float iTime; uniform float iGlobalTime; uniform float iAspect; uniform int iFrame; uniform vec4 iMouse; uniform highp sampler2D iChannel0; uniform highp sampler2D iChannel1; uniform highp sampler2D iChannel2; uniform highp sampler2D iChannel3; uniform highp sampler2D iChannel4; uniform highp sampler2D iChannel5; uniform highp sampler2D iChannel6; uniform highp sampler2D iChannel7; uniform vec2 iChannelResolution0; uniform vec2 iChannelResolution1; uniform vec2 iChannelResolution2; uniform vec2 iChannelResolution3; uniform vec2 iChannelResolution4; uniform vec2 iChannelResolution5; uniform vec2 iChannelResolution6; uniform vec2 iChannelResolution7; `}}const x=0,R=1,E=2,v=3,T=4,_=5;class L{type;name;x=0;y=0;z=0;w=0;matrix;constructor(e,i){this.type=e,this.name=i}}class U{context;canvas;sharedPrograms={};sharedTextures={};quadVBO;lastQuadVBO=void 0;constructor(e=void 0){this.canvas=e||document.createElement("canvas");const i={premultipliedAlpha:!0,alpha:!0,preserveDrawingBuffer:!1,antialias:!1,depth:!1,stencil:!1};if(this.context=this.canvas.getContext("webgl2",i),!this.context)throw new Error("Unable to create WebGL2 context.");this.context.getExtension("WEBGL_color_buffer_float"),this.context.getExtension("EXT_color_buffer_float"),this.context.getExtension("OES_texture_float"),this.context.getExtension("OES_texture_float_linear"),this.context.getExtension("KHR_parallel_shader_compile"),this.context.clearColor(0,0,0,0),this.context.clear(this.context.COLOR_BUFFER_BIT),this.context.enable(this.context.BLEND),this.context.blendFunc(this.context.ONE,this.context.ONE_MINUS_SRC_ALPHA),this.quadVBO=this.generateQuad()}drawQuad(e,i){const t=this.context;this.lastQuadVBO!==this.quadVBO&&(this.lastQuadVBO=this.quadVBO,t.bindBuffer(t.ARRAY_BUFFER,this.quadVBO),t.enableVertexAttribArray(e),t.vertexAttribPointer(e,2,t.FLOAT,!1,4*4,0),t.enableVertexAttribArray(i),t.vertexAttribPointer(i,2,t.FLOAT,!1,4*4,2*4)),t.drawArrays(t.TRIANGLE_STRIP,0,4)}getCachedTexture(e,i){const t=`${e}_${i.clampX}_${i.clampY}_${i.useMipmap}`;return this.sharedTextures[e]?this.sharedTextures[t]:this.sharedTextures[t]=this.context.createTexture()}compileShader(e){return this.sharedPrograms[e]?this.sharedPrograms[e]:this.sharedPrograms[e]=new g(this,e)}setTextureParameter(e,i){const t=this.context;t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,i.clampX?t.CLAMP_TO_EDGE:t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,i.clampY?t.CLAMP_TO_EDGE:t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,i.magFilterLinear?t.LINEAR:t.NEAREST),i.useMipmap?(t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR_MIPMAP_LINEAR),t.generateMipmap(t.TEXTURE_2D)):t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,i.minFilterLinear?t.LINEAR:t.NEAREST)}bindTextures(e){const i=this.context;for(let t=0;t<8;t++){i.activeTexture(i.TEXTURE0+t);const s=e[t];s&&s.buffer?i.bindTexture(i.TEXTURE_2D,s.buffer.src.texture):s&&s.texture?i.bindTexture(i.TEXTURE_2D,s.texture):i.bindTexture(i.TEXTURE_2D,null)}}setUniforms(e,i){const t=this.context;Object.values(e).forEach(s=>{const r=i.getUniformLocation(s.name);if(r!==null)switch(s.type){case x:t.uniform1i(r,s.x);break;case R:t.uniform1f(r,s.x);break;case E:t.uniform2f(r,s.x,s.y);break;case v:t.uniform3f(r,s.x,s.y,s.z);break;case T:t.uniform4f(r,s.x,s.y,s.z,s.w);break;case _:t.uniformMatrix4fv(r,!1,s.matrix);break}})}generateQuad(){const e=this.context,i=new Float32Array([-1,1,0,1,-1,-1,0,0,1,1,1,1,1,-1,1,0]),t=e.createBuffer();return e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,i,e.STATIC_DRAW),t}}const F={clampX:!0,clampY:!0,flipY:!1,useMipmap:!0,useCache:!0,minFilterLinear:!0,magFilterLinear:!0};class d{width=0;height=0;program;main;gl;frame=0;mouse=[0,0,0,0];uniforms={};textures=[];constructor(e){this.gl=e}get shaderCompiled(){return this.program.shaderCompiled}get iMouseUsed(){return this.program.getUniformLocation("iMouse")!==null}setImage(e,i,t={}){if(e>=8)throw new Error("ImageEffectRenderer: A maximum of 8 slots is available, slotIndex is out of bounds.");this.setUniformInt(`iChannel${e}`,e);let s,r;typeof VideoFrame<"u"&&i instanceof VideoFrame?(s=i.displayWidth,r=i.displayHeight):(s=i.width,r=i.height),this.setUniformVec2(`iChannelResolution${e}`,s,r);const n=this.gl.context,o=this.textures[e];if(i instanceof d){o&&o.texture&&!o.cached&&n.deleteTexture(o.texture);const a={...i.options,...t};this.textures[e]={texture:void 0,buffer:i,cached:!1},this.gl.setTextureParameter(i.src.texture,a),this.gl.setTextureParameter(i.dest.texture,a)}else{const a={...F,...t};a.useCache=a.useCache&&i instanceof HTMLImageElement,a.useCache&&o&&o.texture&&!o.cached&&(n.deleteTexture(o.texture),o.texture=void 0);let u=o&&o.texture;a.useCache&&i instanceof HTMLImageElement&&(u=this.gl.getCachedTexture(i.src,a)),u||(u=n.createTexture()),this.textures[e]={texture:u,buffer:void 0,cached:a.useCache},n.bindTexture(n.TEXTURE_2D,u),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,t.flipY?1:0),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,i),this.gl.setTextureParameter(u,a)}}setUniformFloat(e,i){this.setUniform(e,R,i,0,0,0,void 0)}setUniformInt(e,i){this.setUniform(e,x,i,0,0,0,void 0)}setUniformVec2(e,i,t){this.setUniform(e,E,i,t,0,0,void 0)}setUniformVec3(e,i,t,s){this.setUniform(e,v,i,t,s,0,void 0)}setUniformVec4(e,i,t,s,r){this.setUniform(e,T,i,t,s,r,void 0)}setUniformMatrix(e,i){this.setUniform(e,_,0,0,0,0,i)}destruct(){this.textures.forEach(e=>e.texture&&!e.cached&&this.gl.context.deleteTexture(e.texture)),this.textures=[],this.uniforms={}}draw(e=0,i,t){this.width=i|0,this.height=t|0,this.program.use(),this.setUniformFloat("iGlobalTime",e),this.setUniformFloat("iTime",e),this.setUniformInt("iFrame",this.frame),this.setUniformFloat("iAspect",i/t),this.setUniformVec2("iResolution",i,t);const s=this.main.mouse;this.setUniformVec4("iMouse",s[0],s[1],s[2],s[3]),this.gl.setUniforms(this.uniforms,this.program),this.gl.bindTextures(this.textures),this.gl.drawQuad(this.program.getAttributeLocation("aPos"),this.program.getAttributeLocation("aUV")),this.frame++}setUniform(e,i,t,s,r,n,o){let a=this.uniforms[e];a||(a=this.uniforms[e]=new L(i,e)),a.x=t,a.y=s,a.z=r,a.w=n,a.matrix=o}}const w={type:5121,pixelRatio:1,msaa:!1};class A{width=0;height=0;texture;frameBuffer;options;gl;format=WebGLRenderingContext.RGBA;internalFormat=WebGLRenderingContext.RGBA;constructor(e,i={}){switch(this.gl=e,this.options={...w,...i},this.options.type){case WebGLRenderingContext.UNSIGNED_BYTE:this.internalFormat=WebGL2RenderingContext.RGBA8;break;case WebGLRenderingContext.FLOAT:this.internalFormat=WebGL2RenderingContext.RGBA32F;break}const t=e.context;this.texture=t.createTexture(),this.resize(16,16),this.frameBuffer=t.createFramebuffer(),t.bindFramebuffer(t.FRAMEBUFFER,this.frameBuffer),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.texture,0),t.bindFramebuffer(t.FRAMEBUFFER,null)}resize(e,i){if(this.width===(e|0)&&this.height===(i|0))return;this.width=e|0,this.height=i|0;const t=this.gl.context;t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,0),t.texImage2D(t.TEXTURE_2D,0,this.internalFormat,this.width,this.height,0,this.format,this.options.type,null)}destruct(){const e=this.gl.context;this.frameBuffer&&e.deleteFramebuffer(this.frameBuffer),this.texture&&e.deleteTexture(this.texture)}}const B={...F,...w,useMipmap:!1,useCache:!1};class I extends d{options;frameBuffer0;frameBuffer1;constructor(e,i={}){super(e),this.options={...B,...i},this.frameBuffer0=new A(e,this.options),this.frameBuffer1=new A(e,this.options)}get src(){return this.frame%2===0?this.frameBuffer0:this.frameBuffer1}get dest(){return this.frame%2===1?this.frameBuffer0:this.frameBuffer1}draw(e=0,i,t){if(i<=0||t<=0)return;const s=this.gl.context,r=this.dest;r.resize(i,t),s.bindFramebuffer(s.FRAMEBUFFER,r.frameBuffer),s.clear(s.COLOR_BUFFER_BIT),super.draw(e,i,t),s.bindFramebuffer(s.FRAMEBUFFER,null)}destruct(){super.destruct(),this.frameBuffer0.destruct(),this.frameBuffer1.destruct()}}let b=-0,O=-0,C=!1;function M(h){C||(C=!0,h.addEventListener("mousemove",e=>{b=e.clientX,O=e.clientY},{passive:!0}))}function y(){return[b,O]}function D(h,e){const i=(e[0]-h.left)/h.width,t=1-(e[1]-h.top)/h.height;return[i,t]}class S extends d{static index=0;canvas;buffers=[];options;time=0;tickFuncs=[];readyFuncs=[];startTime=-1;drawOneFrame=!1;container;animationRequestId=0;resizeObserver;_ready=!1;constructor(e,i,t,s){if(super(e),this.options={...s},this.container=i,this.main=this,this.options.useSharedContext){this.canvas=document.createElement("canvas");const r=this.canvas.getContext("2d");r.fillStyle="#00000000",r.clearRect(0,0,this.canvas.width,this.canvas.height)}else this.canvas=this.gl.canvas;Object.assign(this.canvas.style,{inset:"0",width:"100%",height:"100%",margin:"0",display:"block"}),this.container.appendChild(this.canvas),this.program=new g(this.gl,t),this.resizeObserver=new ResizeObserver(()=>{this.options.autoResize&&this.updateSize()}),this.resizeObserver.observe(i),this.options.useSharedContext||this.drawingLoop(0)}get drawThisFrame(){return(this.options.loop||this.drawOneFrame)&&this.width>0&&this.height>0&&(!this.options.asyncCompile||this.allShadersCompiled)}get iMouseUsed(){return super.iMouseUsed||this.buffers.some(e=>e&&e.iMouseUsed)}get allShadersCompiled(){return this.shaderCompiled&&this.buffers.every(e=>e&&e.shaderCompiled)}play(){this.options.loop=!0}stop(){this.options.loop=!1}createBuffer(e,i,t={}){const s=this.buffers[e];s&&s.destruct();const r=new I(this.gl,t);return r.program=this.gl.compileShader(i),r.main=this,this.buffers[e]=r}tick(e){this.tickFuncs.push(e)}ready(e){this.readyFuncs.push(e)}drawFrame(e=0){this.time=e/1e3,this.drawOneFrame=!0}drawInstance(e){const i=this.gl.context;if(this.drawOneFrame||(this.time+=e),this.tickFuncs.forEach(t=>t(e)),this.iMouseUsed){const t=this.mouse[0],s=this.mouse[1],[r,n]=D(this.container.getBoundingClientRect(),y());this.mouse=[r,n,t,s]}this.buffers.forEach(t=>{t&&(i.viewport(0,0,this.width,this.height),t.draw(this.time,this.canvas.width,this.canvas.height))}),i.viewport(0,0,this.width,this.height),i.clear(i.COLOR_BUFFER_BIT),this.draw(this.time,this.canvas.width,this.canvas.height),this.drawOneFrame=!1}update(e){this.allShadersCompiled&&(this._ready||(this._ready=!0,this.readyFuncs.forEach(i=>i()),this.readyFuncs=[],this.iMouseUsed&&M(document.body)))}destruct(){cancelAnimationFrame(this.animationRequestId),super.destruct(),this.resizeObserver.disconnect(),this.container.removeChild(this.canvas),this.canvas.replaceWith(this.canvas.cloneNode(!0)),this.buffers.forEach(e=>{e.destruct()}),this.buffers=[],this.tickFuncs=[]}copyCanvas(){const e=this.gl.canvas,t=this.canvas.getContext("2d");t.clearRect(0,0,this.width,this.height),t.drawImage(e,0,e.height-this.height,this.width,this.height,0,0,this.width,this.height)}updateSize(){this.width=this.container.offsetWidth*this.options.pixelRatio|0,this.height=this.container.offsetHeight*this.options.pixelRatio|0,(this.width!==this.canvas.width||this.height!==this.canvas.height)&&(this.canvas.width=this.width,this.canvas.height=this.height,this.drawOneFrame=!0)}drawingLoop(e=0){this.animationRequestId=window.requestAnimationFrame(t=>this.drawingLoop(t)),e/=1e3;const i=this.startTime<0?1/60:e-this.startTime;this.startTime=e>0?e:-1,this.update(i),this.drawThisFrame&&this.drawInstance(i)}}const V={loop:!1,autoResize:!0,pixelRatio:typeof window<"u"?window.devicePixelRatio:1,useSharedContext:!1,asyncCompile:!0},m=[],P=[];let f,p=-1;class G{constructor(){throw new Error("Use ImageEffectRenderer.createTemporary to create an ImageEffectRenderer")}static createTemporary(e,i,t={}){const s={...V,...t};if(s.useSharedContext){f||(f=new U,this.drawInstances(0));const r=new S(f,e,i,s);return m.push(r),r}else{const r=P.pop()||new U;return new S(r,e,i,s)}}static releaseTemporary(e){e.options.useSharedContext||P.push(e.gl),e.stop(),e.destruct();const i=m.indexOf(e);i>-1&&m.splice(i,1)}static drawInstances(e=0){window.requestAnimationFrame(a=>this.drawInstances(a)),e/=1e3;const i=p<0?1/60:e-p;p=e;const t=f.canvas,s=f.context,r=m;let n=0,o=0;r.forEach(a=>{a.update(i)}),r.forEach(a=>{a.drawThisFrame&&(n=Math.max(n,a.width),o=Math.max(o,a.height))}),(n>t.width||o>t.height)&&(t.width=n,t.height=o),s.clear(s.COLOR_BUFFER_BIT),r.forEach(a=>{a.drawThisFrame&&(a.drawInstance(i),a.copyCanvas())})}}c.ImageEffectRenderer=G,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});