@fjandin/react-shader 0.0.12 → 0.0.15
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/ReactShader.d.ts +1 -1
- package/dist/ReactShader.d.ts.map +1 -1
- package/dist/example/frontend.d.ts.map +1 -1
- package/dist/example/glsl/texture-demo.glsl.d.ts +2 -0
- package/dist/example/glsl/texture-demo.glsl.d.ts.map +1 -0
- package/dist/hooks/useWebGL.d.ts +1 -0
- package/dist/hooks/useWebGL.d.ts.map +1 -1
- package/dist/index.cjs +173 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +173 -5
- package/dist/types.d.ts +14 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/textures.d.ts +23 -0
- package/dist/utils/textures.d.ts.map +1 -0
- package/dist/utils/uniforms.d.ts +2 -1
- package/dist/utils/uniforms.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/ReactShader.d.ts
CHANGED
|
@@ -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, onMouseDown, onMouseUp, }: ReactShaderProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function ReactShader({ className, fragment, vertex, uniforms, fullscreen, timeScale, onFrame, onClick, onMouseMove, onMouseDown, onMouseUp, onMouseWheel, }: 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,EACX,WAAW,EACX,SAAS,
|
|
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,EACT,YAAY,GACb,EAAE,gBAAgB,2CA0DlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AAiHpB,wBAAgB,GAAG,4CAwGlB"}
|
|
@@ -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"}
|
package/dist/hooks/useWebGL.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ interface UseWebGLOptions {
|
|
|
9
9
|
onMouseDown?: (info: FrameInfo) => void;
|
|
10
10
|
onMouseUp?: (info: FrameInfo) => void;
|
|
11
11
|
onMouseMove?: (info: FrameInfo) => void;
|
|
12
|
+
onMouseWheel?: (info: FrameInfo, wheelDelta: number) => void;
|
|
12
13
|
timeScale?: number;
|
|
13
14
|
}
|
|
14
15
|
export declare function useWebGL(options: UseWebGLOptions): {
|
|
@@ -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;
|
|
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,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EA0ShD"}
|
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
|
}
|
|
@@ -272,6 +424,7 @@ function useWebGL(options) {
|
|
|
272
424
|
const onMouseDownRef = import_react.useRef(options.onMouseDown);
|
|
273
425
|
const onMouseUpRef = import_react.useRef(options.onMouseUp);
|
|
274
426
|
const onMouseMoveRef = import_react.useRef(options.onMouseMove);
|
|
427
|
+
const onMouseWheelRef = import_react.useRef(options.onMouseWheel);
|
|
275
428
|
const timeScaleRef = import_react.useRef(options.timeScale ?? 1);
|
|
276
429
|
const vertexRef = import_react.useRef(options.vertex);
|
|
277
430
|
const fragmentRef = import_react.useRef(options.fragment);
|
|
@@ -290,6 +443,7 @@ function useWebGL(options) {
|
|
|
290
443
|
onMouseDownRef.current = options.onMouseDown;
|
|
291
444
|
onMouseUpRef.current = options.onMouseUp;
|
|
292
445
|
onMouseMoveRef.current = options.onMouseMove;
|
|
446
|
+
onMouseWheelRef.current = options.onMouseWheel;
|
|
293
447
|
timeScaleRef.current = options.timeScale ?? 1;
|
|
294
448
|
vertexRef.current = options.vertex;
|
|
295
449
|
fragmentRef.current = options.fragment;
|
|
@@ -303,7 +457,7 @@ function useWebGL(options) {
|
|
|
303
457
|
const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
|
|
304
458
|
lastFrameTimeRef.current = time;
|
|
305
459
|
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
306
|
-
const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
|
|
460
|
+
const { gl, program, positionAttributeLocation, uniformLocationCache, textureManager } = state;
|
|
307
461
|
const elapsedTime = elapsedTimeRef.current;
|
|
308
462
|
const dpr = dprRef.current;
|
|
309
463
|
const displayWidth = canvas.clientWidth;
|
|
@@ -331,7 +485,7 @@ function useWebGL(options) {
|
|
|
331
485
|
defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
|
|
332
486
|
defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
|
|
333
487
|
defaultUniforms.iResolution = [canvas.width, canvas.height];
|
|
334
|
-
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
|
|
488
|
+
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache, textureManager);
|
|
335
489
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
336
490
|
if (onFrameRef.current) {
|
|
337
491
|
onFrameRef.current({
|
|
@@ -464,10 +618,21 @@ function useWebGL(options) {
|
|
|
464
618
|
mouseLeftDown: mouseLeftDownRef.current
|
|
465
619
|
});
|
|
466
620
|
};
|
|
621
|
+
const handleMouseWheel = (event) => {
|
|
622
|
+
onMouseWheelRef.current?.({
|
|
623
|
+
deltaTime: 0,
|
|
624
|
+
time: elapsedTimeRef.current,
|
|
625
|
+
resolution: [canvas.width, canvas.height],
|
|
626
|
+
mouse: mouseRef.current,
|
|
627
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
628
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
629
|
+
}, event.deltaY);
|
|
630
|
+
};
|
|
467
631
|
window.addEventListener("mousemove", handleMouseMove);
|
|
468
632
|
window.addEventListener("mousedown", handleMouseDown);
|
|
469
633
|
window.addEventListener("mouseup", handleMouseUp);
|
|
470
634
|
canvas.addEventListener("click", handleClick);
|
|
635
|
+
window.addEventListener("wheel", handleMouseWheel);
|
|
471
636
|
return () => {
|
|
472
637
|
resizeObserver.disconnect();
|
|
473
638
|
window.removeEventListener("scroll", updateRect);
|
|
@@ -475,6 +640,7 @@ function useWebGL(options) {
|
|
|
475
640
|
window.removeEventListener("mousedown", handleMouseDown);
|
|
476
641
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
477
642
|
canvas.removeEventListener("click", handleClick);
|
|
643
|
+
window.removeEventListener("wheel", handleMouseWheel);
|
|
478
644
|
};
|
|
479
645
|
}, []);
|
|
480
646
|
return { canvasRef, mouseRef };
|
|
@@ -518,7 +684,8 @@ function ReactShader({
|
|
|
518
684
|
onClick,
|
|
519
685
|
onMouseMove,
|
|
520
686
|
onMouseDown,
|
|
521
|
-
onMouseUp
|
|
687
|
+
onMouseUp,
|
|
688
|
+
onMouseWheel
|
|
522
689
|
}) {
|
|
523
690
|
const [error, setError] = import_react2.useState(null);
|
|
524
691
|
const handleError = import_react2.useCallback((err) => {
|
|
@@ -538,6 +705,7 @@ function ReactShader({
|
|
|
538
705
|
onMouseMove,
|
|
539
706
|
onMouseDown,
|
|
540
707
|
onMouseUp,
|
|
708
|
+
onMouseWheel,
|
|
541
709
|
timeScale
|
|
542
710
|
});
|
|
543
711
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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
|
}
|
|
@@ -232,6 +384,7 @@ function useWebGL(options) {
|
|
|
232
384
|
const onMouseDownRef = useRef(options.onMouseDown);
|
|
233
385
|
const onMouseUpRef = useRef(options.onMouseUp);
|
|
234
386
|
const onMouseMoveRef = useRef(options.onMouseMove);
|
|
387
|
+
const onMouseWheelRef = useRef(options.onMouseWheel);
|
|
235
388
|
const timeScaleRef = useRef(options.timeScale ?? 1);
|
|
236
389
|
const vertexRef = useRef(options.vertex);
|
|
237
390
|
const fragmentRef = useRef(options.fragment);
|
|
@@ -250,6 +403,7 @@ function useWebGL(options) {
|
|
|
250
403
|
onMouseDownRef.current = options.onMouseDown;
|
|
251
404
|
onMouseUpRef.current = options.onMouseUp;
|
|
252
405
|
onMouseMoveRef.current = options.onMouseMove;
|
|
406
|
+
onMouseWheelRef.current = options.onMouseWheel;
|
|
253
407
|
timeScaleRef.current = options.timeScale ?? 1;
|
|
254
408
|
vertexRef.current = options.vertex;
|
|
255
409
|
fragmentRef.current = options.fragment;
|
|
@@ -263,7 +417,7 @@ function useWebGL(options) {
|
|
|
263
417
|
const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
|
|
264
418
|
lastFrameTimeRef.current = time;
|
|
265
419
|
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
266
|
-
const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
|
|
420
|
+
const { gl, program, positionAttributeLocation, uniformLocationCache, textureManager } = state;
|
|
267
421
|
const elapsedTime = elapsedTimeRef.current;
|
|
268
422
|
const dpr = dprRef.current;
|
|
269
423
|
const displayWidth = canvas.clientWidth;
|
|
@@ -291,7 +445,7 @@ function useWebGL(options) {
|
|
|
291
445
|
defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
|
|
292
446
|
defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
|
|
293
447
|
defaultUniforms.iResolution = [canvas.width, canvas.height];
|
|
294
|
-
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
|
|
448
|
+
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache, textureManager);
|
|
295
449
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
296
450
|
if (onFrameRef.current) {
|
|
297
451
|
onFrameRef.current({
|
|
@@ -424,10 +578,21 @@ function useWebGL(options) {
|
|
|
424
578
|
mouseLeftDown: mouseLeftDownRef.current
|
|
425
579
|
});
|
|
426
580
|
};
|
|
581
|
+
const handleMouseWheel = (event) => {
|
|
582
|
+
onMouseWheelRef.current?.({
|
|
583
|
+
deltaTime: 0,
|
|
584
|
+
time: elapsedTimeRef.current,
|
|
585
|
+
resolution: [canvas.width, canvas.height],
|
|
586
|
+
mouse: mouseRef.current,
|
|
587
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
588
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
589
|
+
}, event.deltaY);
|
|
590
|
+
};
|
|
427
591
|
window.addEventListener("mousemove", handleMouseMove);
|
|
428
592
|
window.addEventListener("mousedown", handleMouseDown);
|
|
429
593
|
window.addEventListener("mouseup", handleMouseUp);
|
|
430
594
|
canvas.addEventListener("click", handleClick);
|
|
595
|
+
window.addEventListener("wheel", handleMouseWheel);
|
|
431
596
|
return () => {
|
|
432
597
|
resizeObserver.disconnect();
|
|
433
598
|
window.removeEventListener("scroll", updateRect);
|
|
@@ -435,6 +600,7 @@ function useWebGL(options) {
|
|
|
435
600
|
window.removeEventListener("mousedown", handleMouseDown);
|
|
436
601
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
437
602
|
canvas.removeEventListener("click", handleClick);
|
|
603
|
+
window.removeEventListener("wheel", handleMouseWheel);
|
|
438
604
|
};
|
|
439
605
|
}, []);
|
|
440
606
|
return { canvasRef, mouseRef };
|
|
@@ -478,7 +644,8 @@ function ReactShader({
|
|
|
478
644
|
onClick,
|
|
479
645
|
onMouseMove,
|
|
480
646
|
onMouseDown,
|
|
481
|
-
onMouseUp
|
|
647
|
+
onMouseUp,
|
|
648
|
+
onMouseWheel
|
|
482
649
|
}) {
|
|
483
650
|
const [error, setError] = useState(null);
|
|
484
651
|
const handleError = useCallback2((err) => {
|
|
@@ -498,6 +665,7 @@ function ReactShader({
|
|
|
498
665
|
onMouseMove,
|
|
499
666
|
onMouseDown,
|
|
500
667
|
onMouseUp,
|
|
668
|
+
onMouseWheel,
|
|
501
669
|
timeScale
|
|
502
670
|
});
|
|
503
671
|
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
|
|
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;
|
|
@@ -26,6 +38,7 @@ export interface ReactShaderProps {
|
|
|
26
38
|
onMouseMove?: (info: FrameInfo) => void;
|
|
27
39
|
onMouseDown?: (info: FrameInfo) => void;
|
|
28
40
|
onMouseUp?: (info: FrameInfo) => void;
|
|
41
|
+
onMouseWheel?: (info: FrameInfo, wheelDelta: number) => void;
|
|
29
42
|
}
|
|
30
43
|
export interface DefaultUniforms {
|
|
31
44
|
iTime: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -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,
|
|
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;IACrC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7D;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"}
|
package/dist/utils/uniforms.d.ts
CHANGED
|
@@ -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
|
|
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;
|
|
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"}
|