@paper-design/shaders 0.0.12 → 0.0.14

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/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  /** The core Shader Mounting class. Pass it a canvas element and a fragment shader to get started. */
2
2
  export { ShaderMount } from './shader-mount';
3
3
  /** An example fragment shader that renders a grainy texture over top of blobby animated clouds */
4
- export { grainCloudsFragmentShader, type GrainCloudsUniforms, } from './shaders/grain-clouds';
4
+ export { grainCloudsFragmentShader, type GrainCloudsUniforms } from './shaders/grain-clouds';
5
+ /** A shader that renders a mesh gradient with a rotating noise pattern and several layers of fractal noise */
6
+ export { meshGradientFragmentShader, type MeshGradientUniforms } from './shaders/mesh-gradient';
7
+ /** A shader rendering a fractal-like structure made of several layers of since-arches */
8
+ export { neuroNoiseFragmentShader, type NeuroNoiseUniforms } from './shaders/neuro-noise';
5
9
  export { getShaderColorFromString } from './shader-mount';
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
- var p=class{canvas;gl;program=null;uniformLocations={};fragmentShader;rafId=null;lastFrameTime=0;totalAnimationTime=0;isAnimated;providedUniforms;hasBeenDisposed=!1;resolutionChanged=!0;constructor(e,r,i={},n,s=!0){this.canvas=e,this.fragmentShader=r,this.providedUniforms=i,this.isAnimated=s;let o=e.getContext("webgl",n);if(!o)throw new Error("WebGL not supported");this.gl=o,this.initWebGL(),this.setupResizeObserver(),this.isAnimated?this.startAnimating():this.render(performance.now())}initWebGL=()=>{let e=x(this.gl,v,this.fragmentShader);e&&(this.program=e,this.setupPositionAttribute(),this.setupUniforms())};setupPositionAttribute=()=>{let e=this.gl.getAttribLocation(this.program,"a_position"),r=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,r);let i=[-1,-1,1,-1,-1,1,-1,1,1,-1,1,1];this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(i),this.gl.STATIC_DRAW),this.gl.enableVertexAttribArray(e),this.gl.vertexAttribPointer(e,2,this.gl.FLOAT,!1,0,0)};setupUniforms=()=>{this.uniformLocations={u_time:this.gl.getUniformLocation(this.program,"u_time"),u_resolution:this.gl.getUniformLocation(this.program,"u_resolution"),...Object.fromEntries(Object.keys(this.providedUniforms).map(e=>[e,this.gl.getUniformLocation(this.program,e)]))}};resizeObserver=null;setupResizeObserver=()=>{this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this.canvas),this.handleResize()};handleResize=()=>{let e=this.canvas.clientWidth,r=this.canvas.clientHeight;(this.canvas.width!==e||this.canvas.height!==r)&&(this.canvas.width=e,this.canvas.height=r,this.resolutionChanged=!0,this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.render(performance.now()))};render=e=>{if(this.hasBeenDisposed)return;let r=e-this.lastFrameTime;this.lastFrameTime=e,this.isAnimated&&(this.totalAnimationTime+=r),this.gl.useProgram(this.program),this.gl.uniform1f(this.uniformLocations.u_time,this.totalAnimationTime*.001),this.resolutionChanged&&(this.gl.uniform2f(this.uniformLocations.u_resolution,this.gl.canvas.width,this.gl.canvas.height),this.resolutionChanged=!1),this.gl.drawArrays(this.gl.TRIANGLES,0,6),this.isAnimated?this.requestRender():this.rafId=null};requestRender=()=>{this.rafId!==null&&cancelAnimationFrame(this.rafId),this.rafId=requestAnimationFrame(this.render)};updateProvidedUniforms=()=>{this.gl.useProgram(this.program),Object.entries(this.providedUniforms).forEach(([e,r])=>{let i=this.uniformLocations[e];if(i)if(Array.isArray(r))switch(r.length){case 2:this.gl.uniform2fv(i,r);break;case 3:this.gl.uniform3fv(i,r);break;case 4:this.gl.uniform4fv(i,r);break;default:r.length===9?this.gl.uniformMatrix3fv(i,!1,r):r.length===16?this.gl.uniformMatrix4fv(i,!1,r):console.warn(`Unsupported uniform array length: ${r.length}`)}else typeof r=="number"?this.gl.uniform1f(i,r):typeof r=="boolean"?this.gl.uniform1i(i,r?1:0):console.warn(`Unsupported uniform type for ${e}: ${typeof r}`)})};startAnimating=()=>{this.isAnimated=!0,this.lastFrameTime=performance.now(),this.rafId=requestAnimationFrame(this.render)};stopAnimating=()=>{this.isAnimated=!1,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null)};setUniforms=e=>{this.providedUniforms={...this.providedUniforms,...e},this.updateProvidedUniforms(),this.render(performance.now())};dispose=()=>{this.hasBeenDisposed=!0,this.stopAnimating(),this.gl&&this.program&&(this.gl.deleteProgram(this.program),this.program=null,this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null),this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null),this.gl.bindRenderbuffer(this.gl.RENDERBUFFER,null),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.getError()),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.uniformLocations={}}},v=`
1
+ /***** Paper Shaders: https://github.com/paper-design/shaders *****/
2
+ var v=class{canvas;gl;program=null;uniformLocations={};fragmentShader;rafId=null;lastFrameTime=0;totalAnimationTime=0;isAnimated;providedUniforms;hasBeenDisposed=!1;resolutionChanged=!0;constructor(r,t,i={},o,n=!0){this.canvas=r,this.fragmentShader=t,this.providedUniforms=i,this.isAnimated=n;let s=r.getContext("webgl",o);if(!s)throw new Error("WebGL not supported");this.gl=s,this.initWebGL(),this.setupResizeObserver(),this.isAnimated?this.startAnimating():this.render(performance.now())}initWebGL=()=>{let r=x(this.gl,_,this.fragmentShader);r&&(this.program=r,this.setupPositionAttribute(),this.setupUniforms())};setupPositionAttribute=()=>{let r=this.gl.getAttribLocation(this.program,"a_position"),t=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,t);let i=[-1,-1,1,-1,-1,1,-1,1,1,-1,1,1];this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(i),this.gl.STATIC_DRAW),this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,0,0)};setupUniforms=()=>{this.uniformLocations={u_time:this.gl.getUniformLocation(this.program,"u_time"),u_resolution:this.gl.getUniformLocation(this.program,"u_resolution"),...Object.fromEntries(Object.keys(this.providedUniforms).map(r=>[r,this.gl.getUniformLocation(this.program,r)]))}};resizeObserver=null;setupResizeObserver=()=>{this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this.canvas),this.handleResize()};handleResize=()=>{let r=this.canvas.clientWidth,t=this.canvas.clientHeight;(this.canvas.width!==r||this.canvas.height!==t)&&(this.canvas.width=r,this.canvas.height=t,this.resolutionChanged=!0,this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.render(performance.now()))};render=r=>{if(this.hasBeenDisposed)return;let t=r-this.lastFrameTime;this.lastFrameTime=r,this.isAnimated&&(this.totalAnimationTime+=t),this.gl.useProgram(this.program),this.gl.uniform1f(this.uniformLocations.u_time,this.totalAnimationTime*.001),this.resolutionChanged&&(this.gl.uniform2f(this.uniformLocations.u_resolution,this.gl.canvas.width,this.gl.canvas.height),this.resolutionChanged=!1),this.gl.drawArrays(this.gl.TRIANGLES,0,6),this.isAnimated?this.requestRender():this.rafId=null};requestRender=()=>{this.rafId!==null&&cancelAnimationFrame(this.rafId),this.rafId=requestAnimationFrame(this.render)};updateProvidedUniforms=()=>{this.gl.useProgram(this.program),Object.entries(this.providedUniforms).forEach(([r,t])=>{let i=this.uniformLocations[r];if(i)if(Array.isArray(t))switch(t.length){case 2:this.gl.uniform2fv(i,t);break;case 3:this.gl.uniform3fv(i,t);break;case 4:this.gl.uniform4fv(i,t);break;default:t.length===9?this.gl.uniformMatrix3fv(i,!1,t):t.length===16?this.gl.uniformMatrix4fv(i,!1,t):console.warn(`Unsupported uniform array length: ${t.length}`)}else typeof t=="number"?this.gl.uniform1f(i,t):typeof t=="boolean"?this.gl.uniform1i(i,t?1:0):console.warn(`Unsupported uniform type for ${r}: ${typeof t}`)})};startAnimating=()=>{this.isAnimated=!0,this.lastFrameTime=performance.now(),this.rafId=requestAnimationFrame(this.render)};stopAnimating=()=>{this.isAnimated=!1,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null)};setUniforms=r=>{this.providedUniforms={...this.providedUniforms,...r},this.updateProvidedUniforms(),this.render(performance.now())};dispose=()=>{this.hasBeenDisposed=!0,this.stopAnimating(),this.gl&&this.program&&(this.gl.deleteProgram(this.program),this.program=null,this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null),this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null),this.gl.bindRenderbuffer(this.gl.RENDERBUFFER,null),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.getError()),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.uniformLocations={}}},_=`
2
3
  attribute vec4 a_position;
