@fjandin/react-shader 0.0.20 → 0.0.30

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.js CHANGED
@@ -348,10 +348,11 @@ function createStorageBuffer(device, name, binding, data) {
348
348
  packingArray[off + 3] = data[i][3];
349
349
  }
350
350
  device.queue.writeBuffer(buffer, 0, packingArray);
351
- return { name, binding, buffer, currentLength: length, dataLength: data.length, packingArray };
351
+ return { name, binding, buffer, currentLength: length, packingArray };
352
352
  }
353
353
  function packAndUploadStorageBuffer(device, entry, data) {
354
354
  const arr = entry.packingArray;
355
+ arr.fill(0);
355
356
  for (let i = 0;i < data.length; i++) {
356
357
  const off = i * 4;
357
358
  arr[off] = data[i][0];
@@ -359,8 +360,7 @@ function packAndUploadStorageBuffer(device, entry, data) {
359
360
  arr[off + 2] = data[i][2];
360
361
  arr[off + 3] = data[i][3];
361
362
  }
362
- const uploadLength = Math.max(entry.dataLength, 1);
363
- device.queue.writeBuffer(entry.buffer, 0, arr, 0, uploadLength * 4);
363
+ device.queue.writeBuffer(entry.buffer, 0, arr);
364
364
  }
365
365
  function rebuildBindGroup(state) {
366
366
  const entries = [{ binding: 0, resource: { buffer: state.uniformBuffer } }];
@@ -477,18 +477,7 @@ async function initializeWebGPU(canvas, fragmentSource, customUniforms, storageB
477
477
  uniformBindGroup,
478
478
  uniformLayout,
479
479
  bindGroupLayout,
480
- storageBuffers,
481
- renderPassDescriptor: {
482
- colorAttachments: [
483
- {
484
- view: undefined,
485
- clearValue: { r: 0, g: 0, b: 0, a: 1 },
486
- loadOp: "clear",
487
- storeOp: "store"
488
- }
489
- ]
490
- },
491
- submitArray: [null]
480
+ storageBuffers
492
481
  };
493
482
  }
494
483
  function cleanupWebGPU(state) {
@@ -506,7 +495,6 @@ function useWebGPU(options) {
506
495
  const lastFrameTimeRef = useRef2(0);
507
496
  const mouseRef = useRef2([0, 0]);
508
497
  const mouseNormalizedRef = useRef2([0, 0]);
509
- const resolutionRef = useRef2([0, 0]);
510
498
  const mouseLeftDownRef = useRef2(false);
511
499
  const canvasRectRef = useRef2(null);
512
500
  const onErrorRef = useRef2(options.onError);
@@ -579,18 +567,16 @@ function useWebGPU(options) {
579
567
  const allValues = allValuesRef.current;
580
568
  allValues.iTime = elapsedTimeRef.current;
581
569
  allValues.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
582
- resolutionRef.current[0] = canvas.width;
583
- resolutionRef.current[1] = canvas.height;
584
- allValues.iResolution = resolutionRef.current;
570
+ allValues.iResolution = [canvas.width, canvas.height];
585
571
  allValues.iMouse = mouseRef.current;
586
572
  allValues.iMouseNormalized = mouseNormalizedRef.current;
587
- const customs = uniformsRef.current;
588
- if (customs) {
589
- for (const name in customs) {
590
- allValues[name] = customs[name];
573
+ if (uniformsRef.current) {
574
+ for (const [name, value] of Object.entries(uniformsRef.current)) {
575
+ allValues[name] = value;
591
576
  }
592
577
  }
593
578
  const uniformData = uniformDataRef.current;
579
+ uniformData.fill(0);
594
580
  for (const field of uniformLayout.fields) {
595
581
  const value = allValues[field.name];
596
582
  if (value === undefined) {
@@ -605,20 +591,18 @@ function useWebGPU(options) {
605
591
  if (!data)
606
592
  continue;
607
593
  const requiredLength = Math.max(data.length, 1);
608
- if (requiredLength > entry.currentLength || requiredLength < entry.currentLength / 2) {
609
- const allocLength = Math.max(Math.ceil(requiredLength * 1.5), 1);
594
+ if (requiredLength !== entry.currentLength) {
610
595
  entry.buffer.destroy();
611
- const byteSize = allocLength * 16;
596
+ const byteSize = requiredLength * 16;
612
597
  entry.buffer = device.createBuffer({
613
598
  label: `storage: ${entry.name}`,
614
599
  size: byteSize,
615
600
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
616
601
  });
617
- entry.packingArray = new Float32Array(allocLength * 4);
618
- entry.currentLength = allocLength;
602
+ entry.packingArray = new Float32Array(requiredLength * 4);
603
+ entry.currentLength = requiredLength;
619
604
  needsBindGroupRebuild = true;
620
605
  }
621
- entry.dataLength = data.length;
622
606
  packAndUploadStorageBuffer(device, entry, data);
623
607
  }
624
608
  if (needsBindGroupRebuild) {
@@ -626,14 +610,21 @@ function useWebGPU(options) {
626
610
  }
627
611
  const commandEncoder = device.createCommandEncoder();
628
612
  const textureView = context.getCurrentTexture().createView();
629
- state.renderPassDescriptor.colorAttachments[0].view = textureView;
630
- const renderPass = commandEncoder.beginRenderPass(state.renderPassDescriptor);
613
+ const renderPass = commandEncoder.beginRenderPass({
614
+ colorAttachments: [
615
+ {
616
+ view: textureView,
617
+ clearValue: { r: 0, g: 0, b: 0, a: 1 },
618
+ loadOp: "clear",
619
+ storeOp: "store"
620
+ }
621
+ ]
622
+ });
631
623
  renderPass.setPipeline(pipeline);
632
624
  renderPass.setBindGroup(0, state.uniformBindGroup);
633
625
  renderPass.draw(3);
634
626
  renderPass.end();
635
- state.submitArray[0] = commandEncoder.finish();
636
- device.queue.submit(state.submitArray);
627
+ device.queue.submit([commandEncoder.finish()]);
637
628
  animationFrameRef.current = requestAnimationFrame(render);
638
629
  }, []);
639
630
  useEffect(() => {
@@ -828,721 +819,6 @@ function ReactGpuShader({
828
819
  style: CANVAS_STYLE
829
820
  }, undefined, false, undefined, this);
830
821
  }
831
- // src/ReactShader.tsx
832
- import { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
833
-
834
- // src/hooks/useWebGL.ts
835
- import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3 } from "react";
836
-
837
- // src/utils/shader.ts
838
- function compileShader(gl, type, source) {
839
- const shader = gl.createShader(type);
840
- if (!shader) {
841
- throw new Error(`Failed to create shader of type ${type === gl.VERTEX_SHADER ? "VERTEX" : "FRAGMENT"}`);
842
- }
843
- gl.shaderSource(shader, source);
844
- gl.compileShader(shader);
845
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
846
- const info = gl.getShaderInfoLog(shader);
847
- gl.deleteShader(shader);
848
- const shaderType = type === gl.VERTEX_SHADER ? "Vertex" : "Fragment";
849
- throw new Error(`${shaderType} shader compilation failed:
850
- ${info}`);
851
- }
852
- return shader;
853
- }
854
- function createProgram(gl, vertexShader, fragmentShader) {
855
- const program = gl.createProgram();
856
- if (!program) {
857
- throw new Error("Failed to create WebGL program");
858
- }
859
- gl.attachShader(program, vertexShader);
860
- gl.attachShader(program, fragmentShader);
861
- gl.linkProgram(program);
862
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
863
- const info = gl.getProgramInfoLog(program);
864
- gl.deleteProgram(program);
865
- throw new Error(`Program linking failed:
866
- ${info}`);
867
- }
868
- return program;
869
- }
870
- function createShaderProgram(gl, vertexSource, fragmentSource) {
871
- const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
872
- const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
873
- try {
874
- return createProgram(gl, vertexShader, fragmentShader);
875
- } finally {
876
- gl.deleteShader(vertexShader);
877
- gl.deleteShader(fragmentShader);
878
- }
879
- }
880
-
881
- // src/utils/textures.ts
882
- function isTextureSource(value) {
883
- if (typeof window === "undefined")
884
- return false;
885
- 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;
886
- }
887
- function isTextureOptions(value) {
888
- return typeof value === "object" && value !== null && "source" in value && isTextureSource(value.source);
889
- }
890
- function isTexture(value) {
891
- return isTextureSource(value) || isTextureOptions(value);
892
- }
893
- function getWrapMode(gl, wrap) {
894
- switch (wrap) {
895
- case "repeat":
896
- return gl.REPEAT;
897
- case "mirror":
898
- return gl.MIRRORED_REPEAT;
899
- default:
900
- return gl.CLAMP_TO_EDGE;
901
- }
902
- }
903
- function getMinFilter(gl, filter) {
904
- switch (filter) {
905
- case "nearest":
906
- return gl.NEAREST;
907
- case "mipmap":
908
- return gl.LINEAR_MIPMAP_LINEAR;
909
- default:
910
- return gl.LINEAR;
911
- }
912
- }
913
- function getMagFilter(gl, filter) {
914
- switch (filter) {
915
- case "nearest":
916
- return gl.NEAREST;
917
- default:
918
- return gl.LINEAR;
919
- }
920
- }
921
- function isPowerOfTwo(value) {
922
- return (value & value - 1) === 0 && value !== 0;
923
- }
924
- function getSourceDimensions(source) {
925
- if (source instanceof HTMLImageElement) {
926
- return { width: source.naturalWidth, height: source.naturalHeight };
927
- }
928
- if (source instanceof HTMLVideoElement) {
929
- return { width: source.videoWidth, height: source.videoHeight };
930
- }
931
- if (source instanceof ImageData) {
932
- return { width: source.width, height: source.height };
933
- }
934
- return { width: source.width, height: source.height };
935
- }
936
- function createTextureManager(gl) {
937
- const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
938
- return {
939
- cache: new Map,
940
- nextUnit: 0,
941
- maxUnits
942
- };
943
- }
944
- function createTexture(gl, source, options = {}) {
945
- const texture = gl.createTexture();
946
- if (!texture) {
947
- throw new Error("Failed to create WebGL texture");
948
- }
949
- const { wrapS = "clamp", wrapT = "clamp", minFilter = "linear", magFilter = "linear", flipY = true } = options;
950
- gl.bindTexture(gl.TEXTURE_2D, texture);
951
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
952
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
953
- const { width, height } = getSourceDimensions(source);
954
- const pot = isPowerOfTwo(width) && isPowerOfTwo(height);
955
- const isWebGL2 = "texStorage2D" in gl;
956
- const actualMinFilter = minFilter === "mipmap" && (pot || isWebGL2) ? minFilter : minFilter === "mipmap" ? "linear" : minFilter;
957
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, getWrapMode(gl, wrapS));
958
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, getWrapMode(gl, wrapT));
959
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, getMinFilter(gl, actualMinFilter));
960
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, getMagFilter(gl, magFilter));
961
- if (actualMinFilter === "mipmap") {
962
- gl.generateMipmap(gl.TEXTURE_2D);
963
- }
964
- gl.bindTexture(gl.TEXTURE_2D, null);
965
- return texture;
966
- }
967
- function updateTexture(gl, texture, source, flipY = true) {
968
- gl.bindTexture(gl.TEXTURE_2D, texture);
969
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
970
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
971
- gl.bindTexture(gl.TEXTURE_2D, null);
972
- }
973
- function needsVideoUpdate(source) {
974
- if (!(source instanceof HTMLVideoElement))
975
- return false;
976
- return !source.paused && !source.ended && source.readyState >= 2;
977
- }
978
- function bindTextureUniform(gl, program, name, value, manager, locationCache) {
979
- const source = isTextureOptions(value) ? value.source : value;
980
- const options = isTextureOptions(value) ? value : {};
981
- let entry = manager.cache.get(name);
982
- if (entry && entry.source !== source) {
983
- gl.deleteTexture(entry.texture);
984
- entry = undefined;
985
- }
986
- if (!entry) {
987
- if (manager.nextUnit >= manager.maxUnits) {
988
- console.warn(`Maximum texture units (${manager.maxUnits}) exceeded for uniform "${name}"`);
989
- return;
990
- }
991
- const texture = createTexture(gl, source, options);
992
- entry = {
993
- texture,
994
- unit: manager.nextUnit++,
995
- source
996
- };
997
- manager.cache.set(name, entry);
998
- }
999
- if (needsVideoUpdate(source)) {
1000
- const flipY = isTextureOptions(value) ? value.flipY ?? true : true;
1001
- updateTexture(gl, entry.texture, source, flipY);
1002
- }
1003
- gl.activeTexture(gl.TEXTURE0 + entry.unit);
1004
- gl.bindTexture(gl.TEXTURE_2D, entry.texture);
1005
- let location = locationCache.get(name);
1006
- if (location === undefined) {
1007
- location = gl.getUniformLocation(program, name);
1008
- locationCache.set(name, location);
1009
- }
1010
- if (location !== null) {
1011
- gl.uniform1i(location, entry.unit);
1012
- }
1013
- }
1014
- function cleanupTextures(gl, manager) {
1015
- for (const entry of manager.cache.values()) {
1016
- gl.deleteTexture(entry.texture);
1017
- }
1018
- manager.cache.clear();
1019
- manager.nextUnit = 0;
1020
- }
1021
-
1022
- // src/utils/uniforms.ts
1023
- var MAX_ARRAY_LENGTH = 100;
1024
- function isVec22(value) {
1025
- return Array.isArray(value) && value.length === 2 && typeof value[0] === "number";
1026
- }
1027
- function isVec32(value) {
1028
- return Array.isArray(value) && value.length === 3 && typeof value[0] === "number";
1029
- }
1030
- function isVec42(value) {
1031
- return Array.isArray(value) && value.length === 4 && typeof value[0] === "number";
1032
- }
1033
- function isFloatArray(value) {
1034
- return Array.isArray(value) && value.length > 4 && typeof value[0] === "number";
1035
- }
1036
- function isVec2Array(value) {
1037
- return Array.isArray(value) && value.length > 0 && Array.isArray(value[0]) && value[0].length === 2;
1038
- }
1039
- function isVec3Array(value) {
1040
- return Array.isArray(value) && value.length > 0 && Array.isArray(value[0]) && value[0].length === 3;
1041
- }
1042
- function isVec4Array(value) {
1043
- return Array.isArray(value) && value.length > 0 && Array.isArray(value[0]) && value[0].length === 4;
1044
- }
1045
- function isArrayUniform(value) {
1046
- return isFloatArray(value) || isVec2Array(value) || isVec3Array(value) || isVec4Array(value);
1047
- }
1048
- function setUniform(gl, location, value) {
1049
- if (location === null) {
1050
- return;
1051
- }
1052
- if (typeof value === "number") {
1053
- gl.uniform1f(location, value);
1054
- } else if (isVec4Array(value)) {
1055
- gl.uniform4fv(location, value.flat());
1056
- } else if (isVec3Array(value)) {
1057
- gl.uniform3fv(location, value.flat());
1058
- } else if (isVec2Array(value)) {
1059
- gl.uniform2fv(location, value.flat());
1060
- } else if (isFloatArray(value)) {
1061
- gl.uniform1fv(location, value);
1062
- } else if (isVec42(value)) {
1063
- gl.uniform4f(location, value[0], value[1], value[2], value[3]);
1064
- } else if (isVec32(value)) {
1065
- gl.uniform3f(location, value[0], value[1], value[2]);
1066
- } else if (isVec22(value)) {
1067
- gl.uniform2f(location, value[0], value[1]);
1068
- }
1069
- }
1070
- function getUniformLocation(gl, program, name) {
1071
- return gl.getUniformLocation(program, name);
1072
- }
1073
- function setUniforms(gl, program, uniforms, locationCache, textureManager) {
1074
- for (const [name, value] of Object.entries(uniforms)) {
1075
- if (isTexture(value)) {
1076
- if (textureManager) {
1077
- bindTextureUniform(gl, program, name, value, textureManager, locationCache);
1078
- }
1079
- continue;
1080
- }
1081
- let location = locationCache.get(name);
1082
- if (location === undefined) {
1083
- location = getUniformLocation(gl, program, name);
1084
- locationCache.set(name, location);
1085
- }
1086
- setUniform(gl, location, value);
1087
- if (isArrayUniform(value)) {
1088
- const countName = `${name}_count`;
1089
- let countLocation = locationCache.get(countName);
1090
- if (countLocation === undefined) {
1091
- countLocation = getUniformLocation(gl, program, countName);
1092
- locationCache.set(countName, countLocation);
1093
- }
1094
- if (countLocation !== null) {
1095
- gl.uniform1i(countLocation, value.length);
1096
- }
1097
- }
1098
- }
1099
- }
1100
- function createUniformLocationCache() {
1101
- return new Map;
1102
- }
1103
- function getUniformType(value) {
1104
- if (isTexture(value)) {
1105
- return "sampler2D";
1106
- }
1107
- if (typeof value === "number") {
1108
- return "float";
1109
- }
1110
- if (isVec4Array(value)) {
1111
- return `vec4[${MAX_ARRAY_LENGTH}]`;
1112
- }
1113
- if (isVec3Array(value)) {
1114
- return `vec3[${MAX_ARRAY_LENGTH}]`;
1115
- }
1116
- if (isVec2Array(value)) {
1117
- return `vec2[${MAX_ARRAY_LENGTH}]`;
1118
- }
1119
- if (isFloatArray(value)) {
1120
- return `float[${MAX_ARRAY_LENGTH}]`;
1121
- }
1122
- if (isVec42(value)) {
1123
- return "vec4";
1124
- }
1125
- if (isVec32(value)) {
1126
- return "vec3";
1127
- }
1128
- if (isVec22(value)) {
1129
- return "vec2";
1130
- }
1131
- return "float";
1132
- }
1133
- function generateUniformDeclarations(uniforms) {
1134
- const lines = [];
1135
- for (const [name, value] of Object.entries(uniforms)) {
1136
- const type = getUniformType(value);
1137
- if (type.includes("[")) {
1138
- const [baseType, arrayPart] = type.split("[");
1139
- lines.push(`uniform ${baseType} ${name}[${arrayPart};`);
1140
- lines.push(`uniform int ${name}_count;`);
1141
- } else {
1142
- lines.push(`uniform ${type} ${name};`);
1143
- }
1144
- }
1145
- return lines.join(`
1146
- `);
1147
- }
1148
- var UNIFORM_MARKER = "// @UNIFORM_VALUES";
1149
- function injectUniformDeclarations(shaderSource, customUniforms, defaultUniforms) {
1150
- if (!shaderSource.includes(UNIFORM_MARKER)) {
1151
- return shaderSource;
1152
- }
1153
- const allUniforms = { ...defaultUniforms, ...customUniforms };
1154
- const declarations = generateUniformDeclarations(allUniforms);
1155
- return shaderSource.replace(UNIFORM_MARKER, declarations);
1156
- }
1157
-
1158
- // src/hooks/useWebGL.ts
1159
- var DEFAULT_UNIFORM_TYPES = {
1160
- iTime: 0,
1161
- iMouse: [0, 0],
1162
- iMouseNormalized: [0, 0],
1163
- iMouseLeftDown: 0,
1164
- iResolution: [0, 0]
1165
- };
1166
- function initializeWebGL(canvas, vertexSource, fragmentSource, customUniforms) {
1167
- const gl = canvas.getContext("webgl2") || canvas.getContext("webgl");
1168
- if (!gl) {
1169
- throw new Error("WebGL not supported");
1170
- }
1171
- const processedVertex = injectUniformDeclarations(vertexSource, customUniforms, DEFAULT_UNIFORM_TYPES);
1172
- const processedFragment = injectUniformDeclarations(fragmentSource, customUniforms, DEFAULT_UNIFORM_TYPES);
1173
- const program = createShaderProgram(gl, processedVertex, processedFragment);
1174
- const positionBuffer = gl.createBuffer();
1175
- if (!positionBuffer) {
1176
- throw new Error("Failed to create position buffer");
1177
- }
1178
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
1179
- const positions = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);
1180
- gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
1181
- const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
1182
- if (positionAttributeLocation === -1) {
1183
- throw new Error('Vertex shader must have an "a_position" attribute');
1184
- }
1185
- return {
1186
- gl,
1187
- program,
1188
- positionBuffer,
1189
- positionAttributeLocation,
1190
- uniformLocationCache: createUniformLocationCache(),
1191
- textureManager: createTextureManager(gl)
1192
- };
1193
- }
1194
- function cleanupWebGL(gl, state) {
1195
- cleanupTextures(gl, state.textureManager);
1196
- gl.deleteBuffer(state.positionBuffer);
1197
- gl.deleteProgram(state.program);
1198
- }
1199
- function useWebGL(options) {
1200
- const canvasRef = useRef3(null);
1201
- const stateRef = useRef3(null);
1202
- const animationFrameRef = useRef3(0);
1203
- const elapsedTimeRef = useRef3(0);
1204
- const lastFrameTimeRef = useRef3(0);
1205
- const mouseRef = useRef3([0, 0]);
1206
- const mouseNormalizedRef = useRef3([0, 0]);
1207
- const mouseLeftDownRef = useRef3(false);
1208
- const canvasRectRef = useRef3(null);
1209
- const contextLostRef = useRef3(false);
1210
- const uniformsRef = useRef3(options.uniforms);
1211
- const onErrorRef = useRef3(options.onError);
1212
- const onFrameRef = useRef3(options.onFrame);
1213
- const onClickRef = useRef3(options.onClick);
1214
- const onMouseDownRef = useRef3(options.onMouseDown);
1215
- const onMouseUpRef = useRef3(options.onMouseUp);
1216
- const onMouseMoveRef = useRef3(options.onMouseMove);
1217
- const onMouseWheelRef = useRef3(options.onMouseWheel);
1218
- const timeScaleRef = useRef3(options.timeScale ?? 1);
1219
- const vertexRef = useRef3(options.vertex);
1220
- const fragmentRef = useRef3(options.fragment);
1221
- const dprRef = useRef3(window.devicePixelRatio || 1);
1222
- const defaultUniformsRef = useRef3({
1223
- iTime: 0,
1224
- iMouse: [0, 0],
1225
- iMouseNormalized: [0, 0],
1226
- iMouseLeftDown: 0,
1227
- iResolution: [0, 0]
1228
- });
1229
- uniformsRef.current = options.uniforms;
1230
- onErrorRef.current = options.onError;
1231
- onFrameRef.current = options.onFrame;
1232
- onClickRef.current = options.onClick;
1233
- onMouseDownRef.current = options.onMouseDown;
1234
- onMouseUpRef.current = options.onMouseUp;
1235
- onMouseMoveRef.current = options.onMouseMove;
1236
- onMouseWheelRef.current = options.onMouseWheel;
1237
- timeScaleRef.current = options.timeScale ?? 1;
1238
- vertexRef.current = options.vertex;
1239
- fragmentRef.current = options.fragment;
1240
- const render = useCallback4((time) => {
1241
- if (contextLostRef.current)
1242
- return;
1243
- const state = stateRef.current;
1244
- const canvas = canvasRef.current;
1245
- if (!state || !canvas)
1246
- return;
1247
- const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
1248
- lastFrameTimeRef.current = time;
1249
- elapsedTimeRef.current += deltaTime * timeScaleRef.current;
1250
- const { gl, program, positionAttributeLocation, uniformLocationCache, textureManager } = state;
1251
- const elapsedTime = elapsedTimeRef.current;
1252
- const dpr = dprRef.current;
1253
- const displayWidth = canvas.clientWidth;
1254
- const displayHeight = canvas.clientHeight;
1255
- if (displayWidth === 0 || displayHeight === 0) {
1256
- animationFrameRef.current = requestAnimationFrame(render);
1257
- return;
1258
- }
1259
- const bufferWidth = Math.round(displayWidth * dpr);
1260
- const bufferHeight = Math.round(displayHeight * dpr);
1261
- if (canvas.width !== bufferWidth || canvas.height !== bufferHeight) {
1262
- canvas.width = bufferWidth;
1263
- canvas.height = bufferHeight;
1264
- gl.viewport(0, 0, bufferWidth, bufferHeight);
1265
- }
1266
- gl.clearColor(0, 0, 0, 1);
1267
- gl.clear(gl.COLOR_BUFFER_BIT);
1268
- gl.useProgram(program);
1269
- gl.enableVertexAttribArray(positionAttributeLocation);
1270
- gl.bindBuffer(gl.ARRAY_BUFFER, state.positionBuffer);
1271
- gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
1272
- const defaultUniforms = defaultUniformsRef.current;
1273
- defaultUniforms.iTime = elapsedTime;
1274
- defaultUniforms.iMouse = mouseRef.current;
1275
- defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
1276
- defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
1277
- defaultUniforms.iResolution = [canvas.width, canvas.height];
1278
- setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache, textureManager);
1279
- gl.drawArrays(gl.TRIANGLES, 0, 6);
1280
- if (onFrameRef.current) {
1281
- onFrameRef.current({
1282
- deltaTime,
1283
- time: elapsedTime,
1284
- resolution: [canvas.width, canvas.height],
1285
- mouse: mouseRef.current,
1286
- mouseNormalized: mouseNormalizedRef.current,
1287
- mouseLeftDown: mouseLeftDownRef.current
1288
- });
1289
- }
1290
- animationFrameRef.current = requestAnimationFrame(render);
1291
- }, []);
1292
- useEffect3(() => {
1293
- const canvas = canvasRef.current;
1294
- if (!canvas)
1295
- return;
1296
- const initialize = () => {
1297
- try {
1298
- stateRef.current = initializeWebGL(canvas, vertexRef.current, fragmentRef.current, uniformsRef.current);
1299
- elapsedTimeRef.current = 0;
1300
- lastFrameTimeRef.current = 0;
1301
- contextLostRef.current = false;
1302
- animationFrameRef.current = requestAnimationFrame(render);
1303
- } catch (err) {
1304
- const error = err instanceof Error ? err : new Error(String(err));
1305
- if (onErrorRef.current) {
1306
- onErrorRef.current(error);
1307
- } else {
1308
- console.error("WebGL initialization failed:", error);
1309
- }
1310
- }
1311
- };
1312
- const handleContextLost = (event) => {
1313
- event.preventDefault();
1314
- contextLostRef.current = true;
1315
- cancelAnimationFrame(animationFrameRef.current);
1316
- stateRef.current = null;
1317
- };
1318
- const handleContextRestored = () => {
1319
- initialize();
1320
- };
1321
- const dprMediaQuery = window.matchMedia(`(resolution: ${dprRef.current}dppx)`);
1322
- const handleDprChange = () => {
1323
- dprRef.current = window.devicePixelRatio || 1;
1324
- };
1325
- dprMediaQuery.addEventListener("change", handleDprChange);
1326
- canvas.addEventListener("webglcontextlost", handleContextLost);
1327
- canvas.addEventListener("webglcontextrestored", handleContextRestored);
1328
- initialize();
1329
- return () => {
1330
- dprMediaQuery.removeEventListener("change", handleDprChange);
1331
- canvas.removeEventListener("webglcontextlost", handleContextLost);
1332
- canvas.removeEventListener("webglcontextrestored", handleContextRestored);
1333
- cancelAnimationFrame(animationFrameRef.current);
1334
- if (stateRef.current) {
1335
- cleanupWebGL(stateRef.current.gl, stateRef.current);
1336
- stateRef.current = null;
1337
- }
1338
- };
1339
- }, [render]);
1340
- useEffect3(() => {
1341
- const canvas = canvasRef.current;
1342
- if (!canvas)
1343
- return;
1344
- const updateRect = () => {
1345
- canvasRectRef.current = canvas.getBoundingClientRect();
1346
- };
1347
- updateRect();
1348
- const resizeObserver = new ResizeObserver(updateRect);
1349
- resizeObserver.observe(canvas);
1350
- window.addEventListener("scroll", updateRect, { passive: true });
1351
- const handleMouseMove = (event) => {
1352
- const rect = canvasRectRef.current;
1353
- if (!rect)
1354
- return;
1355
- const dpr = dprRef.current;
1356
- const x = (event.clientX - rect.left) * dpr;
1357
- const y = (rect.height - (event.clientY - rect.top)) * dpr;
1358
- mouseRef.current = [x, y];
1359
- const minDimension = Math.min(canvas.width, canvas.height) || 1;
1360
- mouseNormalizedRef.current = [
1361
- (mouseRef.current[0] - canvas.width / 2) / minDimension,
1362
- (mouseRef.current[1] - canvas.height / 2) / minDimension
1363
- ];
1364
- onMouseMoveRef.current?.({
1365
- deltaTime: 0,
1366
- time: elapsedTimeRef.current,
1367
- resolution: [canvas.width, canvas.height],
1368
- mouse: mouseRef.current,
1369
- mouseNormalized: mouseNormalizedRef.current,
1370
- mouseLeftDown: mouseLeftDownRef.current
1371
- });
1372
- };
1373
- const handleMouseDown = (event) => {
1374
- if (event.button === 0) {
1375
- mouseLeftDownRef.current = true;
1376
- }
1377
- onMouseDownRef.current?.({
1378
- deltaTime: 0,
1379
- time: elapsedTimeRef.current,
1380
- resolution: [canvas.width, canvas.height],
1381
- mouse: mouseRef.current,
1382
- mouseNormalized: mouseNormalizedRef.current,
1383
- mouseLeftDown: mouseLeftDownRef.current
1384
- });
1385
- };
1386
- const handleMouseUp = (event) => {
1387
- if (event.button === 0) {
1388
- mouseLeftDownRef.current = false;
1389
- }
1390
- onMouseUpRef.current?.({
1391
- deltaTime: 0,
1392
- time: elapsedTimeRef.current,
1393
- resolution: [canvas.width, canvas.height],
1394
- mouse: mouseRef.current,
1395
- mouseNormalized: mouseNormalizedRef.current,
1396
- mouseLeftDown: mouseLeftDownRef.current
1397
- });
1398
- };
1399
- const handleClick = () => {
1400
- if (!onClickRef.current)
1401
- return;
1402
- onClickRef.current({
1403
- deltaTime: 0,
1404
- time: elapsedTimeRef.current,
1405
- resolution: [canvas.width, canvas.height],
1406
- mouse: mouseRef.current,
1407
- mouseNormalized: mouseNormalizedRef.current,
1408
- mouseLeftDown: mouseLeftDownRef.current
1409
- });
1410
- };
1411
- const handleMouseWheel = (event) => {
1412
- onMouseWheelRef.current?.({
1413
- deltaTime: 0,
1414
- time: elapsedTimeRef.current,
1415
- resolution: [canvas.width, canvas.height],
1416
- mouse: mouseRef.current,
1417
- mouseNormalized: mouseNormalizedRef.current,
1418
- mouseLeftDown: mouseLeftDownRef.current
1419
- }, event.deltaY);
1420
- };
1421
- window.addEventListener("mousemove", handleMouseMove);
1422
- window.addEventListener("mousedown", handleMouseDown);
1423
- window.addEventListener("mouseup", handleMouseUp);
1424
- canvas.addEventListener("click", handleClick);
1425
- window.addEventListener("wheel", handleMouseWheel);
1426
- return () => {
1427
- resizeObserver.disconnect();
1428
- window.removeEventListener("scroll", updateRect);
1429
- window.removeEventListener("mousemove", handleMouseMove);
1430
- window.removeEventListener("mousedown", handleMouseDown);
1431
- window.removeEventListener("mouseup", handleMouseUp);
1432
- canvas.removeEventListener("click", handleClick);
1433
- window.removeEventListener("wheel", handleMouseWheel);
1434
- };
1435
- }, []);
1436
- return { canvasRef, mouseRef };
1437
- }
1438
-
1439
- // src/ReactShader.tsx
1440
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
1441
- var DEFAULT_VERTEX = `#version 300 es
1442
- precision highp float;
1443
- in vec2 a_position;
1444
-
1445
- void main() {
1446
- gl_Position = vec4(a_position, 0.0, 1.0);
1447
- }
1448
- `;
1449
- var FULLSCREEN_CONTAINER_STYLE2 = {
1450
- position: "fixed",
1451
- top: 0,
1452
- left: 0,
1453
- width: "100vw",
1454
- height: "100vh",
1455
- zIndex: 9000
1456
- };
1457
- var DEFAULT_CONTAINER_STYLE2 = {
1458
- position: "relative",
1459
- width: "100%",
1460
- height: "100%"
1461
- };
1462
- var CANVAS_STYLE2 = {
1463
- display: "block",
1464
- width: "100%",
1465
- height: "100%"
1466
- };
1467
- function ReactShader({
1468
- className,
1469
- fragment,
1470
- vertex = DEFAULT_VERTEX,
1471
- uniforms,
1472
- fullscreen = false,
1473
- timeScale = 1,
1474
- onFrame,
1475
- onClick,
1476
- onMouseMove,
1477
- onMouseDown,
1478
- onMouseUp,
1479
- onMouseWheel
1480
- }) {
1481
- const [error, setError] = useState3(null);
1482
- const handleError = useCallback5((err) => {
1483
- setError(err.message);
1484
- console.error("ReactShader error:", err);
1485
- }, []);
1486
- useEffect4(() => {
1487
- setError(null);
1488
- }, [fragment, vertex]);
1489
- const { canvasRef } = useWebGL({
1490
- fragment,
1491
- vertex,
1492
- uniforms,
1493
- onError: handleError,
1494
- onFrame,
1495
- onClick,
1496
- onMouseMove,
1497
- onMouseDown,
1498
- onMouseUp,
1499
- onMouseWheel,
1500
- timeScale
1501
- });
1502
- const containerStyle = useMemo2(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE2 : DEFAULT_CONTAINER_STYLE2, [fullscreen]);
1503
- if (error) {
1504
- return /* @__PURE__ */ jsxDEV2("div", {
1505
- className,
1506
- style: {
1507
- ...containerStyle,
1508
- display: "flex",
1509
- alignItems: "center",
1510
- justifyContent: "center",
1511
- backgroundColor: "#1a1a1a",
1512
- color: "#ff6b6b",
1513
- fontFamily: "monospace",
1514
- fontSize: "12px",
1515
- padding: "16px",
1516
- overflow: "auto",
1517
- boxSizing: "border-box",
1518
- width: "100%",
1519
- height: "100%"
1520
- },
1521
- children: /* @__PURE__ */ jsxDEV2("pre", {
1522
- style: { margin: 0, whiteSpace: "pre-wrap" },
1523
- children: error
1524
- }, undefined, false, undefined, this)
1525
- }, undefined, false, undefined, this);
1526
- }
1527
- return /* @__PURE__ */ jsxDEV2("canvas", {
1528
- ref: canvasRef,
1529
- className,
1530
- style: CANVAS_STYLE2
1531
- }, undefined, false, undefined, this);
1532
- }
1533
- // src/shaders/color-palette.ts
1534
- function generateColorPaletteFunction(name, paletteString) {
1535
- const paletteArray = paletteString.replace("[[", "").replace("]]", "").split("] [").map((s) => s.split(" "));
1536
- return `
1537
- vec3 ${name}( float t ) {
1538
- vec3 a = vec3(${paletteArray[0].join(",")});
1539
- vec3 b = vec3(${paletteArray[1].join(",")});
1540
- vec3 c = vec3(${paletteArray[2].join(",")});
1541
- vec3 d = vec3(${paletteArray[3].join(",")});
1542
- return a + b * cos(6.28318 * (c * t + d));
1543
- }
1544
- `;
1545
- }
1546
822
  // src/shaders/color-palette-gpu.ts
1547
823
  function generateColorPaletteFunctionGpu(name, paletteString) {
1548
824
  const paletteArray = paletteString.replace("[[", "").replace("]]", "").split("] [").map((s) => s.split(" "));
@@ -1556,29 +832,6 @@ fn ${name}(t: f32) -> vec3f {
1556
832
  }
1557
833
  `;
1558
834
  }
1559
- // src/shaders/distortion-ripple.ts
1560
- function generateDistortionRippleFunction() {
1561
- return `
1562
- vec2 DistortionRipple(vec2 uv, vec2 center, float radius, float intensity, float thickness) {
1563
- // 1. Calculate vector and distance from center
1564
- vec2 dir = uv - center;
1565
- float dist = length(dir);
1566
-
1567
- // 2. Create a mask so the ripple only exists near the radius Z
1568
- // Using smoothstep creates a soft edge for the ripple
1569
- float mask = smoothstep(radius + thickness, radius, dist) * smoothstep(radius - thickness, radius, dist);
1570
-
1571
- // 3. Calculate the displacement amount using a Sine wave
1572
- // We subtract dist from radius to orient the wave correctly
1573
- float wave = sin((dist - radius) * 20.0);
1574
-
1575
- // 4. Apply intensity and mask, then offset the UV
1576
- vec2 offset = normalize(dir) * wave * intensity * mask;
1577
-
1578
- return offset;
1579
- }
1580
- `;
1581
- }
1582
835
  // src/shaders/distortion-ripple-gpu.ts
1583
836
  function generateDistortionRippleFunctionGpu() {
1584
837
  return `
@@ -1602,40 +855,6 @@ fn DistortionRipple(uv: vec2f, center: vec2f, radius: f32, intensity: f32, thick
1602
855
  }
1603
856
  `;
1604
857
  }
1605
- // src/shaders/scene-circles.ts
1606
- function generateSceneCirclesFunction(paletteString = "[[0.5 0.5 0.5] [0.5 0.5 0.5] [1.0 1.0 1.0] [0.263 0.416 0.557]]") {
1607
- return `
1608
- ${generateColorPaletteFunction("circlesPalette", paletteString)}
1609
-
1610
- vec3 SceneCircles(
1611
- vec2 uv0,
1612
- float iterations,
1613
- float fractMultiplier,
1614
- float time,
1615
- float waveLength,
1616
- float edgeBlur,
1617
- float contrast
1618
- ) {
1619
- vec3 col = vec3(0.0);
1620
- vec2 uv = uv0;
1621
-
1622
- for (float i = 0.0; i < iterations; i++) {
1623
- uv = fract(uv * fractMultiplier) - 0.5;
1624
-
1625
- float d = length(uv) * exp(-length(uv0));
1626
-
1627
- vec3 color = circlesPalette(length(uv0) + i * 0.4 + time * 0.4);
1628
-
1629
- d = sin(d * waveLength + time) / waveLength;
1630
- d = abs(d);
1631
- d = pow(edgeBlur / d, contrast);
1632
-
1633
- col += color * d;
1634
- }
1635
- return col;
1636
- }
1637
- `;
1638
- }
1639
858
  // src/shaders/scene-circles-gpu.ts
1640
859
  function generateSceneCirclesFunctionGpu(paletteString = "[[0.5 0.5 0.5] [0.5 0.5 0.5] [1.0 1.0 1.0] [0.263 0.416 0.557]]") {
1641
860
  return `
@@ -1674,190 +893,6 @@ fn SceneCircles(
1674
893
  }
1675
894
  `;
1676
895
  }
1677
- // src/shaders/simplex-noise.ts
1678
- function generateSimplexNoiseFunction() {
1679
- return `
1680
-
1681
- vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
1682
-
1683
- vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
1684
-
1685
- float mod289(float x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
1686
-
1687
- vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); }
1688
-
1689
- float permute(float x) { return mod289(((x*34.0)+10.0)*x); }
1690
-
1691
- vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
1692
-
1693
- float taylorInvSqrt(float r) { return 1.79284291400159 - 0.85373472095314 * r; }
1694
-
1695
- vec4 grad4(float j, vec4 ip) {
1696
- const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
1697
- vec4 p,s;
1698
-
1699
- p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
1700
- p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
1701
- s = vec4(lessThan(p, vec4(0.0)));
1702
- p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;
1703
-
1704
- return p;
1705
- }
1706
-
1707
- // (sqrt(5) - 1)/4 = F4, used once below
1708
- #define F4 0.309016994374947451
1709
-
1710
- float SimplexNoise4D(vec4 v) {
1711
- const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4
1712
- 0.276393202250021, // 2 * G4
1713
- 0.414589803375032, // 3 * G4
1714
- -0.447213595499958); // -1 + 4 * G4
1715
-
1716
- // First corner
1717
- vec4 i = floor(v + dot(v, vec4(F4)) );
1718
- vec4 x0 = v - i + dot(i, C.xxxx);
1719
-
1720
- // Other corners
1721
-
1722
- // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
1723
- vec4 i0;
1724
- vec3 isX = step( x0.yzw, x0.xxx );
1725
- vec3 isYZ = step( x0.zww, x0.yyz );
1726
- // i0.x = dot( isX, vec3( 1.0 ) );
1727
- i0.x = isX.x + isX.y + isX.z;
1728
- i0.yzw = 1.0 - isX;
1729
- // i0.y += dot( isYZ.xy, vec2( 1.0 ) );
1730
- i0.y += isYZ.x + isYZ.y;
1731
- i0.zw += 1.0 - isYZ.xy;
1732
- i0.z += isYZ.z;
1733
- i0.w += 1.0 - isYZ.z;
1734
-
1735
- // i0 now contains the unique values 0,1,2,3 in each channel
1736
- vec4 i3 = clamp( i0, 0.0, 1.0 );
1737
- vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );
1738
- vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );
1739
-
1740
- // x0 = x0 - 0.0 + 0.0 * C.xxxx
1741
- // x1 = x0 - i1 + 1.0 * C.xxxx
1742
- // x2 = x0 - i2 + 2.0 * C.xxxx
1743
- // x3 = x0 - i3 + 3.0 * C.xxxx
1744
- // x4 = x0 - 1.0 + 4.0 * C.xxxx
1745
- vec4 x1 = x0 - i1 + C.xxxx;
1746
- vec4 x2 = x0 - i2 + C.yyyy;
1747
- vec4 x3 = x0 - i3 + C.zzzz;
1748
- vec4 x4 = x0 + C.wwww;
1749
-
1750
- // Permutations
1751
- i = mod289(i);
1752
- float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);
1753
- vec4 j1 = permute( permute( permute( permute (
1754
- i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))
1755
- + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))
1756
- + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))
1757
- + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));
1758
-
1759
- // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
1760
- // 7*7*6 = 294, which is close to the ring size 17*17 = 289.
1761
- vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;
1762
-
1763
- vec4 p0 = grad4(j0, ip);
1764
- vec4 p1 = grad4(j1.x, ip);
1765
- vec4 p2 = grad4(j1.y, ip);
1766
- vec4 p3 = grad4(j1.z, ip);
1767
- vec4 p4 = grad4(j1.w, ip);
1768
-
1769
- // Normalise gradients
1770
- vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
1771
- p0 *= norm.x;
1772
- p1 *= norm.y;
1773
- p2 *= norm.z;
1774
- p3 *= norm.w;
1775
- p4 *= taylorInvSqrt(dot(p4,p4));
1776
-
1777
- // Mix contributions from the five corners
1778
- vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
1779
- vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);
1780
- m0 = m0 * m0;
1781
- m1 = m1 * m1;
1782
- return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
1783
- + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
1784
- }
1785
-
1786
- float SimplexNoise3D(vec3 v) {
1787
- const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
1788
- const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
1789
-
1790
- // First corner
1791
- vec3 i = floor(v + dot(v, C.yyy) );
1792
- vec3 x0 = v - i + dot(i, C.xxx) ;
1793
-
1794
- // Other corners
1795
- vec3 g = step(x0.yzx, x0.xyz);
1796
- vec3 l = 1.0 - g;
1797
- vec3 i1 = min( g.xyz, l.zxy );
1798
- vec3 i2 = max( g.xyz, l.zxy );
1799
-
1800
- // x0 = x0 - 0.0 + 0.0 * C.xxx;
1801
- // x1 = x0 - i1 + 1.0 * C.xxx;
1802
- // x2 = x0 - i2 + 2.0 * C.xxx;
1803
- // x3 = x0 - 1.0 + 3.0 * C.xxx;
1804
- vec3 x1 = x0 - i1 + C.xxx;
1805
- vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
1806
- vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
1807
-
1808
- // Permutations
1809
- i = mod289(i);
1810
- vec4 p = permute( permute( permute(
1811
- i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
1812
- + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
1813
- + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
1814
-
1815
- // Gradients: 7x7 points over a square, mapped onto an octahedron.
1816
- // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
1817
- float n_ = 0.142857142857; // 1.0/7.0
1818
- vec3 ns = n_ * D.wyz - D.xzx;
1819
-
1820
- vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
1821
-
1822
- vec4 x_ = floor(j * ns.z);
1823
- vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
1824
-
1825
- vec4 x = x_ *ns.x + ns.yyyy;
1826
- vec4 y = y_ *ns.x + ns.yyyy;
1827
- vec4 h = 1.0 - abs(x) - abs(y);
1828
-
1829
- vec4 b0 = vec4( x.xy, y.xy );
1830
- vec4 b1 = vec4( x.zw, y.zw );
1831
-
1832
- //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
1833
- //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
1834
- vec4 s0 = floor(b0)*2.0 + 1.0;
1835
- vec4 s1 = floor(b1)*2.0 + 1.0;
1836
- vec4 sh = -step(h, vec4(0.0));
1837
-
1838
- vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
1839
- vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
1840
-
1841
- vec3 p0 = vec3(a0.xy,h.x);
1842
- vec3 p1 = vec3(a0.zw,h.y);
1843
- vec3 p2 = vec3(a1.xy,h.z);
1844
- vec3 p3 = vec3(a1.zw,h.w);
1845
-
1846
- // Normalise gradients
1847
- vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
1848
- p0 *= norm.x;
1849
- p1 *= norm.y;
1850
- p2 *= norm.z;
1851
- p3 *= norm.w;
1852
-
1853
- // Mix final noise value
1854
- vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
1855
- m = m * m;
1856
- return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
1857
- dot(p2,x2), dot(p3,x3) ) );
1858
- }
1859
- `;
1860
- }
1861
896
  // src/shaders/simplex-noise-gpu.ts
1862
897
  function generateSimplexNoiseFunctionGpu() {
1863
898
  return `
@@ -2033,29 +1068,11 @@ fn SimplexNoise3D(v: vec3f) -> f32 {
2033
1068
  }
2034
1069
  `;
2035
1070
  }
2036
- // src/shaders/utils.ts
2037
- function generateUtilsFunction() {
2038
- return `
2039
- vec2 GetUv(vec2 fragCoord, vec2 resolution) {
2040
- return (fragCoord - 0.5 * resolution) / resolution.y;
2041
- }
2042
-
2043
- vec2 GetMouse(vec2 mouse, vec2 resolution) {
2044
- return (mouse - 0.5 * resolution) / resolution.y;
2045
- }
2046
- `;
2047
- }
2048
1071
  export {
2049
1072
  useAudio,
2050
- generateUtilsFunction,
2051
1073
  generateSimplexNoiseFunctionGpu,
2052
- generateSimplexNoiseFunction,
2053
1074
  generateSceneCirclesFunctionGpu,
2054
- generateSceneCirclesFunction,
2055
1075
  generateDistortionRippleFunctionGpu,
2056
- generateDistortionRippleFunction,
2057
1076
  generateColorPaletteFunctionGpu,
2058
- generateColorPaletteFunction,
2059
- ReactShader,
2060
1077
  ReactGpuShader
2061
1078
  };