@fjandin/react-shader 0.0.11 → 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.
@@ -1,3 +1,3 @@
1
1
  import type { ReactShaderProps } from "./types";
2
- export declare function ReactShader({ className, fragment, vertex, uniforms, fullscreen, timeScale, onFrame, onClick, onMouseMove, }: ReactShaderProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function ReactShader({ className, fragment, vertex, uniforms, fullscreen, timeScale, onFrame, onClick, onMouseMove, onMouseDown, onMouseUp, }: ReactShaderProps): import("react/jsx-runtime").JSX.Element;
3
3
  //# sourceMappingURL=ReactShader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactShader.d.ts","sourceRoot":"","sources":["../src/ReactShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAgC/C,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,EACR,MAAuB,EACvB,QAAQ,EACR,UAAkB,EAClB,SAAa,EACb,OAAO,EACP,OAAO,EACP,WAAW,GACZ,EAAE,gBAAgB,2CAuDlB"}
1
+ {"version":3,"file":"ReactShader.d.ts","sourceRoot":"","sources":["../src/ReactShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAgC/C,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,EACR,MAAuB,EACvB,QAAQ,EACR,UAAkB,EAClB,SAAa,EACb,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,GACV,EAAE,gBAAgB,2CAyDlB"}
@@ -1 +1 @@
1
- {"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AAwBpB,wBAAgB,GAAG,4CAwFlB"}
1
+ {"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AAiHpB,wBAAgB,GAAG,4CAgGlB"}
@@ -0,0 +1,2 @@
1
+ export declare const textureFragment: string;
2
+ //# sourceMappingURL=texture-demo.glsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"texture-demo.glsl.d.ts","sourceRoot":"","sources":["../../../src/example/glsl/texture-demo.glsl.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,QAsC3B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useWebGL.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGL.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAIvD,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EAyRhD"}
1
+ {"version":3,"file":"useWebGL.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGL.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAKvD,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EAyRhD"}
package/dist/index.cjs CHANGED
@@ -88,6 +88,147 @@ function createShaderProgram(gl, vertexSource, fragmentSource) {
88
88
  }
89
89
  }
90
90
 
91
+ // src/utils/textures.ts
92
+ function isTextureSource(value) {
93
+ if (typeof window === "undefined")
94
+ return false;
95
+ return value instanceof HTMLImageElement || value instanceof HTMLCanvasElement || value instanceof HTMLVideoElement || typeof ImageBitmap !== "undefined" && value instanceof ImageBitmap || value instanceof ImageData || typeof OffscreenCanvas !== "undefined" && value instanceof OffscreenCanvas;
96
+ }
97
+ function isTextureOptions(value) {
98
+ return typeof value === "object" && value !== null && "source" in value && isTextureSource(value.source);
99
+ }
100
+ function isTexture(value) {
101
+ return isTextureSource(value) || isTextureOptions(value);
102
+ }
103
+ function getWrapMode(gl, wrap) {
104
+ switch (wrap) {
105
+ case "repeat":
106
+ return gl.REPEAT;
107
+ case "mirror":
108
+ return gl.MIRRORED_REPEAT;
109
+ default:
110
+ return gl.CLAMP_TO_EDGE;
111
+ }
112
+ }
113
+ function getMinFilter(gl, filter) {
114
+ switch (filter) {
115
+ case "nearest":
116
+ return gl.NEAREST;
117
+ case "mipmap":
118
+ return gl.LINEAR_MIPMAP_LINEAR;
119
+ default:
120
+ return gl.LINEAR;
121
+ }
122
+ }
123
+ function getMagFilter(gl, filter) {
124
+ switch (filter) {
125
+ case "nearest":
126
+ return gl.NEAREST;
127
+ default:
128
+ return gl.LINEAR;
129
+ }
130
+ }
131
+ function isPowerOfTwo(value) {
132
+ return (value & value - 1) === 0 && value !== 0;
133
+ }
134
+ function getSourceDimensions(source) {
135
+ if (source instanceof HTMLImageElement) {
136
+ return { width: source.naturalWidth, height: source.naturalHeight };
137
+ }
138
+ if (source instanceof HTMLVideoElement) {
139
+ return { width: source.videoWidth, height: source.videoHeight };
140
+ }
141
+ if (source instanceof ImageData) {
142
+ return { width: source.width, height: source.height };
143
+ }
144
+ return { width: source.width, height: source.height };
145
+ }
146
+ function createTextureManager(gl) {
147
+ const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
148
+ return {
149
+ cache: new Map,
150
+ nextUnit: 0,
151
+ maxUnits
152
+ };
153
+ }
154
+ function createTexture(gl, source, options = {}) {
155
+ const texture = gl.createTexture();
156
+ if (!texture) {
157
+ throw new Error("Failed to create WebGL texture");
158
+ }
159
+ const { wrapS = "clamp", wrapT = "clamp", minFilter = "linear", magFilter = "linear", flipY = true } = options;
160
+ gl.bindTexture(gl.TEXTURE_2D, texture);
161
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
162
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
163
+ const { width, height } = getSourceDimensions(source);
164
+ const pot = isPowerOfTwo(width) && isPowerOfTwo(height);
165
+ const isWebGL2 = "texStorage2D" in gl;
166
+ const actualMinFilter = minFilter === "mipmap" && (pot || isWebGL2) ? minFilter : minFilter === "mipmap" ? "linear" : minFilter;
167
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, getWrapMode(gl, wrapS));
168
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, getWrapMode(gl, wrapT));
169
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, getMinFilter(gl, actualMinFilter));
170
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, getMagFilter(gl, magFilter));
171
+ if (actualMinFilter === "mipmap") {
172
+ gl.generateMipmap(gl.TEXTURE_2D);
173
+ }
174
+ gl.bindTexture(gl.TEXTURE_2D, null);
175
+ return texture;
176
+ }
177
+ function updateTexture(gl, texture, source, flipY = true) {
178
+ gl.bindTexture(gl.TEXTURE_2D, texture);
179
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
180
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
181
+ gl.bindTexture(gl.TEXTURE_2D, null);
182
+ }
183
+ function needsVideoUpdate(source) {
184
+ if (!(source instanceof HTMLVideoElement))
185
+ return false;
186
+ return !source.paused && !source.ended && source.readyState >= 2;
187
+ }
188
+ function bindTextureUniform(gl, program, name, value, manager, locationCache) {
189
+ const source = isTextureOptions(value) ? value.source : value;
190
+ const options = isTextureOptions(value) ? value : {};
191
+ let entry = manager.cache.get(name);
192
+ if (entry && entry.source !== source) {
193
+ gl.deleteTexture(entry.texture);
194
+ entry = undefined;
195
+ }
196
+ if (!entry) {
197
+ if (manager.nextUnit >= manager.maxUnits) {
198
+ console.warn(`Maximum texture units (${manager.maxUnits}) exceeded for uniform "${name}"`);
199
+ return;
200
+ }
201
+ const texture = createTexture(gl, source, options);
202
+ entry = {
203
+ texture,
204
+ unit: manager.nextUnit++,
205
+ source
206
+ };
207
+ manager.cache.set(name, entry);
208
+ }
209
+ if (needsVideoUpdate(source)) {
210
+ const flipY = isTextureOptions(value) ? value.flipY ?? true : true;
211
+ updateTexture(gl, entry.texture, source, flipY);
212
+ }
213
+ gl.activeTexture(gl.TEXTURE0 + entry.unit);
214
+ gl.bindTexture(gl.TEXTURE_2D, entry.texture);
215
+ let location = locationCache.get(name);
216
+ if (location === undefined) {
217
+ location = gl.getUniformLocation(program, name);
218
+ locationCache.set(name, location);
219
+ }
220
+ if (location !== null) {
221
+ gl.uniform1i(location, entry.unit);
222
+ }
223
+ }
224
+ function cleanupTextures(gl, manager) {
225
+ for (const entry of manager.cache.values()) {
226
+ gl.deleteTexture(entry.texture);
227
+ }
228
+ manager.cache.clear();
229
+ manager.nextUnit = 0;
230
+ }
231
+
91
232
  // src/utils/uniforms.ts