3
4
  void main() {
4
5
  gl_Position = a_position;
5
6
  }
6
- `;function b(t,e,r){let i=t.createShader(e);return i?(t.shaderSource(i,r),t.compileShader(i),t.getShaderParameter(i,t.COMPILE_STATUS)?i:(console.error("An error occurred compiling the shaders: "+t.getShaderInfoLog(i)),t.deleteShader(i),null)):null}function x(t,e,r){let i=b(t,t.VERTEX_SHADER,e),n=b(t,t.FRAGMENT_SHADER,r);if(!i||!n)return null;let s=t.createProgram();return s?(t.attachShader(s,i),t.attachShader(s,n),t.linkProgram(s),t.getProgramParameter(s,t.LINK_STATUS)?(t.detachShader(s,i),t.detachShader(s,n),t.deleteShader(i),t.deleteShader(n),s):(console.error("Unable to initialize the shader program: "+t.getProgramInfoLog(s)),t.deleteProgram(s),t.deleteShader(i),t.deleteShader(n),null)):null}function A(t){let e,r,i;if(t.startsWith("#"))[e,r,i]=_(t);else if(t.startsWith("rgb"))[e,r,i]=R(t);else if(t.startsWith("hsl"))[e,r,i]=y(S(t));else return console.error("Unsupported color format"),[0,0,0];return[e,r,i]}function _(t){let e=parseInt(t.slice(1),16),r=(e>>16&255)/255,i=(e>>8&255)/255,n=(e&255)/255;return[r,i,n]}function R(t){let e=t.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);return e?[parseInt(e[1]??"0")/255,parseInt(e[2]??"0")/255,parseInt(e[3]??"0")/255]:[0,0,0]}function S(t){let e=t.match(/^hsl\s*\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$/i);return e?[parseInt(e[1]??"0"),parseInt(e[2]??"0"),parseInt(e[3]??"0")]:[0,0,0]}function y(t){let[e,r,i]=t,n=e/360,s=r/100,o=i/100,m,l,c;if(r===0)m=l=c=o;else{let f=(h,g,a)=>(a<0&&(a+=1),a>1&&(a-=1),a<.16666666666666666?h+(g-h)*6*a:a<.5?g:a<.6666666666666666?h+(g-h)*(.6666666666666666-a)*6:h),u=o<.5?o*(1+s):o+s-o*s,d=2*o-u;m=f(d,u,n+1/3),l=f(d,u,n),c=f(d,u,n-1/3)}return[m,l,c]}var L=`
7
+ `;function b(e,r,t){let i=e.createShader(r);return i?(e.shaderSource(i,t),e.compileShader(i),e.getShaderParameter(i,e.COMPILE_STATUS)?i:(console.error("An error occurred compiling the shaders: "+e.getShaderInfoLog(i)),e.deleteShader(i),null)):null}function x(e,r,t){let i=b(e,e.VERTEX_SHADER,r),o=b(e,e.FRAGMENT_SHADER,t);if(!i||!o)return null;let n=e.createProgram();return n?(e.attachShader(n,i),e.attachShader(n,o),e.linkProgram(n),e.getProgramParameter(n,e.LINK_STATUS)?(e.detachShader(n,i),e.detachShader(n,o),e.deleteShader(i),e.deleteShader(o),n):(console.error("Unable to initialize the shader program: "+e.getProgramInfoLog(n)),e.deleteProgram(n),e.deleteShader(i),e.deleteShader(o),null)):null}function g(e,r=[0,0,0]){if(Array.isArray(e)&&e.length===3)return e;if(typeof e!="string")return g(r);let t,i,o;if(e.startsWith("#"))[t,i,o]=y(e);else if(e.startsWith("rgb"))[t,i,o]=A(e);else if(e.startsWith("hsl"))[t,i,o]=R(S(e));else return console.error("Unsupported color format",e),g(r);return[t,i,o]}function y(e){e.length===4&&(e=`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`);let r=parseInt(e.slice(1),16),t=(r>>16&255)/255,i=(r>>8&255)/255,o=(r&255)/255;return[t,i,o]}function A(e){let r=e.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);return r?[parseInt(r[1]??"0")/255,parseInt(r[2]??"0")/255,parseInt(r[3]??"0")/255]:[0,0,0]}function S(e){let r=e.match(/^hsl\s*\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$/i);return r?[parseInt(r[1]??"0"),parseInt(r[2]??"0"),parseInt(r[3]??"0")]:[0,0,0]}function R(e){let[r,t,i]=e,o=r/360,n=t/100,s=i/100,c,l,h;if(t===0)c=l=h=s;else{let f=(u,p,a)=>(a<0&&(a+=1),a>1&&(a-=1),a<.16666666666666666?u+(p-u)*6*a:a<.5?p:a<.6666666666666666?u+(p-u)*(.6666666666666666-a)*6:u),m=s<.5?s*(1+n):s+n-s*n,d=2*s-m;c=f(d,m,o+1/3),l=f(d,m,o),h=f(d,m,o-1/3)}return[c,l,h]}var F=`
7
8
  precision highp float;
8
9
  uniform vec2 u_resolution;
9
10
  uniform float u_time;
@@ -76,5 +77,137 @@ var p=class{canvas;gl;program=null;uniformLocations={};fragmentShader;rafId=null
76
77
 
77
78
  gl_FragColor = vec4(color, 1.0);
78
79
  }
