@3driseai/3drise-core 1.0.1 → 1.0.2

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.
Files changed (45) hide show
  1. package/dist/services/MaterialRegistry.d.ts +25 -0
  2. package/dist/services/MaterialRegistry.d.ts.map +1 -1
  3. package/dist/services/MaterialRegistry.js +102 -1
  4. package/dist/shaders/CircuitGridMaterial.d.ts +76 -0
  5. package/dist/shaders/CircuitGridMaterial.d.ts.map +1 -0
  6. package/dist/shaders/CircuitGridMaterial.js +298 -0
  7. package/dist/shaders/ContourGridMaterial.d.ts +80 -0
  8. package/dist/shaders/ContourGridMaterial.d.ts.map +1 -0
  9. package/dist/shaders/ContourGridMaterial.js +259 -0
  10. package/dist/shaders/FractalGridMaterial.d.ts +76 -0
  11. package/dist/shaders/FractalGridMaterial.d.ts.map +1 -0
  12. package/dist/shaders/FractalGridMaterial.js +247 -0
  13. package/dist/shaders/HexGridMaterial.d.ts +73 -0
  14. package/dist/shaders/HexGridMaterial.d.ts.map +1 -0
  15. package/dist/shaders/HexGridMaterial.js +265 -0
  16. package/dist/shaders/MoireGridMaterial.d.ts +79 -0
  17. package/dist/shaders/MoireGridMaterial.d.ts.map +1 -0
  18. package/dist/shaders/MoireGridMaterial.js +271 -0
  19. package/dist/shaders/MyGridMaterial.d.ts +7 -0
  20. package/dist/shaders/MyGridMaterial.d.ts.map +1 -1
  21. package/dist/shaders/MyGridMaterial.js +19 -0
  22. package/dist/shaders/QuasiGridMaterial.d.ts +76 -0
  23. package/dist/shaders/QuasiGridMaterial.d.ts.map +1 -0
  24. package/dist/shaders/QuasiGridMaterial.js +238 -0
  25. package/dist/shaders/RadarGridMaterial.d.ts +77 -0
  26. package/dist/shaders/RadarGridMaterial.d.ts.map +1 -0
  27. package/dist/shaders/RadarGridMaterial.js +291 -0
  28. package/dist/shaders/RainMaterial copy.d.ts +34 -0
  29. package/dist/shaders/RainMaterial copy.d.ts.map +1 -0
  30. package/dist/shaders/RainMaterial copy.js +56 -0
  31. package/dist/shaders/ShaderEffectsMaterial copy 2.d.ts +228 -0
  32. package/dist/shaders/ShaderEffectsMaterial copy 2.d.ts.map +1 -0
  33. package/dist/shaders/ShaderEffectsMaterial copy 2.js +233 -0
  34. package/dist/shaders/ShootingStarMaterial copy.d.ts +14 -0
  35. package/dist/shaders/ShootingStarMaterial copy.d.ts.map +1 -0
  36. package/dist/shaders/ShootingStarMaterial copy.js +33 -0
  37. package/dist/shaders/SkyboxMaterial copy.d.ts +38 -0
  38. package/dist/shaders/SkyboxMaterial copy.d.ts.map +1 -0
  39. package/dist/shaders/SkyboxMaterial copy.js +57 -0
  40. package/dist/shaders/VoronoiGridMaterial.d.ts +73 -0
  41. package/dist/shaders/VoronoiGridMaterial.d.ts.map +1 -0
  42. package/dist/shaders/VoronoiGridMaterial.js +266 -0
  43. package/dist/types/objectsConfigs.d.ts +12 -0
  44. package/dist/types/objectsConfigs.d.ts.map +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,259 @@