92
233
  var MAX_ARRAY_LENGTH = 100;
93
234
  function isVec2(value) {
@@ -139,8 +280,14 @@ function setUniform(gl, location, value) {
139
280
  function getUniformLocation(gl, program, name) {
140
281
  return gl.getUniformLocation(program, name);
141
282
  }
142
- function setUniforms(gl, program, uniforms, locationCache) {
283
+ function setUniforms(gl, program, uniforms, locationCache, textureManager) {
143
284
  for (const [name, value] of Object.entries(uniforms)) {
285
+ if (isTexture(value)) {
286
+ if (textureManager) {
287
+ bindTextureUniform(gl, program, name, value, textureManager, locationCache);
288
+ }
289
+ continue;
290
+ }
144
291
  let location = locationCache.get(name);
145
292
  if (location === undefined) {
146
293
  location = getUniformLocation(gl, program, name);
@@ -164,6 +311,9 @@ function createUniformLocationCache() {
164
311
  return new Map;
165
312
  }
166
313
  function getUniformType(value) {
314
+ if (isTexture(value)) {
315
+ return "sampler2D";
316
+ }
167
317
  if (typeof value === "number") {
168
318
  return "float";
169
319
  }
@@ -247,10 +397,12 @@ function initializeWebGL(canvas, vertexSource, fragmentSource, customUniforms) {
247
397
  program,
248
398
  positionBuffer,
249
399
  positionAttributeLocation,
250
- uniformLocationCache: createUniformLocationCache()
400
+ uniformLocationCache: createUniformLocationCache(),
401
+ textureManager: createTextureManager(gl)
251
402
  };
252
403
  }
253
404
  function cleanupWebGL(gl, state) {
405
+ cleanupTextures(gl, state.textureManager);
254
406
  gl.deleteBuffer(state.positionBuffer);
255
407
  gl.deleteProgram(state.program);
256
408
  }
@@ -303,7 +455,7 @@ function useWebGL(options) {
303
455
  const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
304
456
  lastFrameTimeRef.current = time;
305
457
  elapsedTimeRef.current += deltaTime * timeScaleRef.current;
306
- const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
458
+ const { gl, program, positionAttributeLocation, uniformLocationCache, textureManager } = state;
307
459
  const elapsedTime = elapsedTimeRef.current;
308
460
  const dpr = dprRef.current;
309
461
  const displayWidth = canvas.clientWidth;
@@ -331,7 +483,7 @@ function useWebGL(options) {
331
483
  defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
332
484
  defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
333
485
  defaultUniforms.iResolution = [canvas.width, canvas.height];
334
- setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
486
+ setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache, textureManager);
335
487
  gl.drawArrays(gl.TRIANGLES, 0, 6);
336
488
  if (onFrameRef.current) {
337
489
  onFrameRef.current({
@@ -516,7 +668,9 @@ function ReactShader({
516
668
  timeScale = 1,
517
669
  onFrame,
518
670
  onClick,
519
- onMouseMove
671
+ onMouseMove,
672
+ onMouseDown,
673
+ onMouseUp
520
674
  }) {
521
675
  const [error, setError] = import_react2.useState(null);
522
676
  const handleError = import_react2.useCallback((err) => {
@@ -534,6 +688,8 @@ function ReactShader({
534
688
  onFrame,
535
689
  onClick,
536
690
  onMouseMove,
691
+ onMouseDown,
692
+ onMouseUp,
537
693
  timeScale
538
694
  });
539
695
  const containerStyle = import_react2.useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
package/dist/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export { generateDistortionRippleFunction } from "./shaders/distortion-ripple";
4
4
  export { generateSceneCirclesFunction } from "./shaders/scene-circles";
5
5
  export { generateSimplexNoiseFunction } from "./shaders/simplex-noise";
6
6
  export { generateUtilsFunction } from "./shaders/utils";
7
- export type { DefaultUniforms, FloatArray, FrameInfo, ReactShaderProps, UniformValue, Vec2, Vec2Array, Vec3, Vec3Array, Vec4, Vec4Array, } from "./types";
7
+ export type { DefaultUniforms, FloatArray, FrameInfo, ReactShaderProps, TextureMagFilter, TextureMinFilter, TextureOptions, TextureSource, TextureWrap, UniformValue, Vec2, Vec2Array, Vec3, Vec3Array, Vec4, Vec4Array, } from "./types";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAA;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,YAAY,EACV,eAAe,EACf,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAA;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,YAAY,EACV,eAAe,EACf,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,MAAM,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -48,6 +48,147 @@ function createShaderProgram(gl, vertexSource, fragmentSource) {
48
48
  }
49
49
  }
50
50
 
51
+ // src/utils/textures.ts
52
+ function isTextureSource(value) {
53
+ if (typeof window === "undefined")
54
+ return false;
55
+ return value instanceof HTMLImageElement || value instanceof HTMLCanvasElement || value instanceof HTMLVideoElement || typeof ImageBitmap !== "undefined" && value instanceof ImageBitmap || value instanceof ImageData || typeof OffscreenCanvas !== "undefined" && value instanceof OffscreenCanvas;
56
+ }
57
+ function isTextureOptions(value) {
58
+ return typeof value === "object" && value !== null && "source" in value && isTextureSource(value.source);
59
+ }
60
+ function isTexture(value) {
61
+ return isTextureSource(value) || isTextureOptions(value);
62
+ }
63
+ function getWrapMode(gl, wrap) {
64
+ switch (wrap) {
65
+ case "repeat":
66
+ return gl.REPEAT;
67
+ case "mirror":
68
+ return gl.MIRRORED_REPEAT;
69
+ default:
70
+ return gl.CLAMP_TO_EDGE;
71
+ }
72
+ }
73
+ function getMinFilter(gl, filter) {
74
+ switch (filter) {
75
+ case "nearest":
76
+ return gl.NEAREST;
77
+ case "mipmap":
78
+ return gl.LINEAR_MIPMAP_LINEAR;
79
+ default:
80
+ return gl.LINEAR;
81
+ }
82
+ }
83
+ function getMagFilter(gl, filter) {
84
+ switch (filter) {
85
+ case "nearest":
86
+ return gl.NEAREST;
87
+ default:
88
+ return gl.LINEAR;
89
+ }
90
+ }
91
+ function isPowerOfTwo(value) {
92
+ return (value & value - 1) === 0 && value !== 0;
93
+ }
94
+ function getSourceDimensions(source) {
95
+ if (source instanceof HTMLImageElement) {
96
+ return { width: source.naturalWidth, height: source.naturalHeight };
97
+ }
98
+ if (source instanceof HTMLVideoElement) {
99
+ return { width: source.videoWidth, height: source.videoHeight };
100
+ }
101
+ if (source instanceof ImageData) {
102
+ return { width: source.width, height: source.height };
103
+ }
104
+ return { width: source.width, height: source.height };
105
+ }
106
+ function createTextureManager(gl) {
107
+ const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
108
+ return {
109
+ cache: new Map,
110
+ nextUnit: 0,
111
+ maxUnits
112
+ };
113
+ }
114
+ function createTexture(gl, source, options = {}) {
115
+ const texture = gl.createTexture();
116
+ if (!texture) {
117
+ throw new Error("Failed to create WebGL texture");
118
+ }
119
+ const { wrapS = "clamp", wrapT = "clamp", minFilter = "linear", magFilter = "linear", flipY = true } = options;
120
+ gl.bindTexture(gl.TEXTURE_2D, texture);
121
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
122
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
123
+ const { width, height } = getSourceDimensions(source);
124
+ const pot = isPowerOfTwo(width) && isPowerOfTwo(height);
125
+ const isWebGL2 = "texStorage2D" in gl;
126
+ const actualMinFilter = minFilter === "mipmap" && (pot || isWebGL2) ? minFilter : minFilter === "mipmap" ? "linear" : minFilter;
127
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, getWrapMode(gl, wrapS));
128
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, getWrapMode(gl, wrapT));
129
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, getMinFilter(gl, actualMinFilter));
130
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, getMagFilter(gl, magFilter));
131
+ if (actualMinFilter === "mipmap") {
132
+ gl.generateMipmap(gl.TEXTURE_2D);
133
+ }
134
+ gl.bindTexture(gl.TEXTURE_2D, null);
135
+ return texture;
136
+ }
137
+ function updateTexture(gl, texture, source, flipY = true) {
138
+ gl.bindTexture(gl.TEXTURE_2D, texture);
139
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
140
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
141
+ gl.bindTexture(gl.TEXTURE_2D, null);
142
+ }
143
+ function needsVideoUpdate(source) {
144
+ if (!(source instanceof HTMLVideoElement))
145
+ return false;
146
+ return !source.paused && !source.ended && source.readyState >= 2;
147
+ }
148
+ function bindTextureUniform(gl, program, name, value, manager, locationCache) {
149
+ const source = isTextureOptions(value) ? value.source : value;
150
+ const options = isTextureOptions(value) ? value : {};
151
+ let entry = manager.cache.get(name);
152
+ if (entry && entry.source !== source) {
153
+ gl.deleteTexture(entry.texture);
154
+ entry = undefined;
155
+ }
156
+ if (!entry) {
157
+ if (manager.nextUnit >= manager.maxUnits) {
158
+ console.warn(`Maximum texture units (${manager.maxUnits}) exceeded for uniform "${name}"`);
159
+ return;
160
+ }
161
+ const texture = createTexture(gl, source, options);
162
+ entry = {
163
+ texture,
164
+ unit: manager.nextUnit++,
165
+ source
166
+ };
167
+ manager.cache.set(name, entry);
168
+ }
169
+ if (needsVideoUpdate(source)) {
170
+ const flipY = isTextureOptions(value) ? value.flipY ?? true : true;
171
+ updateTexture(gl, entry.texture, source, flipY);
172
+ }
173
+ gl.activeTexture(gl.TEXTURE0 + entry.unit);
174
+ gl.bindTexture(gl.TEXTURE_2D, entry.texture);
175
+ let location = locationCache.get(name);
176
+ if (location === undefined) {
177
+ location = gl.getUniformLocation(program, name);
178
+ locationCache.set(name, location);
179
+ }
180
+ if (location !== null) {
181
+ gl.uniform1i(location, entry.unit);
182
+ }
183
+ }
184
+ function cleanupTextures(gl, manager) {
185
+ for (const entry of manager.cache.values()) {
186
+ gl.deleteTexture(entry.texture);
187
+ }
188
+ manager.cache.clear();
189
+ manager.nextUnit = 0;
190
+ }
191
+
51
192
  // src/utils/uniforms.ts
52
193
  var MAX_ARRAY_LENGTH = 100;
53
194
  function isVec2(value) {
@@ -99,8 +240,14 @@ function setUniform(gl, location, value) {
99
240
  function getUniformLocation(gl, program, name) {
100
241
  return gl.getUniformLocation(program, name);
101
242
  }
102
- function setUniforms(gl, program, uniforms, locationCache) {
243
+ function setUniforms(gl, program, uniforms, locationCache, textureManager) {
103
244
  for (const [name, value] of Object.entries(uniforms)) {
245
+ if (isTexture(value)) {
246
+ if (textureManager) {
247
+ bindTextureUniform(gl, program, name, value, textureManager, locationCache);
248
+ }
249
+ continue;
250
+ }
104
251
  let location = locationCache.get(name);
105
252
  if (location === undefined) {
106
253
  location = getUniformLocation(gl, program, name);
@@ -124,6 +271,9 @@ function createUniformLocationCache() {
124
271
  return new Map;
125
272
  }
126
273
  function getUniformType(value) {
274
+ if (isTexture(value)) {
275
+ return "sampler2D";
276
+ }
127
277
  if (typeof value === "number") {
128
278
  return "float";
129
279
  }
@@ -207,10 +357,12 @@ function initializeWebGL(canvas, vertexSource, fragmentSource, customUniforms) {
207
357
  program,
208
358
  positionBuffer,
209
359
  positionAttributeLocation,
210
- uniformLocationCache: createUniformLocationCache()
360
+ uniformLocationCache: createUniformLocationCache(),
361
+ textureManager: createTextureManager(gl)
211
362
  };
212
363
  }
213
364
  function cleanupWebGL(gl, state) {
365
+ cleanupTextures(gl, state.textureManager);
214
366
  gl.deleteBuffer(state.positionBuffer);
215
367
  gl.deleteProgram(state.program);
216
368
  }
@@ -263,7 +415,7 @@ function useWebGL(options) {
263
415
  const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
264
416
  lastFrameTimeRef.current = time;
265
417
  elapsedTimeRef.current += deltaTime * timeScaleRef.current;
266
- const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
418
+ const { gl, program, positionAttributeLocation, uniformLocationCache, textureManager } = state;
267
419
  const elapsedTime = elapsedTimeRef.current;
268
420
  const dpr = dprRef.current;
269
421
  const displayWidth = canvas.clientWidth;
@@ -291,7 +443,7 @@ function useWebGL(options) {
291
443
  defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
292
444
  defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
293
445
  defaultUniforms.iResolution = [canvas.width, canvas.height];
294
- setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
446
+ setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache, textureManager);
295
447
  gl.drawArrays(gl.TRIANGLES, 0, 6);
296
448
  if (onFrameRef.current) {
297
449
  onFrameRef.current({
@@ -476,7 +628,9 @@ function ReactShader({
476
628
  timeScale = 1,
477
629
  onFrame,
478
630
  onClick,
479
- onMouseMove
631
+ onMouseMove,
632
+ onMouseDown,
633
+ onMouseUp
480
634
  }) {
481
635
  const [error, setError] = useState(null);
482
636
  const handleError = useCallback2((err) => {
@@ -494,6 +648,8 @@ function ReactShader({
494
648
  onFrame,
495
649
  onClick,
496
650
  onMouseMove,
651
+ onMouseDown,
652
+ onMouseUp,
497
653
  timeScale
498
654
  });
499
655
  const containerStyle = useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
package/dist/types.d.ts CHANGED
@@ -5,7 +5,19 @@ export type FloatArray = number[];
5
5
  export type Vec2Array = Vec2[];
6
6
  export type Vec3Array = Vec3[];
7
7
  export type Vec4Array = Vec4[];
8
- export type UniformValue = number | Vec2 | Vec3 | Vec4 | FloatArray | Vec2Array | Vec3Array | Vec4Array;
8
+ export type TextureSource = HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | ImageData | OffscreenCanvas;
9
+ export type TextureWrap = "repeat" | "clamp" | "mirror";
10
+ export type TextureMinFilter = "nearest" | "linear" | "mipmap";
11
+ export type TextureMagFilter = "nearest" | "linear";
12
+ export interface TextureOptions {
13
+ source: TextureSource;
14
+ wrapS?: TextureWrap;
15
+ wrapT?: TextureWrap;
16
+ minFilter?: TextureMinFilter;
17
+ magFilter?: TextureMagFilter;
18
+ flipY?: boolean;
19
+ }
20
+ export type UniformValue = number | Vec2 | Vec3 | Vec4 | FloatArray | Vec2Array | Vec3Array | Vec4Array | TextureSource | TextureOptions;
9
21
  export interface FrameInfo {
10
22
  deltaTime: number;
11
23
  time: number;
@@ -24,6 +36,8 @@ export interface ReactShaderProps {
24
36
  onFrame?: (info: FrameInfo) => void;
25
37
  onClick?: (info: FrameInfo) => void;
26
38
  onMouseMove?: (info: FrameInfo) => void;
39
+ onMouseDown?: (info: FrameInfo) => void;
40
+ onMouseUp?: (info: FrameInfo) => void;
27
41
  }
28
42
  export interface DefaultUniforms {
29
43
  iTime: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AACnC,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAC3C,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,CAAA;AACjC,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAE9B,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;AAEvG,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,aAAa,EAAE,OAAO,CAAA;CACvB;AACD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,IAAI,CAAA;IACZ,gBAAgB,EAAE,IAAI,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,IAAI,CAAA;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AACnC,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAC3C,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,CAAA;AACjC,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAE9B,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,GAChB,WAAW,GACX,SAAS,GACT,eAAe,CAAA;AAEnB,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;AACvD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAC9D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEnD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,UAAU,GACV,SAAS,GACT,SAAS,GACT,SAAS,GACT,aAAa,GACb,cAAc,CAAA;AAElB,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,aAAa,EAAE,OAAO,CAAA;CACvB;AACD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,IAAI,CAAA;IACZ,gBAAgB,EAAE,IAAI,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,IAAI,CAAA;CAClB"}
@@ -0,0 +1,23 @@
1
+ import type { TextureOptions, TextureSource } from "../types";
2
+ type WebGLContext = WebGLRenderingContext | WebGL2RenderingContext;
3
+ interface TextureEntry {
4
+ texture: WebGLTexture;
5
+ unit: number;
6
+ source: TextureSource;
7
+ }
8
+ export interface TextureManager {
9
+ cache: Map<string, TextureEntry>;
10
+ nextUnit: number;
11
+ maxUnits: number;
12
+ }
13
+ export declare function isTextureSource(value: unknown): value is TextureSource;
14
+ export declare function isTextureOptions(value: unknown): value is TextureOptions;
15
+ export declare function isTexture(value: unknown): value is TextureSource | TextureOptions;
16
+ export declare function createTextureManager(gl: WebGLContext): TextureManager;
17
+ export declare function createTexture(gl: WebGLContext, source: TextureSource, options?: Partial<TextureOptions>): WebGLTexture;
18
+ export declare function updateTexture(gl: WebGLContext, texture: WebGLTexture, source: TextureSource, flipY?: boolean): void;
19
+ export declare function needsVideoUpdate(source: TextureSource): boolean;
20
+ export declare function bindTextureUniform(gl: WebGLContext, program: WebGLProgram, name: string, value: TextureSource | TextureOptions, manager: TextureManager, locationCache: Map<string, WebGLUniformLocation | null>): void;
21
+ export declare function cleanupTextures(gl: WebGLContext, manager: TextureManager): void;
22
+ export {};
23
+ //# sourceMappingURL=textures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textures.d.ts","sourceRoot":"","sources":["../../src/utils/textures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsC,cAAc,EAAE,aAAa,EAAe,MAAM,UAAU,CAAA;AAE9G,KAAK,YAAY,GAAG,qBAAqB,GAAG,sBAAsB,CAAA;AAElE,UAAU,YAAY;IACpB,OAAO,EAAE,YAAY,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,aAAa,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAUtE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAOxE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,GAAG,cAAc,CAEjF;AAmDD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,cAAc,CAOrE;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,OAAO,CAAC,cAAc,CAAM,GACpC,YAAY,CAqCd;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,UAAO,GAAG,IAAI,CAKhH;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAG/D;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,GAAG,cAAc,EACrC,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC,GACtD,IAAI,CA+CN;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAM/E"}
@@ -1,9 +1,10 @@
1
1
  import type { UniformValue } from "../types";
2
+ import { type TextureManager } from "./textures";
2
3
  type WebGLContext = WebGLRenderingContext | WebGL2RenderingContext;
3
4
  export declare const MAX_ARRAY_LENGTH = 100;
4
5
  export declare function setUniform(gl: WebGLContext, location: WebGLUniformLocation | null, value: UniformValue): void;
5
6
  export declare function getUniformLocation(gl: WebGLContext, program: WebGLProgram, name: string): WebGLUniformLocation | null;
6
- export declare function setUniforms(gl: WebGLContext, program: WebGLProgram, uniforms: Record<string, UniformValue>, locationCache: Map<string, WebGLUniformLocation | null>): void;
7
+ export declare function setUniforms(gl: WebGLContext, program: WebGLProgram, uniforms: Record<string, UniformValue>, locationCache: Map<string, WebGLUniformLocation | null>, textureManager?: TextureManager): void;
7
8
  export declare function createUniformLocationCache(): Map<string, WebGLUniformLocation | null>;
8
9
  export declare function generateUniformDeclarations(uniforms: Record<string, UniformValue>): string;
9
10
  export declare function injectUniformDeclarations(shaderSource: string, customUniforms: Record<string, UniformValue> | undefined, defaultUniforms: Record<string, UniformValue>): string;
@@ -1 +1 @@
1
- {"version":3,"file":"uniforms.d.ts","sourceRoot":"","sources":["../../src/utils/uniforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,YAAY,EAAqD,MAAM,UAAU,CAAA;AAE3G,KAAK,YAAY,GAAG,qBAAqB,GAAG,sBAAsB,CAAA;AAElE,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAkCnC,wBAAgB,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAsB7G;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAErH;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC,GACtD,IAAI,CAsBN;AAED,wBAAgB,0BAA0B,IAAI,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC,CAErF;AA8BD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,CAa1F;AAID,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,EACxD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAC5C,MAAM,CAQR"}
1
+ {"version":3,"file":"uniforms.d.ts","sourceRoot":"","sources":["../../src/utils/uniforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,YAAY,EAAqD,MAAM,UAAU,CAAA;AAC3G,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAE/E,KAAK,YAAY,GAAG,qBAAqB,GAAG,sBAAsB,CAAA;AAElE,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAkCnC,wBAAgB,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAsB7G;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAErH;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC,EACvD,cAAc,CAAC,EAAE,cAAc,GAC9B,IAAI,CA8BN;AAED,wBAAgB,0BAA0B,IAAI,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC,CAErF;AAiCD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,CAa1F;AAID,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,EACxD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAC5C,MAAM,CAQR"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjandin/react-shader",
3
- "version": "0.0.11",
3
+ "version": "0.0.14",
4
4
  "description": "React component for rendering WebGL shaders",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",