79
- `;export{p as ShaderMount,A as getShaderColorFromString,L as grainCloudsFragmentShader};
80
+ `;var w=`
81
+ // Mesh Gradient: https://www.shadertoy.com/view/wdyczG
82
+ #define S(a,b,t) smoothstep(a,b,t)
83
+
84
+ precision highp float;
85
+
86
+ uniform vec3 u_color1;
87
+ uniform vec3 u_color2;
88
+ uniform vec3 u_color3;
89
+ uniform vec3 u_color4;
90
+ uniform vec2 u_resolution;
91
+ uniform float u_time;
92
+ uniform float u_speed;
93
+
94
+ mat2 Rot(float a)
95
+ {
96
+ float s = sin(a);
97
+ float c = cos(a);
98
+ return mat2(c, -s, s, c);
99
+ }
100
+
101
+
102
+ vec2 hash(vec2 p) {
103
+ vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
104
+ p3 += dot(p3, p3.yzx + 33.33);
105
+ return fract((p3.xx+p3.yz)*p3.zy);
106
+ }
107
+
108
+ float noise( in vec2 p )
109
+ {
110
+ vec2 i = floor( p );
111
+ vec2 f = fract( p );
112
+
113
+ vec2 u = f*f*(3.0-2.0*f);
114
+
115
+ float n = mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
116
+ dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
117
+ mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
118
+ dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
119
+ return 0.5 + 0.5*n;
120
+ }
121
+
122
+
123
+ void main() {
124
+ vec2 uv = gl_FragCoord.xy / u_resolution.xy;
125
+ float ratio = u_resolution.x / u_resolution.y;
126
+
127
+ vec2 tuv = uv;
128
+ tuv -= .5;
129
+
130
+ // rotate with Noise
131
+ float degree = noise(vec2(u_time * u_speed, tuv.x * tuv.y));
132
+
133
+ tuv.y *= 1./ratio;
134
+ tuv *= Rot(radians((degree-.5)*720.+180.));
135
+ tuv.y *= ratio;
136
+
137
+
138
+ // Wave warp with sin
139
+ float frequency = 5.;
140
+ float amplitude = 30.;
141
+ float speed = u_time * 2.;
142
+ tuv.x += sin(tuv.y*frequency+speed)/amplitude;
143
+ tuv.y += sin(tuv.x*frequency*1.5+speed)/(amplitude*.5);
144
+
145
+
146
+ // draw the image
147
+ vec3 layer1 = mix(u_color1, u_color2, S(-.3, .2, (tuv*Rot(radians(-5.))).x));
148
+ vec3 layer2 = mix(u_color3, u_color4, S(-.3, .2, (tuv*Rot(radians(-5.))).x));
149
+
150
+ vec3 finalComp = mix(layer1, layer2, S(.5, -.3, tuv.y));
151
+
152
+ vec3 col = finalComp;
153
+
154
+ gl_FragColor = vec4(col,1.0);
155
+ }
156
+ `;var C=`
157
+ precision mediump float;
158
+
159
+ uniform vec3 u_colorFront;
160
+ uniform vec3 u_colorBack;
161
+ uniform float u_scale;
162
+ uniform float u_brightness;
163
+ uniform float u_speed;
164
+
165
+ uniform float u_time;
166
+ uniform float u_ratio;
167
+ uniform vec2 u_resolution;
168
+
169
+ vec2 rotate(vec2 uv, float th) {
170
+ return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;
171
+ }
172
+
173
+ float neuro_shape(vec2 uv, float t) {
174
+ vec2 sine_acc = vec2(0.);
175
+ vec2 res = vec2(0.);
176
+ float scale = 8.;
177
+
178
+ for (int j = 0; j < 15; j++) {
179
+ uv = rotate(uv, 1.);
180
+ sine_acc = rotate(sine_acc, 1.);
181
+ vec2 layer = uv * scale + float(j) + sine_acc - t;
182
+ sine_acc += sin(layer);
183
+ res += (.5 + .5 * cos(layer)) / scale;
184
+ scale *= (1.2);
185
+ }
186
+ return res.x + res.y;
187
+ }
188
+
189
+ void main() {
190
+ vec2 uv = gl_FragCoord.xy / u_resolution.xy;
191
+ float ratio = u_resolution.x / u_resolution.y;
192
+ vec2 uv_r = uv;
193
+ uv_r -= .5;
194
+ uv_r *= u_scale;
195
+ uv_r += .5;
196
+ uv_r.x *= ratio;
197
+
198
+ float t = u_speed * u_time;
199
+ vec3 color = vec3(0.);
200
+
201
+ float noise = neuro_shape(uv_r, t);
202
+
203
+ noise = u_brightness * pow(noise, 3.);
204
+ noise += pow(noise, 10.);
205
+ noise = max(.0, noise - .5);
206
+ noise *= (1. - length(uv - .5));
207
+
208
+ color = mix(u_colorBack, u_colorFront, noise);
209
+
210
+ gl_FragColor = vec4(color, 1.);
211
+ }
212
+ `;export{v as ShaderMount,g as getShaderColorFromString,F as grainCloudsFragmentShader,w as meshGradientFragmentShader,C as neuroNoiseFragmentShader};
80
213
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/shader-mount.ts", "../src/shaders/grain-clouds.ts"],
4
- "sourcesContent": ["export class ShaderMount {\n private canvas: HTMLCanvasElement;\n private gl: WebGLRenderingContext;\n private program: WebGLProgram | null = null;\n private uniformLocations: Record<string, WebGLUniformLocation | null> = {};\n /** The fragment shader that we are using */\n private fragmentShader: string;\n /** Stores the RAF for the render loop */\n private rafId: number | null = null;\n /** Time of the last rendered frame */\n private lastFrameTime = 0;\n /** Total time that we have played any animation, passed as a uniform to the shader for time-based VFX */\n private totalAnimationTime = 0;\n /** Whether we RAF the render or not */\n private isAnimated: boolean;\n /** Uniforms that are provided by the user for the specific shader being mounted (not including uniforms that this Mount adds, like time and resolution) */\n private providedUniforms: Record<string, number | number[]>;\n /** Just a sanity check to make sure frames don't run after we're disposed */\n private hasBeenDisposed = false;\n /** If the resolution of the canvas has changed since the last render */\n private resolutionChanged = true;\n\n constructor(\n canvas: HTMLCanvasElement,\n fragmentShader: string,\n uniforms: Record<string, number | number[]> = {},\n webGlContextAttributes?: WebGLContextAttributes,\n animated = true\n ) {\n this.canvas = canvas;\n this.fragmentShader = fragmentShader;\n this.providedUniforms = uniforms;\n this.isAnimated = animated;\n\n const gl = canvas.getContext('webgl', webGlContextAttributes);\n if (!gl) {\n throw new Error('WebGL not supported');\n }\n this.gl = gl;\n\n this.initWebGL();\n this.setupResizeObserver();\n if (this.isAnimated) {\n this.startAnimating();\n } else {\n this.render(performance.now());\n }\n }\n\n private initWebGL = () => {\n const program = createProgram(\n this.gl,\n vertexShaderSource,\n this.fragmentShader\n );\n if (!program) return;\n this.program = program;\n\n this.setupPositionAttribute();\n this.setupUniforms();\n };\n\n private setupPositionAttribute = () => {\n const positionAttributeLocation = this.gl.getAttribLocation(\n this.program!,\n 'a_position'\n );\n const positionBuffer = this.gl.createBuffer();\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, positionBuffer);\n const positions = [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];\n this.gl.bufferData(\n this.gl.ARRAY_BUFFER,\n new Float32Array(positions),\n this.gl.STATIC_DRAW\n );\n this.gl.enableVertexAttribArray(positionAttributeLocation);\n this.gl.vertexAttribPointer(\n positionAttributeLocation,\n 2,\n this.gl.FLOAT,\n false,\n 0,\n 0\n );\n };\n\n private setupUniforms = () => {\n this.uniformLocations = {\n u_time: this.gl.getUniformLocation(this.program!, 'u_time'),\n u_resolution: this.gl.getUniformLocation(this.program!, 'u_resolution'),\n ...Object.fromEntries(\n Object.keys(this.providedUniforms).map((key) => [\n key,\n this.gl.getUniformLocation(this.program!, key),\n ])\n ),\n };\n };\n\n private resizeObserver: ResizeObserver | null = null;\n private setupResizeObserver = () => {\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n this.resizeObserver.observe(this.canvas);\n this.handleResize();\n };\n\n private handleResize = () => {\n const newWidth = this.canvas.clientWidth;\n const newHeight = this.canvas.clientHeight;\n if (this.canvas.width !== newWidth || this.canvas.height !== newHeight) {\n this.canvas.width = newWidth;\n this.canvas.height = newHeight;\n this.resolutionChanged = true;\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n this.render(performance.now());\n }\n };\n\n private render = (currentTime: number) => {\n if (this.hasBeenDisposed) return;\n\n const dt = currentTime - this.lastFrameTime;\n this.lastFrameTime = currentTime;\n\n if (this.isAnimated) {\n this.totalAnimationTime += dt;\n }\n\n this.gl.useProgram(this.program);\n\n // Update the time uniform\n this.gl.uniform1f(\n this.uniformLocations.u_time!,\n this.totalAnimationTime * 0.001\n );\n // If the resolution has changed, we need to update the uniform\n if (this.resolutionChanged) {\n this.gl.uniform2f(\n this.uniformLocations.u_resolution!,\n this.gl.canvas.width,\n this.gl.canvas.height\n );\n this.resolutionChanged = false;\n }\n\n this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\n // Loop if we're animating\n\n if (this.isAnimated) {\n this.requestRender();\n } else {\n this.rafId = null;\n }\n };\n\n private requestRender = () => {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n }\n this.rafId = requestAnimationFrame(this.render);\n };\n\n private updateProvidedUniforms = () => {\n this.gl.useProgram(this.program);\n Object.entries(this.providedUniforms).forEach(([key, value]) => {\n const location = this.uniformLocations[key];\n if (location) {\n if (Array.isArray(value)) {\n switch (value.length) {\n case 2:\n this.gl.uniform2fv(location, value);\n break;\n case 3:\n this.gl.uniform3fv(location, value);\n break;\n case 4:\n this.gl.uniform4fv(location, value);\n break;\n default:\n if (value.length === 9) {\n this.gl.uniformMatrix3fv(location, false, value);\n } else if (value.length === 16) {\n this.gl.uniformMatrix4fv(location, false, value);\n } else {\n console.warn(\n `Unsupported uniform array length: ${value.length}`\n );\n }\n }\n } else if (typeof value === 'number') {\n this.gl.uniform1f(location, value);\n } else if (typeof value === 'boolean') {\n this.gl.uniform1i(location, value ? 1 : 0);\n } else {\n console.warn(`Unsupported uniform type for ${key}: ${typeof value}`);\n }\n }\n });\n };\n\n /** Start the animation loop, can be called during instantiation or later by an outside source */\n public startAnimating = (): void => {\n this.isAnimated = true;\n this.lastFrameTime = performance.now();\n this.rafId = requestAnimationFrame(this.render);\n };\n\n /** Stop the animation loop */\n public stopAnimating = (): void => {\n this.isAnimated = false;\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n };\n\n /** Update the uniforms that are provided by the outside shader */\n public setUniforms = (\n newUniforms: Record<string, number | number[]>\n ): void => {\n this.providedUniforms = { ...this.providedUniforms, ...newUniforms };\n\n // If we need to allow users to add uniforms after the shader has been created, we can do that here\n // But right now we're expecting the uniform list to be predictable and static\n // this.setupUniforms();\n\n this.updateProvidedUniforms();\n this.render(performance.now());\n };\n\n /** Dispose of the shader mount, cleaning up all of the WebGL resources */\n public dispose = (): void => {\n this.hasBeenDisposed = true;\n this.stopAnimating();\n if (this.gl && this.program) {\n this.gl.deleteProgram(this.program);\n this.program = null;\n\n // Reset the WebGL context\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);\n this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);\n this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);\n\n // Clear any errors\n this.gl.getError();\n }\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n this.uniformLocations = {};\n };\n}\n\n/** Vertex shader for the shader mount */\nconst vertexShaderSource = `\n attribute vec4 a_position;\n void main() {\n gl_Position = a_position;\n }\n`;\n\nfunction createShader(\n gl: WebGLRenderingContext,\n type: number,\n source: string\n): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error(\n 'An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader)\n );\n gl.deleteShader(shader);\n return null;\n }\n\n return shader;\n}\n\nfunction createProgram(\n gl: WebGLRenderingContext,\n vertexShaderSource: string,\n fragmentShaderSource: string\n): WebGLProgram | null {\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);\n const fragmentShader = createShader(\n gl,\n gl.FRAGMENT_SHADER,\n fragmentShaderSource\n );\n\n if (!vertexShader || !fragmentShader) return null;\n\n const program = gl.createProgram();\n if (!program) return null;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error(\n 'Unable to initialize the shader program: ' +\n gl.getProgramInfoLog(program)\n );\n gl.deleteProgram(program);\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n return null;\n }\n\n // Clean up shaders after successful linking\n gl.detachShader(program, vertexShader);\n gl.detachShader(program, fragmentShader);\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n}\n\n/** Convert color string from HSL, RGB, or hex to 0-to-1-range-RGB array */\nexport function getShaderColorFromString(\n colorString: string\n): [number, number, number] {\n let r: number, g: number, b: number;\n if (colorString.startsWith('#')) {\n [r, g, b] = hexToRgb(colorString);\n } else if (colorString.startsWith('rgb')) {\n [r, g, b] = parseRgb(colorString);\n } else if (colorString.startsWith('hsl')) {\n [r, g, b] = hslToRgb(parseHsl(colorString));\n } else {\n console.error('Unsupported color format');\n return [0, 0, 0];\n }\n return [r, g, b];\n}\n\n/** Convert hex to RGB (0 to 1 range) */\nfunction hexToRgb(hex: string): [number, number, number] {\n const bigint = parseInt(hex.slice(1), 16);\n const r = ((bigint >> 16) & 255) / 255;\n const g = ((bigint >> 8) & 255) / 255;\n const b = (bigint & 255) / 255;\n return [r, g, b];\n}\n\n/** Parse RGB string to RGB (0 to 1 range) */\nfunction parseRgb(rgb: string): [number, number, number] {\n const match = rgb.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i);\n if (!match) return [0, 0, 0];\n return [\n parseInt(match[1] ?? '0') / 255,\n parseInt(match[2] ?? '0') / 255,\n parseInt(match[3] ?? '0') / 255,\n ];\n}\n\n/** Parse HSL string */\nfunction parseHsl(hsl: string): [number, number, number] {\n const match = hsl.match(/^hsl\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*\\)$/i);\n if (!match) return [0, 0, 0];\n return [\n parseInt(match[1] ?? '0'),\n parseInt(match[2] ?? '0'),\n parseInt(match[3] ?? '0'),\n ];\n}\n\n/** Convert HSL to RGB (0 to 1 range) */\nfunction hslToRgb(hsl: [number, number, number]): [number, number, number] {\n const [h, s, l] = hsl;\n const hDecimal = h / 360;\n const sDecimal = s / 100;\n const lDecimal = l / 100;\n let r, g, b;\n\n if (s === 0) {\n r = g = b = lDecimal; // achromatic\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n const q =\n lDecimal < 0.5\n ? lDecimal * (1 + sDecimal)\n : lDecimal + sDecimal - lDecimal * sDecimal;\n const p = 2 * lDecimal - q;\n r = hue2rgb(p, q, hDecimal + 1 / 3);\n g = hue2rgb(p, q, hDecimal);\n b = hue2rgb(p, q, hDecimal - 1 / 3);\n }\n\n return [r, g, b];\n}\n", "export type GrainCloudsUniforms = {\n u_color1: [number, number, number];\n u_color2: [number, number, number];\n u_noiseScale: number;\n u_noiseSpeed: number;\n u_grainAmount: number;\n};\n\n/**\n * Renders a grainy texture over top of blobby animated clouds\n * This is an example shader that we're using to bootstrap the project\n * Generated by Claude 3.5 Sonnet\n *\n * Uniforms include:\n * u_color1: The first color of the clouds\n * u_color2: The second color of the clouds\n * u_noiseScale: The scale of the noise\n * u_noiseSpeed: The speed of the noise\n * u_grainAmount: The amount of grain on the texture\n */\nexport const grainCloudsFragmentShader = `\n precision highp float;\n uniform vec2 u_resolution;\n uniform float u_time;\n uniform vec3 u_color1;\n uniform vec3 u_color2;\n uniform float u_noiseScale;\n uniform float u_noiseSpeed;\n uniform float u_grainAmount;\n\n // Simplex 2D noise\n vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }\n\n float snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),\n dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n }\n\n void main() {\n vec2 st = gl_FragCoord.xy / u_resolution.xy;\n\n // Calculate the aspect ratio of the shader\n float shaderAspect = u_resolution.x / u_resolution.y;\n\n // Define the aspect ratio of your content (e.g., 1.0 for square)\n float contentAspect = 1.0;\n\n // Adjust st to maintain content aspect ratio\n if (shaderAspect > contentAspect) {\n float scale = shaderAspect / contentAspect;\n st.x = (st.x - 0.5) * scale + 0.5;\n } else {\n float scale = contentAspect / shaderAspect;\n st.y = (st.y - 0.5) * scale + 0.5;\n }\n\n // Create blobby texture\n float n = snoise(st * u_noiseScale + u_time * u_noiseSpeed);\n n += 0.5 * snoise(st * u_noiseScale * 2.0 - u_time * u_noiseSpeed * 0.5);\n n += 0.25 * snoise(st * u_noiseScale * 4.0 + u_time * u_noiseSpeed * 0.25);\n n = n * 0.5 + 0.5;\n\n // Color interpolation\n vec3 color = mix(u_color1, u_color2, n);\n\n // Add grain\n float grain = fract(sin(dot(st * 1000.0, vec2(12.9898, 78.233))) * 43758.5453);\n color += (grain - 0.5) * u_grainAmount;\n\n gl_FragColor = vec4(color, 1.0);\n }\n`;\n"],
5
- "mappings": "AAAO,IAAMA,EAAN,KAAkB,CACf,OACA,GACA,QAA+B,KAC/B,iBAAgE,CAAC,EAEjE,eAEA,MAAuB,KAEvB,cAAgB,EAEhB,mBAAqB,EAErB,WAEA,iBAEA,gBAAkB,GAElB,kBAAoB,GAE5B,YACEC,EACAC,EACAC,EAA8C,CAAC,EAC/CC,EACAC,EAAW,GACX,CACA,KAAK,OAASJ,EACd,KAAK,eAAiBC,EACtB,KAAK,iBAAmBC,EACxB,KAAK,WAAaE,EAElB,IAAMC,EAAKL,EAAO,WAAW,QAASG,CAAsB,EAC5D,GAAI,CAACE,EACH,MAAM,IAAI,MAAM,qBAAqB,EAEvC,KAAK,GAAKA,EAEV,KAAK,UAAU,EACf,KAAK,oBAAoB,EACrB,KAAK,WACP,KAAK,eAAe,EAEpB,KAAK,OAAO,YAAY,IAAI,CAAC,CAEjC,CAEQ,UAAY,IAAM,CACxB,IAAMC,EAAUC,EACd,KAAK,GACLC,EACA,KAAK,cACP,EACKF,IACL,KAAK,QAAUA,EAEf,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACrB,EAEQ,uBAAyB,IAAM,CACrC,IAAMG,EAA4B,KAAK,GAAG,kBACxC,KAAK,QACL,YACF,EACMC,EAAiB,KAAK,GAAG,aAAa,EAC5C,KAAK,GAAG,WAAW,KAAK,GAAG,aAAcA,CAAc,EACvD,IAAMC,EAAY,CAAC,GAAI,GAAI,EAAG,GAAI,GAAI,EAAG,GAAI,EAAG,EAAG,GAAI,EAAG,CAAC,EAC3D,KAAK,GAAG,WACN,KAAK,GAAG,aACR,IAAI,aAAaA,CAAS,EAC1B,KAAK,GAAG,WACV,EACA,KAAK,GAAG,wBAAwBF,CAAyB,EACzD,KAAK,GAAG,oBACNA,EACA,EACA,KAAK,GAAG,MACR,GACA,EACA,CACF,CACF,EAEQ,cAAgB,IAAM,CAC5B,KAAK,iBAAmB,CACtB,OAAQ,KAAK,GAAG,mBAAmB,KAAK,QAAU,QAAQ,EAC1D,aAAc,KAAK,GAAG,mBAAmB,KAAK,QAAU,cAAc,EACtE,GAAG,OAAO,YACR,OAAO,KAAK,KAAK,gBAAgB,EAAE,IAAKG,GAAQ,CAC9CA,EACA,KAAK,GAAG,mBAAmB,KAAK,QAAUA,CAAG,CAC/C,CAAC,CACH,CACF,CACF,EAEQ,eAAwC,KACxC,oBAAsB,IAAM,CAClC,KAAK,eAAiB,IAAI,eAAe,IAAM,KAAK,aAAa,CAAC,EAClE,KAAK,eAAe,QAAQ,KAAK,MAAM,EACvC,KAAK,aAAa,CACpB,EAEQ,aAAe,IAAM,CAC3B,IAAMC,EAAW,KAAK,OAAO,YACvBC,EAAY,KAAK,OAAO,cAC1B,KAAK,OAAO,QAAUD,GAAY,KAAK,OAAO,SAAWC,KAC3D,KAAK,OAAO,MAAQD,EACpB,KAAK,OAAO,OAASC,EACrB,KAAK,kBAAoB,GACzB,KAAK,GAAG,SAAS,EAAG,EAAG,KAAK,GAAG,OAAO,MAAO,KAAK,GAAG,OAAO,MAAM,EAClE,KAAK,OAAO,YAAY,IAAI,CAAC,EAEjC,EAEQ,OAAUC,GAAwB,CACxC,GAAI,KAAK,gBAAiB,OAE1B,IAAMC,EAAKD,EAAc,KAAK,cAC9B,KAAK,cAAgBA,EAEjB,KAAK,aACP,KAAK,oBAAsBC,GAG7B,KAAK,GAAG,WAAW,KAAK,OAAO,EAG/B,KAAK,GAAG,UACN,KAAK,iBAAiB,OACtB,KAAK,mBAAqB,IAC5B,EAEI,KAAK,oBACP,KAAK,GAAG,UACN,KAAK,iBAAiB,aACtB,KAAK,GAAG,OAAO,MACf,KAAK,GAAG,OAAO,MACjB,EACA,KAAK,kBAAoB,IAG3B,KAAK,GAAG,WAAW,KAAK,GAAG,UAAW,EAAG,CAAC,EAItC,KAAK,WACP,KAAK,cAAc,EAEnB,KAAK,MAAQ,IAEjB,EAEQ,cAAgB,IAAM,CACxB,KAAK,QAAU,MACjB,qBAAqB,KAAK,KAAK,EAEjC,KAAK,MAAQ,sBAAsB,KAAK,MAAM,CAChD,EAEQ,uBAAyB,IAAM,CACrC,KAAK,GAAG,WAAW,KAAK,OAAO,EAC/B,OAAO,QAAQ,KAAK,gBAAgB,EAAE,QAAQ,CAAC,CAACJ,EAAKK,CAAK,IAAM,CAC9D,IAAMC,EAAW,KAAK,iBAAiBN,CAAG,EAC1C,GAAIM,EACF,GAAI,MAAM,QAAQD,CAAK,EACrB,OAAQA,EAAM,OAAQ,CACpB,IAAK,GACH,KAAK,GAAG,WAAWC,EAAUD,CAAK,EAClC,MACF,IAAK,GACH,KAAK,GAAG,WAAWC,EAAUD,CAAK,EAClC,MACF,IAAK,GACH,KAAK,GAAG,WAAWC,EAAUD,CAAK,EAClC,MACF,QACMA,EAAM,SAAW,EACnB,KAAK,GAAG,iBAAiBC,EAAU,GAAOD,CAAK,EACtCA,EAAM,SAAW,GAC1B,KAAK,GAAG,iBAAiBC,EAAU,GAAOD,CAAK,EAE/C,QAAQ,KACN,qCAAqCA,EAAM,MAAM,EACnD,CAEN,MACS,OAAOA,GAAU,SAC1B,KAAK,GAAG,UAAUC,EAAUD,CAAK,EACxB,OAAOA,GAAU,UAC1B,KAAK,GAAG,UAAUC,EAAUD,EAAQ,EAAI,CAAC,EAEzC,QAAQ,KAAK,gCAAgCL,CAAG,KAAK,OAAOK,CAAK,EAAE,CAGzE,CAAC,CACH,EAGO,eAAiB,IAAY,CAClC,KAAK,WAAa,GAClB,KAAK,cAAgB,YAAY,IAAI,EACrC,KAAK,MAAQ,sBAAsB,KAAK,MAAM,CAChD,EAGO,cAAgB,IAAY,CACjC,KAAK,WAAa,GACd,KAAK,QACP,qBAAqB,KAAK,KAAK,EAC/B,KAAK,MAAQ,KAEjB,EAGO,YACLE,GACS,CACT,KAAK,iBAAmB,CAAE,GAAG,KAAK,iBAAkB,GAAGA,CAAY,EAMnE,KAAK,uBAAuB,EAC5B,KAAK,OAAO,YAAY,IAAI,CAAC,CAC/B,EAGO,QAAU,IAAY,CAC3B,KAAK,gBAAkB,GACvB,KAAK,cAAc,EACf,KAAK,IAAM,KAAK,UAClB,KAAK,GAAG,cAAc,KAAK,OAAO,EAClC,KAAK,QAAU,KAGf,KAAK,GAAG,WAAW,KAAK,GAAG,aAAc,IAAI,EAC7C,KAAK,GAAG,WAAW,KAAK,GAAG,qBAAsB,IAAI,EACrD,KAAK,GAAG,iBAAiB,KAAK,GAAG,aAAc,IAAI,EACnD,KAAK,GAAG,gBAAgB,KAAK,GAAG,YAAa,IAAI,EAGjD,KAAK,GAAG,SAAS,GAGf,KAAK,iBACP,KAAK,eAAe,WAAW,EAC/B,KAAK,eAAiB,MAGxB,KAAK,iBAAmB,CAAC,CAC3B,CACF,EAGMX,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3B,SAASY,EACPf,EACAgB,EACAC,EACoB,CACpB,IAAMC,EAASlB,EAAG,aAAagB,CAAI,EACnC,OAAKE,GAELlB,EAAG,aAAakB,EAAQD,CAAM,EAC9BjB,EAAG,cAAckB,CAAM,EAElBlB,EAAG,mBAAmBkB,EAAQlB,EAAG,cAAc,EAQ7CkB,GAPL,QAAQ,MACN,4CAA8ClB,EAAG,iBAAiBkB,CAAM,CAC1E,EACAlB,EAAG,aAAakB,CAAM,EACf,OAVW,IActB,CAEA,SAAShB,EACPF,EACAG,EACAgB,EACqB,CACrB,IAAMC,EAAeL,EAAaf,EAAIA,EAAG,cAAeG,CAAkB,EACpEP,EAAiBmB,EACrBf,EACAA,EAAG,gBACHmB,CACF,EAEA,GAAI,CAACC,GAAgB,CAACxB,EAAgB,OAAO,KAE7C,IAAMK,EAAUD,EAAG,cAAc,EACjC,OAAKC,GAELD,EAAG,aAAaC,EAASmB,CAAY,EACrCpB,EAAG,aAAaC,EAASL,CAAc,EACvCI,EAAG,YAAYC,CAAO,EAEjBD,EAAG,oBAAoBC,EAASD,EAAG,WAAW,GAYnDA,EAAG,aAAaC,EAASmB,CAAY,EACrCpB,EAAG,aAAaC,EAASL,CAAc,EACvCI,EAAG,aAAaoB,CAAY,EAC5BpB,EAAG,aAAaJ,CAAc,EAEvBK,IAhBL,QAAQ,MACN,4CACED,EAAG,kBAAkBC,CAAO,CAChC,EACAD,EAAG,cAAcC,CAAO,EACxBD,EAAG,aAAaoB,CAAY,EAC5BpB,EAAG,aAAaJ,CAAc,EACvB,OAdY,IAwBvB,CAGO,SAASyB,EACdC,EAC0B,CAC1B,IAAIC,EAAWC,EAAWC,EAC1B,GAAIH,EAAY,WAAW,GAAG,EAC5B,CAACC,EAAGC,EAAGC,CAAC,EAAIC,EAASJ,CAAW,UACvBA,EAAY,WAAW,KAAK,EACrC,CAACC,EAAGC,EAAGC,CAAC,EAAIE,EAASL,CAAW,UACvBA,EAAY,WAAW,KAAK,EACrC,CAACC,EAAGC,EAAGC,CAAC,EAAIG,EAASC,EAASP,CAAW,CAAC,MAE1C,gBAAQ,MAAM,0BAA0B,EACjC,CAAC,EAAG,EAAG,CAAC,EAEjB,MAAO,CAACC,EAAGC,EAAGC,CAAC,CACjB,CAGA,SAASC,EAASI,EAAuC,CACvD,IAAMC,EAAS,SAASD,EAAI,MAAM,CAAC,EAAG,EAAE,EAClC,GAAMC,GAAU,GAAM,KAAO,IAC7BP,GAAMO,GAAU,EAAK,KAAO,IAC5BN,GAAKM,EAAS,KAAO,IAC3B,MAAO,CAAC,EAAGP,EAAGC,CAAC,CACjB,CAGA,SAASE,EAASK,EAAuC,CACvD,IAAMC,EAAQD,EAAI,MAAM,kDAAkD,EAC1E,OAAKC,EACE,CACL,SAASA,EAAM,CAAC,GAAK,GAAG,EAAI,IAC5B,SAASA,EAAM,CAAC,GAAK,GAAG,EAAI,IAC5B,SAASA,EAAM,CAAC,GAAK,GAAG,EAAI,GAC9B,EALmB,CAAC,EAAG,EAAG,CAAC,CAM7B,CAGA,SAASJ,EAASK,EAAuC,CACvD,IAAMD,EAAQC,EAAI,MAAM,oDAAoD,EAC5E,OAAKD,EACE,CACL,SAASA,EAAM,CAAC,GAAK,GAAG,EACxB,SAASA,EAAM,CAAC,GAAK,GAAG,EACxB,SAASA,EAAM,CAAC,GAAK,GAAG,CAC1B,EALmB,CAAC,EAAG,EAAG,CAAC,CAM7B,CAGA,SAASL,EAASM,EAAyD,CACzE,GAAM,CAACC,EAAGC,EAAGC,CAAC,EAAIH,EACZI,EAAWH,EAAI,IACfI,EAAWH,EAAI,IACfI,EAAWH,EAAI,IACjBd,EAAGC,EAAGC,EAEV,GAAIW,IAAM,EACRb,EAAIC,EAAIC,EAAIe,MACP,CACL,IAAMC,EAAU,CAACC,EAAWC,EAAWC,KACjCA,EAAI,IAAGA,GAAK,GACZA,EAAI,IAAGA,GAAK,GACZA,EAAI,mBAAcF,GAAKC,EAAID,GAAK,EAAIE,EACpCA,EAAI,GAAcD,EAClBC,EAAI,kBAAcF,GAAKC,EAAID,IAAM,kBAAQE,GAAK,EAC3CF,GAGHC,EACJH,EAAW,GACPA,GAAY,EAAID,GAChBC,EAAWD,EAAWC,EAAWD,EACjCG,EAAI,EAAIF,EAAWG,EACzBpB,EAAIkB,EAAQC,EAAGC,EAAGL,EAAW,EAAI,CAAC,EAClCd,EAAIiB,EAAQC,EAAGC,EAAGL,CAAQ,EAC1Bb,EAAIgB,EAAQC,EAAGC,EAAGL,EAAW,EAAI,CAAC,CACpC,CAEA,MAAO,CAACf,EAAGC,EAAGC,CAAC,CACjB,CCrYO,IAAMoB,EAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
- "names": ["ShaderMount", "canvas", "fragmentShader", "uniforms", "webGlContextAttributes", "animated", "gl", "program", "createProgram", "vertexShaderSource", "positionAttributeLocation", "positionBuffer", "positions", "key", "newWidth", "newHeight", "currentTime", "dt", "value", "location", "newUniforms", "createShader", "type", "source", "shader", "fragmentShaderSource", "vertexShader", "getShaderColorFromString", "colorString", "r", "g", "b", "hexToRgb", "parseRgb", "hslToRgb", "parseHsl", "hex", "bigint", "rgb", "match", "hsl", "h", "s", "l", "hDecimal", "sDecimal", "lDecimal", "hue2rgb", "p", "q", "t", "grainCloudsFragmentShader"]
3
+ "sources": ["../src/shader-mount.ts", "../src/shaders/grain-clouds.ts", "../src/shaders/mesh-gradient.ts", "../src/shaders/neuro-noise.ts"],
4
+ "sourcesContent": ["export class ShaderMount {\n private canvas: HTMLCanvasElement;\n private gl: WebGLRenderingContext;\n private program: WebGLProgram | null = null;\n private uniformLocations: Record<string, WebGLUniformLocation | null> = {};\n /** The fragment shader that we are using */\n private fragmentShader: string;\n /** Stores the RAF for the render loop */\n private rafId: number | null = null;\n /** Time of the last rendered frame */\n private lastFrameTime = 0;\n /** Total time that we have played any animation, passed as a uniform to the shader for time-based VFX */\n private totalAnimationTime = 0;\n /** Whether we RAF the render or not */\n private isAnimated: boolean;\n /** Uniforms that are provided by the user for the specific shader being mounted (not including uniforms that this Mount adds, like time and resolution) */\n private providedUniforms: Record<string, number | number[]>;\n /** Just a sanity check to make sure frames don't run after we're disposed */\n private hasBeenDisposed = false;\n /** If the resolution of the canvas has changed since the last render */\n private resolutionChanged = true;\n\n constructor(\n canvas: HTMLCanvasElement,\n fragmentShader: string,\n uniforms: Record<string, number | number[]> = {},\n webGlContextAttributes?: WebGLContextAttributes,\n animated = true\n ) {\n this.canvas = canvas;\n this.fragmentShader = fragmentShader;\n this.providedUniforms = uniforms;\n this.isAnimated = animated;\n\n const gl = canvas.getContext('webgl', webGlContextAttributes);\n if (!gl) {\n throw new Error('WebGL not supported');\n }\n this.gl = gl;\n\n this.initWebGL();\n this.setupResizeObserver();\n if (this.isAnimated) {\n this.startAnimating();\n } else {\n this.render(performance.now());\n }\n }\n\n private initWebGL = () => {\n const program = createProgram(this.gl, vertexShaderSource, this.fragmentShader);\n if (!program) return;\n this.program = program;\n\n this.setupPositionAttribute();\n this.setupUniforms();\n };\n\n private setupPositionAttribute = () => {\n const positionAttributeLocation = this.gl.getAttribLocation(this.program!, 'a_position');\n const positionBuffer = this.gl.createBuffer();\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, positionBuffer);\n const positions = [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];\n this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(positions), this.gl.STATIC_DRAW);\n this.gl.enableVertexAttribArray(positionAttributeLocation);\n this.gl.vertexAttribPointer(positionAttributeLocation, 2, this.gl.FLOAT, false, 0, 0);\n };\n\n private setupUniforms = () => {\n this.uniformLocations = {\n u_time: this.gl.getUniformLocation(this.program!, 'u_time'),\n u_resolution: this.gl.getUniformLocation(this.program!, 'u_resolution'),\n ...Object.fromEntries(\n Object.keys(this.providedUniforms).map((key) => [key, this.gl.getUniformLocation(this.program!, key)])\n ),\n };\n };\n\n private resizeObserver: ResizeObserver | null = null;\n private setupResizeObserver = () => {\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n this.resizeObserver.observe(this.canvas);\n this.handleResize();\n };\n\n private handleResize = () => {\n const newWidth = this.canvas.clientWidth;\n const newHeight = this.canvas.clientHeight;\n if (this.canvas.width !== newWidth || this.canvas.height !== newHeight) {\n this.canvas.width = newWidth;\n this.canvas.height = newHeight;\n this.resolutionChanged = true;\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n this.render(performance.now());\n }\n };\n\n private render = (currentTime: number) => {\n if (this.hasBeenDisposed) return;\n\n const dt = currentTime - this.lastFrameTime;\n this.lastFrameTime = currentTime;\n\n if (this.isAnimated) {\n this.totalAnimationTime += dt;\n }\n\n this.gl.useProgram(this.program);\n\n // Update the time uniform\n this.gl.uniform1f(this.uniformLocations.u_time!, this.totalAnimationTime * 0.001);\n // If the resolution has changed, we need to update the uniform\n if (this.resolutionChanged) {\n this.gl.uniform2f(this.uniformLocations.u_resolution!, this.gl.canvas.width, this.gl.canvas.height);\n this.resolutionChanged = false;\n }\n\n this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\n // Loop if we're animating\n\n if (this.isAnimated) {\n this.requestRender();\n } else {\n this.rafId = null;\n }\n };\n\n private requestRender = () => {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n }\n this.rafId = requestAnimationFrame(this.render);\n };\n\n private updateProvidedUniforms = () => {\n this.gl.useProgram(this.program);\n Object.entries(this.providedUniforms).forEach(([key, value]) => {\n const location = this.uniformLocations[key];\n if (location) {\n if (Array.isArray(value)) {\n switch (value.length) {\n case 2:\n this.gl.uniform2fv(location, value);\n break;\n case 3:\n this.gl.uniform3fv(location, value);\n break;\n case 4:\n this.gl.uniform4fv(location, value);\n break;\n default:\n if (value.length === 9) {\n this.gl.uniformMatrix3fv(location, false, value);\n } else if (value.length === 16) {\n this.gl.uniformMatrix4fv(location, false, value);\n } else {\n console.warn(`Unsupported uniform array length: ${value.length}`);\n }\n }\n } else if (typeof value === 'number') {\n this.gl.uniform1f(location, value);\n } else if (typeof value === 'boolean') {\n this.gl.uniform1i(location, value ? 1 : 0);\n } else {\n console.warn(`Unsupported uniform type for ${key}: ${typeof value}`);\n }\n }\n });\n };\n\n /** Start the animation loop, can be called during instantiation or later by an outside source */\n public startAnimating = (): void => {\n this.isAnimated = true;\n this.lastFrameTime = performance.now();\n this.rafId = requestAnimationFrame(this.render);\n };\n\n /** Stop the animation loop */\n public stopAnimating = (): void => {\n this.isAnimated = false;\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n };\n\n /** Update the uniforms that are provided by the outside shader */\n public setUniforms = (newUniforms: Record<string, number | number[]>): void => {\n this.providedUniforms = { ...this.providedUniforms, ...newUniforms };\n\n // If we need to allow users to add uniforms after the shader has been created, we can do that here\n // But right now we're expecting the uniform list to be predictable and static\n // this.setupUniforms();\n\n this.updateProvidedUniforms();\n this.render(performance.now());\n };\n\n /** Dispose of the shader mount, cleaning up all of the WebGL resources */\n public dispose = (): void => {\n this.hasBeenDisposed = true;\n this.stopAnimating();\n if (this.gl && this.program) {\n this.gl.deleteProgram(this.program);\n this.program = null;\n\n // Reset the WebGL context\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);\n this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);\n this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);\n\n // Clear any errors\n this.gl.getError();\n }\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n this.uniformLocations = {};\n };\n}\n\n/** Vertex shader for the shader mount */\nconst vertexShaderSource = `\n attribute vec4 a_position;\n void main() {\n gl_Position = a_position;\n }\n`;\n\nfunction createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n\n return shader;\n}\n\nfunction createProgram(\n gl: WebGLRenderingContext,\n vertexShaderSource: string,\n fragmentShaderSource: string\n): WebGLProgram | null {\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);\n const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);\n\n if (!vertexShader || !fragmentShader) return null;\n\n const program = gl.createProgram();\n if (!program) return null;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program));\n gl.deleteProgram(program);\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n return null;\n }\n\n // Clean up shaders after successful linking\n gl.detachShader(program, vertexShader);\n gl.detachShader(program, fragmentShader);\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n}\n\n/** Convert color string from HSL, RGB, or hex to 0-to-1-range-RGB array */\nexport function getShaderColorFromString(\n colorString: string | [number, number, number] | undefined,\n fallback: string | [number, number, number] = [0, 0, 0]\n): [number, number, number] {\n // If the color string is already an array of 3 numbers, return it\n // Allowing this pass-through is useful for creating default objects in TypeScript with either syntax\n if (Array.isArray(colorString) && colorString.length === 3) {\n return colorString;\n }\n\n // If the color string is not a string, return the fallback\n if (typeof colorString !== 'string') {\n // Return the fallback color, processed, with no additional fallback argument\n // It'll default to [0, 0, 0] if not parseable\n return getShaderColorFromString(fallback);\n }\n\n let r: number, g: number, b: number;\n if (colorString.startsWith('#')) {\n [r, g, b] = hexToRgb(colorString);\n } else if (colorString.startsWith('rgb')) {\n [r, g, b] = parseRgb(colorString);\n } else if (colorString.startsWith('hsl')) {\n [r, g, b] = hslToRgb(parseHsl(colorString));\n } else {\n console.error('Unsupported color format', colorString);\n // Return the fallback color, processed, with no additional fallback argument\n // It'll default to [0, 0, 0] if not parseable\n return getShaderColorFromString(fallback);\n }\n return [r, g, b];\n}\n\n/** Convert hex to RGB (0 to 1 range) */\nfunction hexToRgb(hex: string): [number, number, number] {\n // Expand three-letter hex to six-letter\n if (hex.length === 4) {\n hex = `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`;\n }\n const bigint = parseInt(hex.slice(1), 16);\n const r = ((bigint >> 16) & 255) / 255;\n const g = ((bigint >> 8) & 255) / 255;\n const b = (bigint & 255) / 255;\n return [r, g, b];\n}\n\n/** Parse RGB string to RGB (0 to 1 range) */\nfunction parseRgb(rgb: string): [number, number, number] {\n const match = rgb.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i);\n if (!match) return [0, 0, 0];\n return [parseInt(match[1] ?? '0') / 255, parseInt(match[2] ?? '0') / 255, parseInt(match[3] ?? '0') / 255];\n}\n\n/** Parse HSL string */\nfunction parseHsl(hsl: string): [number, number, number] {\n const match = hsl.match(/^hsl\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*\\)$/i);\n if (!match) return [0, 0, 0];\n return [parseInt(match[1] ?? '0'), parseInt(match[2] ?? '0'), parseInt(match[3] ?? '0')];\n}\n\n/** Convert HSL to RGB (0 to 1 range) */\nfunction hslToRgb(hsl: [number, number, number]): [number, number, number] {\n const [h, s, l] = hsl;\n const hDecimal = h / 360;\n const sDecimal = s / 100;\n const lDecimal = l / 100;\n let r, g, b;\n\n if (s === 0) {\n r = g = b = lDecimal; // achromatic\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n const q = lDecimal < 0.5 ? lDecimal * (1 + sDecimal) : lDecimal + sDecimal - lDecimal * sDecimal;\n const p = 2 * lDecimal - q;\n r = hue2rgb(p, q, hDecimal + 1 / 3);\n g = hue2rgb(p, q, hDecimal);\n b = hue2rgb(p, q, hDecimal - 1 / 3);\n }\n\n return [r, g, b];\n}\n", "export type GrainCloudsUniforms = {\n u_color1: [number, number, number];\n u_color2: [number, number, number];\n u_noiseScale: number;\n u_noiseSpeed: number;\n u_grainAmount: number;\n};\n\n/**\n * Renders a grainy texture over top of blobby animated clouds\n * This is an example shader that we're using to bootstrap the project\n * Generated by Claude 3.5 Sonnet\n *\n * Uniforms include:\n * u_color1: The first color of the clouds\n * u_color2: The second color of the clouds\n * u_noiseScale: The scale of the noise\n * u_noiseSpeed: The speed of the noise\n * u_grainAmount: The amount of grain on the texture\n */\nexport const grainCloudsFragmentShader = `\n precision highp float;\n uniform vec2 u_resolution;\n uniform float u_time;\n uniform vec3 u_color1;\n uniform vec3 u_color2;\n uniform float u_noiseScale;\n uniform float u_noiseSpeed;\n uniform float u_grainAmount;\n\n // Simplex 2D noise\n vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }\n\n float snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),\n dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n }\n\n void main() {\n vec2 st = gl_FragCoord.xy / u_resolution.xy;\n\n // Calculate the aspect ratio of the shader\n float shaderAspect = u_resolution.x / u_resolution.y;\n\n // Define the aspect ratio of your content (e.g., 1.0 for square)\n float contentAspect = 1.0;\n\n // Adjust st to maintain content aspect ratio\n if (shaderAspect > contentAspect) {\n float scale = shaderAspect / contentAspect;\n st.x = (st.x - 0.5) * scale + 0.5;\n } else {\n float scale = contentAspect / shaderAspect;\n st.y = (st.y - 0.5) * scale + 0.5;\n }\n\n // Create blobby texture\n float n = snoise(st * u_noiseScale + u_time * u_noiseSpeed);\n n += 0.5 * snoise(st * u_noiseScale * 2.0 - u_time * u_noiseSpeed * 0.5);\n n += 0.25 * snoise(st * u_noiseScale * 4.0 + u_time * u_noiseSpeed * 0.25);\n n = n * 0.5 + 0.5;\n\n // Color interpolation\n vec3 color = mix(u_color1, u_color2, n);\n\n // Add grain\n float grain = fract(sin(dot(st * 1000.0, vec2(12.9898, 78.233))) * 43758.5453);\n color += (grain - 0.5) * u_grainAmount;\n\n gl_FragColor = vec4(color, 1.0);\n }\n`;\n", "import { getShaderColorFromString } from '../shader-mount';\n\nexport type MeshGradientUniforms = {\n u_color1: [number, number, number];\n u_color2: [number, number, number];\n u_color3: [number, number, number];\n u_color4: [number, number, number];\n u_speed: number;\n};\n\n/**\n * Mesh Gradient, based on https://www.shadertoy.com/view/wdyczG\n * Renders a mesh gradient with a rotating noise pattern\n * and several layers of fractal noise\n *\n * Uniforms include:\n * u_color1: The first color of the mesh gradient\n * u_color2: The second color of the mesh gradient\n * u_color3: The third color of the mesh gradient\n * u_color4: The fourth color of the mesh gradient\n * u_speed: The speed of the noise\n */\n\nexport const meshGradientFragmentShader = `\n// Mesh Gradient: https://www.shadertoy.com/view/wdyczG\n#define S(a,b,t) smoothstep(a,b,t)\n\nprecision highp float;\n\nuniform vec3 u_color1;\nuniform vec3 u_color2;\nuniform vec3 u_color3;\nuniform vec3 u_color4;\nuniform vec2 u_resolution;\nuniform float u_time;\nuniform float u_speed;\n\nmat2 Rot(float a)\n{\n float s = sin(a);\n float c = cos(a);\n return mat2(c, -s, s, c);\n}\n\n\nvec2 hash(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.xx+p3.yz)*p3.zy);\n}\n\nfloat noise( in vec2 p )\n{\n vec2 i = floor( p );\n vec2 f = fract( p );\n\n\tvec2 u = f*f*(3.0-2.0*f);\n\n float n = mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),\n dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),\n mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),\n dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);\n\treturn 0.5 + 0.5*n;\n}\n\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_resolution.xy;\n float ratio = u_resolution.x / u_resolution.y;\n\n vec2 tuv = uv;\n tuv -= .5;\n\n // rotate with Noise\n float degree = noise(vec2(u_time * u_speed, tuv.x * tuv.y));\n\n tuv.y *= 1./ratio;\n tuv *= Rot(radians((degree-.5)*720.+180.));\n\ttuv.y *= ratio;\n\n\n // Wave warp with sin\n float frequency = 5.;\n float amplitude = 30.;\n float speed = u_time * 2.;\n tuv.x += sin(tuv.y*frequency+speed)/amplitude;\n \ttuv.y += sin(tuv.x*frequency*1.5+speed)/(amplitude*.5);\n\n\n // draw the image\n vec3 layer1 = mix(u_color1, u_color2, S(-.3, .2, (tuv*Rot(radians(-5.))).x));\n vec3 layer2 = mix(u_color3, u_color4, S(-.3, .2, (tuv*Rot(radians(-5.))).x));\n\n vec3 finalComp = mix(layer1, layer2, S(.5, -.3, tuv.y));\n\n vec3 col = finalComp;\n\n gl_FragColor = vec4(col,1.0);\n}\n`;\n", "export type NeuroNoiseUniforms = {\n u_colorFront: [number, number, number];\n u_colorBack: [number, number, number];\n u_scale: number;\n u_brightness: number;\n u_speed: number;\n};\n\n/**\n * Neuro Noise Pattern;\n * The original artwork: https://codepen.io/ksenia-k/full/vYwgrWv by Ksenia Kondrashova\n * Renders a fractal-like structure made of several layers of since-arches\n *\n * Uniforms include:\n * u_colorFront: The front color of pattern\n * u_colorBack: The back color of pattern\n * u_brightness: The power/brightness of pattern lines\n * u_scale: The scale applied to coordinates\n * u_speed: The speed coefficient for pattern animation\n */\n\nexport const neuroNoiseFragmentShader = `\nprecision mediump float;\n\nuniform vec3 u_colorFront;\nuniform vec3 u_colorBack;\nuniform float u_scale;\nuniform float u_brightness;\nuniform float u_speed;\n\nuniform float u_time;\nuniform float u_ratio;\nuniform vec2 u_resolution;\n\nvec2 rotate(vec2 uv, float th) {\n return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;\n}\n\nfloat neuro_shape(vec2 uv, float t) {\n vec2 sine_acc = vec2(0.);\n vec2 res = vec2(0.);\n float scale = 8.;\n\n for (int j = 0; j < 15; j++) {\n uv = rotate(uv, 1.);\n sine_acc = rotate(sine_acc, 1.);\n vec2 layer = uv * scale + float(j) + sine_acc - t;\n sine_acc += sin(layer);\n res += (.5 + .5 * cos(layer)) / scale;\n scale *= (1.2);\n }\n return res.x + res.y;\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_resolution.xy;\n float ratio = u_resolution.x / u_resolution.y;\n vec2 uv_r = uv;\n uv_r -= .5;\n uv_r *= u_scale;\n uv_r += .5;\n uv_r.x *= ratio;\n\n float t = u_speed * u_time;\n vec3 color = vec3(0.);\n\n float noise = neuro_shape(uv_r, t);\n\n noise = u_brightness * pow(noise, 3.);\n noise += pow(noise, 10.);\n noise = max(.0, noise - .5);\n noise *= (1. - length(uv - .5));\n\n color = mix(u_colorBack, u_colorFront, noise);\n\n gl_FragColor = vec4(color, 1.);\n}\n`;\n"],
5
+ "mappings": "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",
6
+ "names": ["ShaderMount", "canvas", "fragmentShader", "uniforms", "webGlContextAttributes", "animated", "gl", "program", "createProgram", "vertexShaderSource", "positionAttributeLocation", "positionBuffer", "positions", "key", "newWidth", "newHeight", "currentTime", "dt", "value", "location", "newUniforms", "createShader", "type", "source", "shader", "fragmentShaderSource", "vertexShader", "getShaderColorFromString", "colorString", "fallback", "r", "g", "b", "hexToRgb", "parseRgb", "hslToRgb", "parseHsl", "hex", "bigint", "rgb", "match", "hsl", "h", "s", "l", "hDecimal", "sDecimal", "lDecimal", "hue2rgb", "p", "q", "t", "grainCloudsFragmentShader", "meshGradientFragmentShader", "neuroNoiseFragmentShader"]
7
7
  }