1
+ import * as THREE from 'three';
2
+ import { shaderMaterial } from '@react-three/drei';
3
+ import { extend } from '@react-three/fiber';
4
+ export const contourGridMaterialDefaults = {
5
+ u_time: 0,
6
+ u_cellSize: 14.0,
7
+ u_lineWidth: 1.0,
8
+ u_sectionSize: 5.0,
9
+ u_sectionWidth: 2.2,
10
+ u_lineColor: new THREE.Color(0.35, 0.85, 0.7),
11
+ u_sectionColor: new THREE.Color(0.75, 0.95, 0.6),
12
+ u_cellColor: new THREE.Color(0.1, 0.36, 0.32),
13
+ u_glowColor: new THREE.Color(0.55, 1.0, 0.75),
14
+ u_bgColor: new THREE.Color(0.01, 0.04, 0.04),
15
+ u_bgOpacity: 0.0,
16
+ u_lineMode: 0,
17
+ u_cellMode: 1,
18
+ u_animSpeed: 1.0,
19
+ u_animScale: 0.5,
20
+ u_animIntensity: 1.0,
21
+ u_fadeDistance: 25.0,
22
+ u_fadeStrength: 0.7,
23
+ u_focus: new THREE.Vector2(0, 0),
24
+ u_mouse: new THREE.Vector2(0, 0),
25
+ u_displace: 0.0,
26
+ u_reveal: 1.0,
27
+ u_levels: 16.0,
28
+ u_roughness: 0.5,
29
+ u_warp: 0.35,
30
+ };
31
+ /**
32
+ * Shared by both stages — and it has to be, exactly. The vertex stage displaces
33
+ * to `terrain()` and the fragment stage draws contours of the same function, so
34
+ * any divergence between the two would slide the lines off the landform they
35
+ * are supposed to be describing.
36
+ */
37
+ const contourCommon = /*glsl*/ `
38
+ const float TAU = 6.28318530718;
39
+
40
+ float hash21(vec2 p){
41
+ p = fract(p * vec2(123.34, 456.21));
42
+ p += dot(p, p + 45.32);
43
+ return fract(p.x * p.y);
44
+ }
45
+
46
+ float vnoise(vec2 p){
47
+ vec2 i = floor(p);
48
+ vec2 f = fract(p);
49
+ f = f * f * (3.0 - 2.0 * f);
50
+ float a = hash21(i);
51
+ float b = hash21(i + vec2(1.0, 0.0));
52
+ float c = hash21(i + vec2(0.0, 1.0));
53
+ float d = hash21(i + vec2(1.0, 1.0));
54
+ return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
55
+ }
56
+
57
+ float fbm(vec2 p, float gain){
58
+ float sum = 0.0;
59
+ float amp = 0.5;
60
+ float tot = 0.0;
61
+ for (int i = 0; i < 5; i++){
62
+ sum += amp * vnoise(p);
63
+ tot += amp;
64
+ p *= 2.02;
65
+ amp *= gain;
66
+ }
67
+ return sum / max(tot, 1e-5);
68
+ }
69
+
70
+ /** 0..1 elevation at a point, drifting with time */
71
+ float terrain(vec2 p, float t, float gain, float warp){
72
+ vec2 q = p;
73
+ if (warp > 0.0){
74
+ q += warp * vec2(
75
+ fbm(p + vec2(1.7, 9.2), gain),
76
+ fbm(p + vec2(8.3, 2.8), gain)
77
+ );
78
+ }
79
+ // Value-noise fbm clusters hard around 0.5, which would leave most of the
80
+ // contour range unused and only a handful of lines on screen. Stretching it
81
+ // about the midpoint spreads the elevation across the full 0..1 band set.
82
+ float h = fbm(q + vec2(0.0, t * 0.05), gain);
83
+ return clamp((h - 0.5) * 2.2 + 0.5, 0.0, 1.0);
84
+ }
85
+ `;
86
+ const vertex = /*glsl*/ `
87
+ uniform float u_time;
88
+ uniform float u_cellSize;
89
+ uniform float u_displace;
90
+ uniform float u_animSpeed;
91
+ uniform float u_roughness;
92
+ uniform float u_warp;
93
+
94
+ varying vec2 vGridPos;
95
+
96
+ ${contourCommon}
97
+
98
+ void main(){
99
+ vGridPos = position.xy;
100
+ vec3 pos = position;
101
+ if (u_displace > 0.0){
102
+ float t = u_time * u_animSpeed;
103
+ vec2 coord = position.xy / max(u_cellSize, 1e-4);
104
+ pos.z += terrain(coord, t, u_roughness, u_warp) * u_displace;
105
+ }
106
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
107
+ }
108
+ `;
109
+ const fragment = /*glsl*/ `
110
+ precision highp float;
111
+
112
+ uniform float u_time;
113
+ uniform float u_cellSize;
114
+ uniform float u_lineWidth;
115
+ uniform float u_sectionSize;
116
+ uniform float u_sectionWidth;
117
+ uniform vec3 u_lineColor;
118
+ uniform vec3 u_sectionColor;
119
+ uniform vec3 u_cellColor;
120
+ uniform vec3 u_glowColor;
121
+ uniform vec3 u_bgColor;
122
+ uniform float u_bgOpacity;
123
+ uniform float u_lineMode;
124
+ uniform float u_cellMode;
125
+ uniform float u_animSpeed;
126
+ uniform float u_animScale;
127
+ uniform float u_animIntensity;
128
+ uniform float u_fadeDistance;
129
+ uniform float u_fadeStrength;
130
+ uniform vec2 u_focus;
131
+ uniform float u_reveal;
132
+ uniform float u_levels;
133
+ uniform float u_roughness;
134
+ uniform float u_warp;
135
+
136
+ varying vec2 vGridPos;
137
+
138
+ ${contourCommon}
139
+
140
+ float lineAt(float c, float width, float fp){
141
+ float d = abs(fract(c - 0.5) - 0.5);
142
+ return 1.0 - clamp(d / max(fp * max(width, 0.05), 1e-6), 0.0, 1.0);
143
+ }
144
+
145
+ void main(){
146
+ vec2 coord = vGridPos / max(u_cellSize, 1e-4);
147
+ vec2 focus = u_focus / max(u_cellSize, 1e-4);
148
+ float t = u_time * u_animSpeed;
149
+
150
+ float h = terrain(coord, t, u_roughness, u_warp);
151
+
152
+ // Contours are just iso-lines of the height field: bands crosses an integer
153
+ // once per elevation step, and fwidth turns that into a screen-space width,
154
+ // so lines stay one pixel thick on a steep slope and on a flat plain alike.
155
+ float bands = h * max(u_levels, 1.0);
156
+ float fp = max(fwidth(bands), 1e-6);
157
+ float minor = lineAt(bands, u_lineWidth, fp);
158
+
159
+ float major = 0.0;
160
+ if (u_sectionWidth > 0.0 && u_sectionSize > 0.0){
161
+ float mb = bands / u_sectionSize;
162
+ major = lineAt(mb, u_sectionWidth, max(fwidth(mb), 1e-6));
163
+ }
164
+
165
+ // ---- contour animation -----------------------------------------------
166
+ float lineAnim = 1.0;
167
+ if (u_lineMode > 0.5 && u_lineMode < 1.5){
168
+ lineAnim = 0.5 + 0.5 * sin(length(coord - focus) * u_animScale * 6.0 - t);
169
+ } else if (u_lineMode < 2.5){
170
+ // elevation sweep: a band of contours lights as it rises through the range
171
+ lineAnim = 0.3 + 0.7 * pow(fract(h - t * 0.1), 8.0);
172
+ } else if (u_lineMode < 3.5){
173
+ float s = fract((coord.x + coord.y) * 0.3 * u_animScale - t * 0.15);
174
+ lineAnim = 0.25 + smoothstep(0.0, 0.15, s) * (1.0 - smoothstep(0.15, 0.35, s));
175
+ } else if (u_lineMode < 4.5){
176
+ lineAnim = 0.5 + 0.5 * sin(t);
177
+ }
178
+ lineAnim = mix(1.0, lineAnim, u_animIntensity);
179
+
180
+ // ---- hypsometric fill ------------------------------------------------
181
+ float cell = 0.0;
182
+ float bandId = floor(bands);
183
+ if (u_cellMode > 0.5 && u_cellMode < 1.5){
184
+ cell = h; // straight elevation tint
185
+ } else if (u_cellMode < 2.5){
186
+ float bh = hash21(vec2(bandId, 3.7));
187
+ cell = 0.5 + 0.5 * sin(t * (0.6 + bh) + bh * TAU);
188
+ } else if (u_cellMode < 3.5){
189
+ cell = smoothstep(0.6, 1.0, sin(length(coord - focus) * u_animScale * 6.0 - t));
190
+ } else if (u_cellMode < 4.5){
191
+ cell = mod(bandId, 2.0) * (0.5 + 0.5 * sin(t));
192
+ }
193
+ cell *= u_animIntensity;
194
+
195
+ float r = length(vGridPos) / max(u_fadeDistance, 1e-4);
196
+ float fade = 1.0 - smoothstep(1.0 - u_fadeStrength, 1.0, r);
197
+
198
+ vec3 col = u_bgColor * u_bgOpacity;
199
+ float a = u_bgOpacity;
200
+
201
+ col += u_cellColor * cell; a = max(a, cell * 0.8);
202
+ float minorI = minor * lineAnim;
203
+ col += u_lineColor * minorI; a = max(a, minorI);
204
+ float majorI = major * lineAnim;
205
+ col += u_sectionColor * majorI; a = max(a, majorI);
206
+ // peaks glow, so the eye reads height without needing a legend
207
+ col += u_glowColor * (minorI * 0.15 + majorI * 0.3) * h * u_animIntensity;
208
+
209
+ col *= fade;
210
+ a *= fade;
211
+
212
+ // ---- reveal ----------------------------------------------------------
213
+ // The build boundary sweeps outward from the focus point. Its leading band
214
+ // mostly brightens whatever is already there rather than painting a solid
215
+ // disc, so the grid reads as assembling itself rather than fading in.
216
+ if (u_reveal < 0.999){
217
+ float rd = length(vGridPos - u_focus) / max(u_fadeDistance, 1e-4);
218
+ // 1.1, not 1.25: the boundary has to clear the fade radius by just the
219
+ // width of its own soft edge. Overshooting further finishes the build
220
+ // before reveal reaches 1 and leaves the tail of the range doing nothing.
221
+ float edge = u_reveal * 1.1;
222
+ float mask = 1.0 - smoothstep(edge - 0.05, edge, rd);
223
+ float front = mask * smoothstep(edge - 0.22, edge - 0.05, rd);
224
+ col = col * mask + u_glowColor * front * (a * 1.8 + 0.08);
225
+ a = max(a * mask, front * 0.10);
226
+ }
227
+
228
+ if (a < 0.002) discard;
229
+ gl_FragColor = vec4(col, a);
230
+ }
231
+ `;
232
+ export const ContourGridMaterial = shaderMaterial({
233
+ u_time: contourGridMaterialDefaults.u_time,
234
+ u_cellSize: contourGridMaterialDefaults.u_cellSize,
235
+ u_lineWidth: contourGridMaterialDefaults.u_lineWidth,
236
+ u_sectionSize: contourGridMaterialDefaults.u_sectionSize,
237
+ u_sectionWidth: contourGridMaterialDefaults.u_sectionWidth,
238
+ u_lineColor: contourGridMaterialDefaults.u_lineColor.clone(),
239
+ u_sectionColor: contourGridMaterialDefaults.u_sectionColor.clone(),
240
+ u_cellColor: contourGridMaterialDefaults.u_cellColor.clone(),
241
+ u_glowColor: contourGridMaterialDefaults.u_glowColor.clone(),
242
+ u_bgColor: contourGridMaterialDefaults.u_bgColor.clone(),
243
+ u_bgOpacity: contourGridMaterialDefaults.u_bgOpacity,
244
+ u_lineMode: contourGridMaterialDefaults.u_lineMode,
245
+ u_cellMode: contourGridMaterialDefaults.u_cellMode,
246
+ u_animSpeed: contourGridMaterialDefaults.u_animSpeed,
247
+ u_animScale: contourGridMaterialDefaults.u_animScale,
248
+ u_animIntensity: contourGridMaterialDefaults.u_animIntensity,
249
+ u_fadeDistance: contourGridMaterialDefaults.u_fadeDistance,
250
+ u_fadeStrength: contourGridMaterialDefaults.u_fadeStrength,
251
+ u_focus: contourGridMaterialDefaults.u_focus.clone(),
252
+ u_mouse: contourGridMaterialDefaults.u_mouse.clone(),
253
+ u_displace: contourGridMaterialDefaults.u_displace,
254
+ u_reveal: contourGridMaterialDefaults.u_reveal,
255
+ u_levels: contourGridMaterialDefaults.u_levels,
256
+ u_roughness: contourGridMaterialDefaults.u_roughness,
257
+ u_warp: contourGridMaterialDefaults.u_warp,
258
+ }, vertex, fragment);
259
+ extend({ ContourGridMaterial });
@@ -0,0 +1,76 @@
1
+ import * as THREE from 'three';
2
+ export interface FractalGridMaterialUniforms {
3
+ u_time: number;
4
+ /** size of a level-0 cell, in world units */
5
+ u_cellSize: number;
6
+ /** line thickness at level 0, in pixels; deeper levels thin out */
7
+ u_lineWidth: number;
8
+ /** how many level-0 cells make one accent group */
9
+ u_sectionSize: number;
10
+ /** accent thickness, in pixels; 0 disables the layer */
11
+ u_sectionWidth: number;
12
+ u_lineColor: THREE.Color;
13
+ u_sectionColor: THREE.Color;
14
+ u_cellColor: THREE.Color;
15
+ u_glowColor: THREE.Color;
16
+ u_bgColor: THREE.Color;
17
+ u_bgOpacity: number;
18
+ u_lineMode: number;
19
+ u_cellMode: number;
20
+ u_animSpeed: number;
21
+ u_animScale: number;
22
+ u_animIntensity: number;
23
+ u_fadeDistance: number;
24
+ u_fadeStrength: number;
25
+ u_focus: THREE.Vector2;
26
+ u_mouse: THREE.Vector2;
27
+ u_displace: number;
28
+ /**
29
+ * 0..1 assemble/dissolve. The build boundary sweeps outward from u_focus
30
+ * with a bright leading edge; 1 is fully built, 0 is gone. Animate it
31
+ * downward to dissolve.
32
+ */
33
+ u_reveal: number;
34
+ /** maximum subdivision levels, 1..6 */
35
+ u_depth: number;
36
+ /** radius around the focus, in level-0 cells, inside which cells subdivide */
37
+ u_splitRadius: number;
38
+ /** 0..1 — how much the split radius wobbles per cell, for an organic edge */
39
+ u_splitJitter: number;
40
+ }
41
+ declare module '@react-three/fiber' {
42
+ interface ThreeElements {
43
+ fractalGridMaterial: ThreeElements['shaderMaterial'] & Partial<FractalGridMaterialUniforms>;
44
+ }
45
+ }
46
+ export declare const fractalGridMaterialDefaults: FractalGridMaterialUniforms;
47
+ export declare const FractalGridMaterial: import("@react-three/fiber").ConstructorRepresentation<THREE.ShaderMaterial & {
48
+ u_time: number;
49
+ u_cellSize: number;
50
+ u_lineWidth: number;
51
+ u_sectionSize: number;
52
+ u_sectionWidth: number;
53
+ u_lineColor: THREE.Color;
54
+ u_sectionColor: THREE.Color;
55
+ u_cellColor: THREE.Color;
56
+ u_glowColor: THREE.Color;
57
+ u_bgColor: THREE.Color;
58
+ u_bgOpacity: number;
59
+ u_lineMode: number;
60
+ u_cellMode: number;
61
+ u_animSpeed: number;
62
+ u_animScale: number;
63
+ u_animIntensity: number;
64
+ u_fadeDistance: number;
65
+ u_fadeStrength: number;
66
+ u_focus: THREE.Vector2;
67
+ u_mouse: THREE.Vector2;
68
+ u_displace: number;
69
+ u_reveal: number;
70
+ u_depth: number;
71
+ u_splitRadius: number;
72
+ u_splitJitter: number;
73
+ }> & {
74
+ key: string;
75
+ };
76
+ //# sourceMappingURL=FractalGridMaterial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FractalGridMaterial.d.ts","sourceRoot":"","sources":["../../src/shaders/FractalGridMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,2BAA2B;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC;IAC5B,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,OAAO,QAAQ,oBAAoB,CAAC;IAChC,UAAU,aAAa;QACnB,mBAAmB,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;KAC/F;CACJ;AAED,eAAO,MAAM,2BAA2B,EAAE,2BA0BzC,CAAC;AAmMF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B/B,CAAC"}
@@ -0,0 +1,247 @@
1
+ import * as THREE from 'three';
2
+ import { shaderMaterial } from '@react-three/drei';
3
+ import { extend } from '@react-three/fiber';
4
+ export const fractalGridMaterialDefaults = {
5
+ u_time: 0,
6
+ u_cellSize: 4.0,
7
+ u_lineWidth: 1.6,
8
+ u_sectionSize: 4.0,
9
+ u_sectionWidth: 2.2,
10
+ u_lineColor: new THREE.Color(0.35, 0.75, 1.0),
11
+ u_sectionColor: new THREE.Color(0.6, 0.9, 1.0),
12
+ u_cellColor: new THREE.Color(0.12, 0.38, 0.62),
13
+ u_glowColor: new THREE.Color(0.4, 0.9, 1.0),
14
+ u_bgColor: new THREE.Color(0.01, 0.03, 0.06),
15
+ u_bgOpacity: 0.0,
16
+ u_lineMode: 0,
17
+ u_cellMode: 2,
18
+ u_animSpeed: 1.0,
19
+ u_animScale: 0.5,
20
+ u_animIntensity: 1.0,
21
+ u_fadeDistance: 25.0,
22
+ u_fadeStrength: 0.7,
23
+ u_focus: new THREE.Vector2(0, 0),
24
+ u_mouse: new THREE.Vector2(0, 0),
25
+ u_displace: 0.0,
26
+ u_reveal: 1.0,
27
+ u_depth: 5.0,
28
+ u_splitRadius: 3.5,
29
+ u_splitJitter: 0.5,
30
+ };
31
+ const fractalCommon = /*glsl*/ `
32
+ const float TAU = 6.28318530718;
33
+
34
+ float hash21(vec2 p){
35
+ p = fract(p * vec2(123.34, 456.21));
36
+ p += dot(p, p + 45.32);
37
+ return fract(p.x * p.y);
38
+ }
39
+ `;
40
+ // Fragment-only: derivatives do not exist in the vertex stage, so anything
41
+ // calling fwidth has to stay out of the shared chunk.
42
+ const fractalLines = /*glsl*/ `
43
+ float gridLines(vec2 c, float width){
44
+ vec2 d = fwidth(c);
45
+ vec2 g = abs(fract(c - 0.5) - 0.5) / max(d * width, 1e-5);
46
+ return 1.0 - clamp(min(g.x, g.y), 0.0, 1.0);
47
+ }
48
+ `;
49
+ const vertex = /*glsl*/ `
50
+ uniform float u_time;
51
+ uniform float u_cellSize;
52
+ uniform float u_displace;
53
+ uniform float u_animSpeed;
54
+ uniform float u_animScale;
55
+
56
+ varying vec2 vGridPos;
57
+
58
+ ${fractalCommon}
59
+
60
+ void main(){
61
+ vGridPos = position.xy;
62
+ vec3 pos = position;
63
+ if (u_displace > 0.0){
64
+ float t = u_time * u_animSpeed;
65
+ float d = length(position.xy) / max(u_cellSize, 1e-4);
66
+ pos.z += sin(d * u_animScale - t) * u_displace;
67
+ }
68
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
69
+ }
70
+ `;
71
+ const fragment = /*glsl*/ `
72
+ precision highp float;
73
+
74
+ uniform float u_time;
75
+ uniform float u_cellSize;
76
+ uniform float u_lineWidth;
77
+ uniform float u_sectionSize;
78
+ uniform float u_sectionWidth;
79
+ uniform vec3 u_lineColor;
80
+ uniform vec3 u_sectionColor;
81
+ uniform vec3 u_cellColor;
82
+ uniform vec3 u_glowColor;
83
+ uniform vec3 u_bgColor;
84
+ uniform float u_bgOpacity;
85
+ uniform float u_lineMode;
86
+ uniform float u_cellMode;
87
+ uniform float u_animSpeed;
88
+ uniform float u_animScale;
89
+ uniform float u_animIntensity;
90
+ uniform float u_fadeDistance;
91
+ uniform float u_fadeStrength;
92
+ uniform vec2 u_focus;
93
+ uniform float u_reveal;
94
+ uniform float u_depth;
95
+ uniform float u_splitRadius;
96
+ uniform float u_splitJitter;
97
+
98
+ varying vec2 vGridPos;
99
+
100
+ ${fractalCommon}
101
+ ${fractalLines}
102
+
103
+ void main(){
104
+ vec2 coord = vGridPos / max(u_cellSize, 1e-4);
105
+ vec2 focus = u_focus / max(u_cellSize, 1e-4);
106
+ float t = u_time * u_animSpeed;
107
+
108
+ // Walk the quadtree from the root. the alive flag stays 1 only along the chain of
109
+ // cells that have subdivided so far, so a level's lines are drawn exactly
110
+ // where its parent split — no explicit tree, no recursion.
111
+ float lines = 0.0;
112
+ float alive = 1.0;
113
+ float depthReached = 0.0;
114
+ vec2 c = coord;
115
+ float sc = 1.0; // 2^level
116
+
117
+ for (int i = 0; i < 6; i++){
118
+ float fi = float(i);
119
+
120
+ float lw = max(u_lineWidth * (1.0 - fi * 0.1), 0.35);
121
+ float dim = pow(0.84, fi);
122
+ lines = max(lines, gridLines(c, lw) * dim * alive);
123
+
124
+ // Does the cell we are standing in at this level subdivide? The radius
125
+ // halves with depth, which is what makes the refinement self-similar
126
+ // rather than just one big blurred blob around the focus.
127
+ vec2 id = floor(c);
128
+ vec2 centre = (id + 0.5) / sc;
129
+ float d = length(centre - focus);
130
+ float h = hash21(id + fi * 17.3);
131
+ float rad = (u_splitRadius / sc) * (1.0 + (h - 0.5) * u_splitJitter);
132
+
133
+ float want = step(d, rad) * step(fi + 1.0, u_depth);
134
+ alive *= want;
135
+ depthReached += alive;
136
+
137
+ c *= 2.0;
138
+ sc *= 2.0;
139
+ }
140
+
141
+ // the leaf cell this fragment actually landed in
142
+ vec2 leafC = coord * exp2(depthReached);
143
+ vec2 leafId = floor(leafC);
144
+ float leafH = hash21(leafId + depthReached * 3.7);
145
+
146
+ float major = 0.0;
147
+ if (u_sectionWidth > 0.0 && u_sectionSize > 0.0){
148
+ major = gridLines(coord / u_sectionSize, u_sectionWidth);
149
+ }
150
+
151
+ // ---- line animation --------------------------------------------------
152
+ float lineAnim = 1.0;
153
+ if (u_lineMode > 0.5 && u_lineMode < 1.5){
154
+ lineAnim = 0.5 + 0.5 * sin(length(coord - focus) * u_animScale - t);
155
+ } else if (u_lineMode < 2.5){
156
+ lineAnim = 0.5 + 0.5 * sin(dot(coord, vec2(0.5, 0.5)) * u_animScale - t);
157
+ } else if (u_lineMode < 3.5){
158
+ float s = fract((coord.x + coord.y) * 0.05 * u_animScale - t * 0.15);
159
+ lineAnim = 0.25 + smoothstep(0.0, 0.15, s) * (1.0 - smoothstep(0.15, 0.35, s));
160
+ } else if (u_lineMode < 4.5){
161
+ lineAnim = 0.5 + 0.5 * sin(t);
162
+ }
163
+ lineAnim = mix(1.0, lineAnim, u_animIntensity);
164
+
165
+ // ---- leaf-cell fill --------------------------------------------------
166
+ float cell = 0.0;
167
+ if (u_cellMode > 0.5 && u_cellMode < 1.5){
168
+ cell = 0.5 + 0.5 * sin(dot(leafId, vec2(0.7, 0.3)) * u_animScale - t);
169
+ } else if (u_cellMode < 2.5){
170
+ cell = 0.5 + 0.5 * sin(t * (0.6 + leafH) + leafH * TAU);
171
+ } else if (u_cellMode < 3.5){
172
+ cell = smoothstep(0.6, 1.0, sin(length(coord - focus) * u_animScale - t));
173
+ } else if (u_cellMode < 4.5){
174
+ cell = mod(leafId.x + leafId.y, 2.0) * (0.5 + 0.5 * sin(t));
175
+ }
176
+ cell *= u_animIntensity;
177
+ vec2 lf = abs(fract(leafC) - 0.5);
178
+ cell *= smoothstep(0.5, 0.32, max(lf.x, lf.y));
179
+
180
+ // deeper cells lean toward the accent colour, so refinement is legible
181
+ float depthT = depthReached / max(u_depth, 1.0);
182
+
183
+ float r = length(vGridPos) / max(u_fadeDistance, 1e-4);
184
+ float fade = 1.0 - smoothstep(1.0 - u_fadeStrength, 1.0, r);
185
+
186
+ vec3 col = u_bgColor * u_bgOpacity;
187
+ float a = u_bgOpacity;
188
+
189
+ col += u_cellColor * cell * 0.55; a = max(a, cell * 0.5);
190
+ float linesI = lines * lineAnim;
191
+ col += mix(u_lineColor, u_sectionColor, depthT) * linesI * 1.35;
192
+ a = max(a, linesI);
193
+ float majorI = major * lineAnim;
194
+ col += u_sectionColor * majorI; a = max(a, majorI);
195
+ col += u_glowColor * (linesI * depthT * 0.5 + cell * 0.2) * u_animIntensity;
196
+
197
+ col *= fade;
198
+ a *= fade;
199
+
200
+ // ---- reveal ----------------------------------------------------------
201
+ // The build boundary sweeps outward from the focus point. Its leading band
202
+ // mostly brightens whatever is already there rather than painting a solid
203
+ // disc, so the grid reads as assembling itself rather than fading in.
204
+ if (u_reveal < 0.999){
205
+ float rd = length(vGridPos - u_focus) / max(u_fadeDistance, 1e-4);
206
+ // 1.1, not 1.25: the boundary has to clear the fade radius by just the
207
+ // width of its own soft edge. Overshooting further finishes the build
208
+ // before reveal reaches 1 and leaves the tail of the range doing nothing.
209
+ float edge = u_reveal * 1.1;
210
+ float mask = 1.0 - smoothstep(edge - 0.05, edge, rd);
211
+ float front = mask * smoothstep(edge - 0.22, edge - 0.05, rd);
212
+ col = col * mask + u_glowColor * front * (a * 1.8 + 0.08);
213
+ a = max(a * mask, front * 0.10);
214
+ }
215
+
216
+ if (a < 0.002) discard;
217
+ gl_FragColor = vec4(col, a);
218
+ }
219
+ `;
220
+ export const FractalGridMaterial = shaderMaterial({
221
+ u_time: fractalGridMaterialDefaults.u_time,
222
+ u_cellSize: fractalGridMaterialDefaults.u_cellSize,
223
+ u_lineWidth: fractalGridMaterialDefaults.u_lineWidth,
224
+ u_sectionSize: fractalGridMaterialDefaults.u_sectionSize,
225
+ u_sectionWidth: fractalGridMaterialDefaults.u_sectionWidth,
226
+ u_lineColor: fractalGridMaterialDefaults.u_lineColor.clone(),
227
+ u_sectionColor: fractalGridMaterialDefaults.u_sectionColor.clone(),
228
+ u_cellColor: fractalGridMaterialDefaults.u_cellColor.clone(),
229
+ u_glowColor: fractalGridMaterialDefaults.u_glowColor.clone(),
230
+ u_bgColor: fractalGridMaterialDefaults.u_bgColor.clone(),
231
+ u_bgOpacity: fractalGridMaterialDefaults.u_bgOpacity,
232
+ u_lineMode: fractalGridMaterialDefaults.u_lineMode,
233
+ u_cellMode: fractalGridMaterialDefaults.u_cellMode,
234
+ u_animSpeed: fractalGridMaterialDefaults.u_animSpeed,
235
+ u_animScale: fractalGridMaterialDefaults.u_animScale,
236
+ u_animIntensity: fractalGridMaterialDefaults.u_animIntensity,
237
+ u_fadeDistance: fractalGridMaterialDefaults.u_fadeDistance,
238
+ u_fadeStrength: fractalGridMaterialDefaults.u_fadeStrength,
239
+ u_focus: fractalGridMaterialDefaults.u_focus.clone(),
240
+ u_mouse: fractalGridMaterialDefaults.u_mouse.clone(),
241
+ u_displace: fractalGridMaterialDefaults.u_displace,
242
+ u_reveal: fractalGridMaterialDefaults.u_reveal,
243
+ u_depth: fractalGridMaterialDefaults.u_depth,
244
+ u_splitRadius: fractalGridMaterialDefaults.u_splitRadius,
245
+ u_splitJitter: fractalGridMaterialDefaults.u_splitJitter,
246
+ }, vertex, fragment);
247
+ extend({ FractalGridMaterial });
@@ -0,0 +1,73 @@
1
+ import * as THREE from 'three';
2
+ export interface HexGridMaterialUniforms {
3
+ u_time: number;
4
+ /** flat-to-flat width of one hex, in world units */
5
+ u_cellSize: number;
6
+ /** edge thickness, in pixels */
7
+ u_lineWidth: number;
8
+ /** how many hexes make one super-hex */
9
+ u_sectionSize: number;
10
+ /** super-hex edge thickness, in pixels; 0 disables the layer */
11
+ u_sectionWidth: number;
12
+ u_lineColor: THREE.Color;
13
+ u_sectionColor: THREE.Color;
14
+ u_cellColor: THREE.Color;
15
+ u_glowColor: THREE.Color;
16
+ u_bgColor: THREE.Color;
17
+ u_bgOpacity: number;
18
+ u_lineMode: number;
19
+ u_cellMode: number;
20
+ u_animSpeed: number;
21
+ u_animScale: number;
22
+ u_animIntensity: number;
23
+ u_fadeDistance: number;
24
+ u_fadeStrength: number;
25
+ /** ripple origin in local grid coords */
26
+ u_focus: THREE.Vector2;
27
+ /** mouse in NDC (Vector2) — 3drise convention; the host maps it into u_focus */
28
+ u_mouse: THREE.Vector2;
29
+ /** vertex displacement along the plane normal (needs a segmented plane) */
30
+ u_displace: number;
31
+ /**
32
+ * 0..1 assemble/dissolve. The build boundary sweeps outward from u_focus
33
+ * with a bright leading edge; 1 is fully built, 0 is gone. Animate it
34
+ * downward to dissolve.
35
+ */
36
+ u_reveal: number;
37
+ /** 1 = each hex lifts to its own flat height, 0 = smooth wave */
38
+ u_plateau: number;
39
+ }
40
+ declare module '@react-three/fiber' {
41
+ interface ThreeElements {
42
+ hexGridMaterial: ThreeElements['shaderMaterial'] & Partial<HexGridMaterialUniforms>;
43
+ }
44
+ }
45
+ export declare const hexGridMaterialDefaults: HexGridMaterialUniforms;
46
+ export declare const HexGridMaterial: import("@react-three/fiber").ConstructorRepresentation<THREE.ShaderMaterial & {
47
+ u_time: number;
48
+ u_cellSize: number;
49
+ u_lineWidth: number;
50
+ u_sectionSize: number;
51
+ u_sectionWidth: number;
52
+ u_lineColor: THREE.Color;
53
+ u_sectionColor: THREE.Color;
54
+ u_cellColor: THREE.Color;
55
+ u_glowColor: THREE.Color;
56
+ u_bgColor: THREE.Color;
57
+ u_bgOpacity: number;
58
+ u_lineMode: number;
59
+ u_cellMode: number;
60
+ u_animSpeed: number;
61
+ u_animScale: number;
62
+ u_animIntensity: number;
63
+ u_fadeDistance: number;
64
+ u_fadeStrength: number;
65
+ u_focus: THREE.Vector2;
66
+ u_mouse: THREE.Vector2;
67
+ u_displace: number;
68
+ u_reveal: number;
69
+ u_plateau: number;
70
+ }> & {
71
+ key: string;
72
+ };
73
+ //# sourceMappingURL=HexGridMaterial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HexGridMaterial.d.ts","sourceRoot":"","sources":["../../src/shaders/HexGridMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,uBAAuB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC;IAC5B,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IACvB,gFAAgF;IAChF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IACvB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,OAAO,QAAQ,oBAAoB,CAAC;IAChC,UAAU,aAAa;QACnB,eAAe,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;KACvF;CACJ;AAED,eAAO,MAAM,uBAAuB,EAAE,uBAwBrC,CAAC;AAwNF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;CA4B3B,CAAC"}