@@ -39,4 +39,4 @@ export declare class ShaderMount {
39
39
  dispose: () => void;
40
40
  }
41
41
  /** Convert color string from HSL, RGB, or hex to 0-to-1-range-RGB array */
42
- export declare function getShaderColorFromString(colorString: string): [number, number, number];
42
+ export declare function getShaderColorFromString(colorString: string | [number, number, number] | undefined, fallback?: string | [number, number, number]): [number, number, number];
@@ -0,0 +1,20 @@
1
+ export type MeshGradientUniforms = {
2
+ u_color1: [number, number, number];
3
+ u_color2: [number, number, number];
4
+ u_color3: [number, number, number];
5
+ u_color4: [number, number, number];
6
+ u_speed: number;
7
+ };
8
+ /**
9
+ * Mesh Gradient, based on https://www.shadertoy.com/view/wdyczG
10
+ * Renders a mesh gradient with a rotating noise pattern
11
+ * and several layers of fractal noise
12
+ *
13
+ * Uniforms include:
14
+ * u_color1: The first color of the mesh gradient
15
+ * u_color2: The second color of the mesh gradient
16
+ * u_color3: The third color of the mesh gradient
17
+ * u_color4: The fourth color of the mesh gradient
18
+ * u_speed: The speed of the noise
19
+ */
20
+ export declare const meshGradientFragmentShader = "\n// Mesh Gradient: https://www.shadertoy.com/view/wdyczG\n#define S(a,b,t) smoothstep(a,b,t)\n\nprecision highp float;\n\nuniform vec3 u_color1;\nuniform vec3 u_color2;\nuniform vec3 u_color3;\nuniform vec3 u_color4;\nuniform vec2 u_resolution;\nuniform float u_time;\nuniform float u_speed;\n\nmat2 Rot(float a)\n{\n float s = sin(a);\n float c = cos(a);\n return mat2(c, -s, s, c);\n}\n\n\nvec2 hash(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.xx+p3.yz)*p3.zy);\n}\n\nfloat noise( in vec2 p )\n{\n vec2 i = floor( p );\n vec2 f = fract( p );\n\n\tvec2 u = f*f*(3.0-2.0*f);\n\n float n = mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),\n dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),\n mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),\n dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);\n\treturn 0.5 + 0.5*n;\n}\n\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_resolution.xy;\n float ratio = u_resolution.x / u_resolution.y;\n\n vec2 tuv = uv;\n tuv -= .5;\n\n // rotate with Noise\n float degree = noise(vec2(u_time * u_speed, tuv.x * tuv.y));\n\n tuv.y *= 1./ratio;\n tuv *= Rot(radians((degree-.5)*720.+180.));\n\ttuv.y *= ratio;\n\n\n // Wave warp with sin\n float frequency = 5.;\n float amplitude = 30.;\n float speed = u_time * 2.;\n tuv.x += sin(tuv.y*frequency+speed)/amplitude;\n \ttuv.y += sin(tuv.x*frequency*1.5+speed)/(amplitude*.5);\n\n\n // draw the image\n vec3 layer1 = mix(u_color1, u_color2, S(-.3, .2, (tuv*Rot(radians(-5.))).x));\n vec3 layer2 = mix(u_color3, u_color4, S(-.3, .2, (tuv*Rot(radians(-5.))).x));\n\n vec3 finalComp = mix(layer1, layer2, S(.5, -.3, tuv.y));\n\n vec3 col = finalComp;\n\n gl_FragColor = vec4(col,1.0);\n}\n";
@@ -0,0 +1,20 @@
1
+ export type NeuroNoiseUniforms = {
2
+ u_colorFront: [number, number, number];
3
+ u_colorBack: [number, number, number];
4
+ u_scale: number;
5
+ u_brightness: number;
6
+ u_speed: number;
7
+ };
8
+ /**
9
+ * Neuro Noise Pattern;
10
+ * The original artwork: https://codepen.io/ksenia-k/full/vYwgrWv by Ksenia Kondrashova
11
+ * Renders a fractal-like structure made of several layers of since-arches
12
+ *
13
+ * Uniforms include:
14
+ * u_colorFront: The front color of pattern
15
+ * u_colorBack: The back color of pattern
16
+ * u_brightness: The power/brightness of pattern lines
17
+ * u_scale: The scale applied to coordinates
18
+ * u_speed: The speed coefficient for pattern animation
19
+ */
20
+ export declare const neuroNoiseFragmentShader = "\nprecision mediump float;\n\nuniform vec3 u_colorFront;\nuniform vec3 u_colorBack;\nuniform float u_scale;\nuniform float u_brightness;\nuniform float u_speed;\n\nuniform float u_time;\nuniform float u_ratio;\nuniform vec2 u_resolution;\n\nvec2 rotate(vec2 uv, float th) {\n return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;\n}\n\nfloat neuro_shape(vec2 uv, float t) {\n vec2 sine_acc = vec2(0.);\n vec2 res = vec2(0.);\n float scale = 8.;\n\n for (int j = 0; j < 15; j++) {\n uv = rotate(uv, 1.);\n sine_acc = rotate(sine_acc, 1.);\n vec2 layer = uv * scale + float(j) + sine_acc - t;\n sine_acc += sin(layer);\n res += (.5 + .5 * cos(layer)) / scale;\n scale *= (1.2);\n }\n return res.x + res.y;\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_resolution.xy;\n float ratio = u_resolution.x / u_resolution.y;\n vec2 uv_r = uv;\n uv_r -= .5;\n uv_r *= u_scale;\n uv_r += .5;\n uv_r.x *= ratio;\n\n float t = u_speed * u_time;\n vec3 color = vec3(0.);\n\n float noise = neuro_shape(uv_r, t);\n\n noise = u_brightness * pow(noise, 3.);\n noise += pow(noise, 10.);\n noise = max(.0, noise - .5);\n noise *= (1. - length(uv - .5));\n\n color = mix(u_colorBack, u_colorFront, noise);\n\n gl_FragColor = vec4(color, 1.);\n}\n";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paper-design/shaders",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -12,6 +12,7 @@
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
15
16
  "default": "./dist/index.js"
16
17
  }
17
18
  },