@3driseai/3drise-core 1.0.20 → 1.0.21

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 (34) hide show
  1. package/dist/data/gridsDefaults.d.ts.map +1 -1
  2. package/dist/data/gridsDefaults.js +129 -0
  3. package/dist/properties/tables/gridProperties.d.ts.map +1 -1
  4. package/dist/properties/tables/gridProperties.js +78 -0
  5. package/dist/properties/tables/index.d.ts +0 -1
  6. package/dist/properties/tables/index.d.ts.map +1 -1
  7. package/dist/properties/tables/index.js +0 -1
  8. package/dist/properties/tables/lightProperties.js +1 -1
  9. package/dist/properties/tables/materialBounds.js +1 -1
  10. package/dist/shaders/ApollonianGridMaterial.d.ts +70 -0
  11. package/dist/shaders/ApollonianGridMaterial.d.ts.map +1 -0
  12. package/dist/shaders/ApollonianGridMaterial.js +289 -0
  13. package/dist/shaders/ConformalGridMaterial.d.ts +91 -0
  14. package/dist/shaders/ConformalGridMaterial.d.ts.map +1 -0
  15. package/dist/shaders/ConformalGridMaterial.js +335 -0
  16. package/dist/shaders/HilbertGridMaterial.d.ts +79 -0
  17. package/dist/shaders/HilbertGridMaterial.d.ts.map +1 -0
  18. package/dist/shaders/HilbertGridMaterial.js +329 -0
  19. package/dist/shaders/LensingGridMaterial.d.ts +73 -0
  20. package/dist/shaders/LensingGridMaterial.d.ts.map +1 -0
  21. package/dist/shaders/LensingGridMaterial.js +253 -0
  22. package/dist/shaders/ParastichyGridMaterial.d.ts +76 -0
  23. package/dist/shaders/ParastichyGridMaterial.d.ts.map +1 -0
  24. package/dist/shaders/ParastichyGridMaterial.js +282 -0
  25. package/dist/shaders/PhyllotaxisGridMaterial.d.ts +85 -0
  26. package/dist/shaders/PhyllotaxisGridMaterial.d.ts.map +1 -0
  27. package/dist/shaders/PhyllotaxisGridMaterial.js +532 -0
  28. package/dist/shaders/TruchetGridMaterial.d.ts +76 -0
  29. package/dist/shaders/TruchetGridMaterial.d.ts.map +1 -0
  30. package/dist/shaders/TruchetGridMaterial.js +290 -0
  31. package/dist/shaders/index.d.ts +7 -0
  32. package/dist/shaders/index.d.ts.map +1 -1
  33. package/dist/shaders/index.js +7 -0
  34. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"gridsDefaults.d.ts","sourceRoot":"","sources":["../../src/data/gridsDefaults.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAiR/E,CAAC"}
1
+ {"version":3,"file":"gridsDefaults.d.ts","sourceRoot":"","sources":["../../src/data/gridsDefaults.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAkZ/E,CAAC"}
@@ -287,4 +287,133 @@ export const GRIDS_ANIMATABLE = {
287
287
  { value: 'glowColor', label: 'Glow Color' },
288
288
  { value: 'bgColor', label: 'Bg Color' },
289
289
  ],
290
+ lensingGrid: [
291
+ { value: 'cellSize', label: 'Cell Size' },
292
+ { value: 'lineWidth', label: 'Line Width' },
293
+ { value: 'sectionWidth', label: 'Section Width' },
294
+ { value: 'animSpeed', label: 'Anim Speed' },
295
+ { value: 'animScale', label: 'Anim Scale' },
296
+ { value: 'animIntensity', label: 'Anim Intensity' },
297
+ { value: 'fadeStrength', label: 'Fade Strength' },
298
+ { value: 'bgOpacity', label: 'Bg Opacity' },
299
+ { value: 'lineColor', label: 'Line Color' },
300
+ { value: 'sectionColor', label: 'Section Color' },
301
+ { value: 'cellColor', label: 'Cell Color' },
302
+ { value: 'glowColor', label: 'Glow Color' },
303
+ { value: 'bgColor', label: 'Bg Color' },
304
+ { value: 'mass', label: 'Mass' },
305
+ { value: 'orbit', label: 'Orbit' },
306
+ { value: 'ringGlow', label: 'Ring Glow' },
307
+ ],
308
+ conformalGrid: [
309
+ { value: 'cellSize', label: 'Cell Size' },
310
+ { value: 'lineWidth', label: 'Line Width' },
311
+ { value: 'sectionWidth', label: 'Section Width' },
312
+ { value: 'animSpeed', label: 'Anim Speed' },
313
+ { value: 'animScale', label: 'Anim Scale' },
314
+ { value: 'animIntensity', label: 'Anim Intensity' },
315
+ { value: 'fadeStrength', label: 'Fade Strength' },
316
+ { value: 'bgOpacity', label: 'Bg Opacity' },
317
+ { value: 'lineColor', label: 'Line Color' },
318
+ { value: 'sectionColor', label: 'Section Color' },
319
+ { value: 'cellColor', label: 'Cell Color' },
320
+ { value: 'glowColor', label: 'Glow Color' },
321
+ { value: 'bgColor', label: 'Bg Color' },
322
+ { value: 'poleSpread', label: 'Pole Spread' },
323
+ { value: 'circulation', label: 'Circulation' },
324
+ { value: 'drift', label: 'Drift' },
325
+ { value: 'fill', label: 'Fill' },
326
+ { value: 'dye', label: 'Dye' },
327
+ ],
328
+ truchetGrid: [
329
+ { value: 'cellSize', label: 'Cell Size' },
330
+ { value: 'lineWidth', label: 'Line Width' },
331
+ { value: 'sectionWidth', label: 'Section Width' },
332
+ { value: 'animSpeed', label: 'Anim Speed' },
333
+ { value: 'animScale', label: 'Anim Scale' },
334
+ { value: 'animIntensity', label: 'Anim Intensity' },
335
+ { value: 'fadeStrength', label: 'Fade Strength' },
336
+ { value: 'bgOpacity', label: 'Bg Opacity' },
337
+ { value: 'lineColor', label: 'Line Color' },
338
+ { value: 'sectionColor', label: 'Section Color' },
339
+ { value: 'cellColor', label: 'Cell Color' },
340
+ { value: 'glowColor', label: 'Glow Color' },
341
+ { value: 'bgColor', label: 'Bg Color' },
342
+ { value: 'flip', label: 'Flip' },
343
+ { value: 'bias', label: 'Bias' },
344
+ { value: 'pulse', label: 'Pulse' },
345
+ { value: 'regionFill', label: 'Region Fill' },
346
+ ],
347
+ phyllotaxisGrid: [
348
+ { value: 'cellSize', label: 'Cell Size' },
349
+ { value: 'lineWidth', label: 'Line Width' },
350
+ { value: 'sectionWidth', label: 'Section Width' },
351
+ { value: 'animSpeed', label: 'Anim Speed' },
352
+ { value: 'animScale', label: 'Anim Scale' },
353
+ { value: 'animIntensity', label: 'Anim Intensity' },
354
+ { value: 'fadeStrength', label: 'Fade Strength' },
355
+ { value: 'bgOpacity', label: 'Bg Opacity' },
356
+ { value: 'lineColor', label: 'Line Color' },
357
+ { value: 'sectionColor', label: 'Section Color' },
358
+ { value: 'cellColor', label: 'Cell Color' },
359
+ { value: 'glowColor', label: 'Glow Color' },
360
+ { value: 'bgColor', label: 'Bg Color' },
361
+ { value: 'divergence', label: 'Divergence' },
362
+ { value: 'bloomRate', label: 'Bloom Rate' },
363
+ { value: 'relief', label: 'Relief' },
364
+ { value: 'shapeSize', label: 'Shape Size' },
365
+ { value: 'shapeGlow', label: 'Shape Glow' },
366
+ ],
367
+ parastichyGrid: [
368
+ { value: 'cellSize', label: 'Cell Size' },
369
+ { value: 'lineWidth', label: 'Line Width' },
370
+ { value: 'sectionWidth', label: 'Section Width' },
371
+ { value: 'animSpeed', label: 'Anim Speed' },
372
+ { value: 'animScale', label: 'Anim Scale' },
373
+ { value: 'animIntensity', label: 'Anim Intensity' },
374
+ { value: 'fadeStrength', label: 'Fade Strength' },
375
+ { value: 'bgOpacity', label: 'Bg Opacity' },
376
+ { value: 'lineColor', label: 'Line Color' },
377
+ { value: 'sectionColor', label: 'Section Color' },
378
+ { value: 'cellColor', label: 'Cell Color' },
379
+ { value: 'glowColor', label: 'Glow Color' },
380
+ { value: 'bgColor', label: 'Bg Color' },
381
+ { value: 'divergence', label: 'Divergence' },
382
+ { value: 'third', label: 'Third' },
383
+ { value: 'sap', label: 'Sap' },
384
+ { value: 'fill', label: 'Fill' },
385
+ ],
386
+ apollonianGrid: [
387
+ { value: 'cellSize', label: 'Cell Size' },
388
+ { value: 'lineWidth', label: 'Line Width' },
389
+ { value: 'sectionWidth', label: 'Section Width' },
390
+ { value: 'animSpeed', label: 'Anim Speed' },
391
+ { value: 'animScale', label: 'Anim Scale' },
392
+ { value: 'animIntensity', label: 'Anim Intensity' },
393
+ { value: 'fadeStrength', label: 'Fade Strength' },
394
+ { value: 'bgOpacity', label: 'Bg Opacity' },
395
+ { value: 'lineColor', label: 'Line Color' },
396
+ { value: 'sectionColor', label: 'Section Color' },
397
+ { value: 'cellColor', label: 'Cell Color' },
398
+ { value: 'glowColor', label: 'Glow Color' },
399
+ { value: 'bgColor', label: 'Bg Color' },
400
+ { value: 'morph', label: 'Morph' },
401
+ ],
402
+ hilbertGrid: [
403
+ { value: 'cellSize', label: 'Cell Size' },
404
+ { value: 'lineWidth', label: 'Line Width' },
405
+ { value: 'sectionWidth', label: 'Section Width' },
406
+ { value: 'animSpeed', label: 'Anim Speed' },
407
+ { value: 'animScale', label: 'Anim Scale' },
408
+ { value: 'animIntensity', label: 'Anim Intensity' },
409
+ { value: 'fadeStrength', label: 'Fade Strength' },
410
+ { value: 'bgOpacity', label: 'Bg Opacity' },
411
+ { value: 'lineColor', label: 'Line Color' },
412
+ { value: 'sectionColor', label: 'Section Color' },
413
+ { value: 'cellColor', label: 'Cell Color' },
414
+ { value: 'glowColor', label: 'Glow Color' },
415
+ { value: 'bgColor', label: 'Bg Color' },
416
+ { value: 'trail', label: 'Trail' },
417
+ { value: 'signalSpeed', label: 'Signal Speed' },
418
+ ],
290
419
  };
@@ -1 +1 @@
1
- {"version":3,"file":"gridProperties.d.ts","sourceRoot":"","sources":["../../../src/properties/tables/gridProperties.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAiB7D,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,EAAE,gBAAgB,EAwBrD,CAAC;AAmFF,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAE9D,CAAC"}
1
+ {"version":3,"file":"gridProperties.d.ts","sourceRoot":"","sources":["../../../src/properties/tables/gridProperties.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAiB7D,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,EAAE,gBAAgB,EAwBrD,CAAC;AAiKF,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAE9D,CAAC"}
@@ -117,5 +117,83 @@ const own = {
117
117
  { name: 'tileCells', description: 'Cells covered by one simulation tile', type: 'number', min: 1, max: 20, step: 1 },
118
118
  ],
119
119
  };
120
+ /**
121
+ * Grids that always lie flat (the parent object's transform orients them) and
122
+ * leave pointer behaviour to the Pointer tab: their surface rows have no `flat`
123
+ * and no `followMouse`. `section` re-describes `sectionSize` where the grid
124
+ * gives it its own meaning (spiral count, bloom rings, inversion levels).
125
+ */
126
+ const SURFACE_PARENT_ORIENTED = GRID_SURFACE_PROPERTIES.filter((p) => p.name !== 'flat' && p.name !== 'followMouse');
127
+ const surfaceFor = (section) => section ? SURFACE_PARENT_ORIENTED.map((p) => (p.name === 'sectionSize' ? { ...p, ...section } : p)) : SURFACE_PARENT_ORIENTED;
128
+ const parentOriented = {
129
+ lensingGrid: {
130
+ own: [
131
+ { name: 'mass', description: "Einstein radius of the lens, in cells; 0 leaves the lattice undistorted", type: 'number', min: 0, max: 12, step: 0.1 },
132
+ { name: 'orbit', description: "Radius the lens circles the centre on, in cells; 0 holds it at the centre", type: 'number', min: 0, max: 15, step: 0.1 },
133
+ { name: 'ringGlow', description: "Brightness of the Einstein ring and its halo", type: 'number', min: 0, max: 3, step: 0.05 },
134
+ ],
135
+ },
136
+ conformalGrid: {
137
+ own: [
138
+ { name: 'flowMap', description: "The flow: 0 source + sink, 1 spiral vortex, 2 spinning cylinder, 3 corner", type: 'select', options: ['0', '1', '2', '3'], optionLabels: ['Source + sink', 'Spiral vortex', 'Spinning cylinder', 'Corner'] },
139
+ { name: 'poleSpread', description: "Distance from the centre to the poles, or the cylinder radius, in world units", type: 'number', min: 1, max: 25, step: 0.1 },
140
+ { name: 'spokes', description: "Lattice lines per turn round a pole (whole number, so the log seam closes)", type: 'number', min: 4, max: 64, step: 1 },
141
+ { name: 'arms', description: "Spiral arms of the vortex flow; 0 gives a plain polar web", type: 'number', min: -8, max: 8, step: 1 },
142
+ { name: 'circulation', description: "Circulation round the cylinder (lift); at ±2 both stagnation points meet", type: 'number', min: -3, max: 3, step: 0.01 },
143
+ { name: 'drift', description: "How fast the lattice streams along the flow; negative reverses it", type: 'number', min: -1, max: 1, step: 0.01 },
144
+ { name: 'fill', description: "Strength of the speed-coloured stream-tube fill", type: 'number', min: 0, max: 1, step: 0.01 },
145
+ { name: 'dye', description: "Brightness of the dashes carried along the streamlines", type: 'number', min: 0, max: 2, step: 0.01 },
146
+ ],
147
+ section: { description: "Streamlines per accent streamline" },
148
+ },
149
+ truchetGrid: {
150
+ own: [
151
+ { name: 'flip', description: "Chance a tile re-deals its orientation each epoch; 0 freezes the paths", type: 'number', min: 0, max: 1, step: 0.01 },
152
+ { name: 'bias', description: "Balance of the two tile orientations: 0.5 is a maze, the ends are stripes", type: 'number', min: 0, max: 1, step: 0.01 },
153
+ { name: 'pulse', description: "Brightness of the comets travelling the loops", type: 'number', min: 0, max: 2, step: 0.01 },
154
+ { name: 'regionFill', description: "Fill of one colour of the two-colouring", type: 'number', min: 0, max: 1, step: 0.01 },
155
+ ],
156
+ section: { description: "Tiles per tile of the coarser Truchet accent layer" },
157
+ },
158
+ phyllotaxisGrid: {
159
+ own: [
160
+ { name: 'divergence', description: "Angle between successive seeds, degrees; 137.508 is the golden angle", type: 'number', min: 130, max: 145, step: 0.001 },
161
+ { name: 'bloomRate', description: "Speed of the bloom rings travelling rim to centre; negative reverses them", type: 'number', min: -0.3, max: 0.3, step: 0.001 },
162
+ { name: 'relief', description: "Depth of the lit dome on each floret", type: 'number', min: 0, max: 1, step: 0.01 },
163
+ { name: 'shape', description: "The mark each floret carries (0 draws only the domes)", type: 'select', options: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21'], optionLabels: ['Domes only', 'Seed', 'Ring', 'Crescent', 'Sparkle', 'Reuleaux', 'Spiral', 'Target', 'Pebble', 'Dot', 'Dots (sunflower)', 'Square', 'Star', 'Hexagon', 'Triangle', 'Cross', 'Heart', 'Chevron', 'Infinity', 'Gear', 'Atom', 'Sunburst'] },
164
+ { name: 'shapeSize', description: "Size of the mark relative to its floret", type: 'number', min: 0.3, max: 1.2, step: 0.01 },
165
+ { name: 'shapeGlow', description: "Brightness of the marks", type: 'number', min: 0, max: 2, step: 0.01 },
166
+ ],
167
+ section: { description: "Bloom rings across the head at once", min: 1, max: 6, step: 1 },
168
+ },
169
+ parastichyGrid: {
170
+ own: [
171
+ { name: 'divergence', description: "Angle between successive seeds, degrees; 137.508 is the golden angle", type: 'number', min: 135, max: 140, step: 0.001 },
172
+ { name: 'third', description: "Weight of the third spiral family that splits cells into triangles", type: 'number', min: 0, max: 1, step: 0.01 },
173
+ { name: 'sap', description: "Brightness of the light running inward along the spirals", type: 'number', min: 0, max: 2, step: 0.01 },
174
+ { name: 'fill', description: "Strength of the faceted cell fill", type: 'number', min: 0, max: 1, step: 0.01 },
175
+ ],
176
+ section: { description: "Spirals in the main family (a Fibonacci number: 13, 21, 34, 55)", min: 3, max: 55, step: 1 },
177
+ },
178
+ apollonianGrid: {
179
+ own: [
180
+ { name: 'depth', description: "Inversion levels: how deep the packing nests", type: 'number', min: 1, max: 24, step: 1 },
181
+ { name: 'morph', description: "Strength of the Möbius flow that re-balances the packing; 0 holds it symmetric", type: 'number', min: 0, max: 0.9, step: 0.01 },
182
+ ],
183
+ section: { description: "Circles shallower than this many levels get the accent rim", min: 0, max: 12, step: 1 },
184
+ },
185
+ hilbertGrid: {
186
+ own: [
187
+ { name: 'order', description: "Curve order: the loop covers 2^order cells per side", type: 'number', min: 2, max: 8, step: 1 },
188
+ { name: 'signals', description: "Signals circulating round the loop", type: 'number', min: 1, max: 32, step: 1 },
189
+ { name: 'trail', description: "Length of each signal trail, in cells", type: 'number', min: 1, max: 128, step: 0.5 },
190
+ { name: 'signalSpeed', description: "Signal speed, in cells per second", type: 'number', min: 0, max: 40, step: 0.1 },
191
+ ],
192
+ section: { description: "Cells per cell of the coarser accent curve (a power of two)", min: 0, max: 32, step: 1 },
193
+ },
194
+ };
120
195
  /** Every shader-plane grid's inputs: its own knobs first, then the shared surface. */
121
196
  export const GRID_PROPERTIES = Object.fromEntries(Object.entries(own).map(([type, props]) => [type, [...props, ...GRID_SURFACE_PROPERTIES]]));
197
+ for (const [type, { own: props, section }] of Object.entries(parentOriented)) {
198
+ GRID_PROPERTIES[type] = [...props, ...surfaceFor(section)];
199
+ }
@@ -4,6 +4,5 @@ export * from './particlesProperties';
4
4
  export * from './effectsProperties';
5
5
  export * from './gridProperties';
6
6
  export * from './materialBounds';
7
- export * from './getPropertyConfig';
8
7
  export * from './geometryProperties';
9
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/properties/tables/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/properties/tables/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
@@ -4,5 +4,4 @@ export * from './particlesProperties.js';
4
4
  export * from './effectsProperties.js';
5
5
  export * from './gridProperties.js';
6
6
  export * from './materialBounds.js';
7
- export * from './getPropertyConfig.js';
8
7
  export * from './geometryProperties.js';
@@ -1,4 +1,4 @@
1
- // Moved from client (client/app/utils/lightProperties.ts). Property tables — the registry (../registry) is built on these.
1
+ // Property table (moved from the client). The registry (../registry.ts) is built on these tables.
2
2
  // =============================================================================
3
3
  // lightProperties — the knobs LightControllerUi shows, per light type
4
4
  // =============================================================================
@@ -1,4 +1,4 @@
1
- // Moved from client (client/app/containers/pages/controllers/materialBounds.ts). Property tables — the registry (../registry) is built on these.
1
+ // Property table (moved from the client). The registry (../registry.ts) is built on these tables.
2
2
  // =============================================================================
3
3
  // MATERIAL PROPERTY BOUNDS — Min/Max/Step for Slider Controls
4
4
  // =============================================================================
@@ -0,0 +1,70 @@
1
+ import * as THREE from 'three';
2
+ export interface ApollonianGridMaterialUniforms {
3
+ /** elapsed seconds (useGridSurface) */
4
+ u_time: number;
5
+ /** size of one cell, in world units */
6
+ u_cellSize: number;
7
+ /** line thickness, in pixels */
8
+ u_lineWidth: number;
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
+ /** ripple / reveal origin; stays at the origin */
26
+ u_focus: THREE.Vector2;
27
+ u_mouse: THREE.Vector2;
28
+ u_displace: number;
29
+ /** 0..1 assemble / dissolve */
30
+ u_reveal: number;
31
+ /** Inversion levels: how deep the packing nests */
32
+ u_depth: number;
33
+ /** Strength of the Möbius flow that re-balances the packing; 0 holds it symmetric */
34
+ u_morph: number;
35
+ }
36
+ declare module '@react-three/fiber' {
37
+ interface ThreeElements {
38
+ apollonianGridMaterial: ThreeElements['shaderMaterial'] & Partial<ApollonianGridMaterialUniforms>;
39
+ }
40
+ }
41
+ export declare const apollonianGridMaterialDefaults: ApollonianGridMaterialUniforms;
42
+ export declare const ApollonianGridMaterial: import("@react-three/fiber").ConstructorRepresentation<THREE.ShaderMaterial & {
43
+ u_time: number;
44
+ u_cellSize: number;
45
+ u_lineWidth: number;
46
+ u_sectionSize: number;
47
+ u_sectionWidth: number;
48
+ u_lineColor: THREE.Color;
49
+ u_sectionColor: THREE.Color;
50
+ u_cellColor: THREE.Color;
51
+ u_glowColor: THREE.Color;
52
+ u_bgColor: THREE.Color;
53
+ u_bgOpacity: number;
54
+ u_lineMode: number;
55
+ u_cellMode: number;
56
+ u_animSpeed: number;
57
+ u_animScale: number;
58
+ u_animIntensity: number;
59
+ u_fadeDistance: number;
60
+ u_fadeStrength: number;
61
+ u_focus: THREE.Vector2;
62
+ u_mouse: THREE.Vector2;
63
+ u_displace: number;
64
+ u_reveal: number;
65
+ u_depth: number;
66
+ u_morph: number;
67
+ }> & {
68
+ key: string;
69
+ };
70
+ //# sourceMappingURL=ApollonianGridMaterial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApollonianGridMaterial.d.ts","sourceRoot":"","sources":["../../src/shaders/ApollonianGridMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,MAAM,WAAW,8BAA8B;IAC3C,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,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,kDAAkD;IAClD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,OAAO,QAAQ,oBAAoB,CAAC;IAChC,UAAU,aAAa;QACnB,sBAAsB,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;KACrG;CACJ;AAED,eAAO,MAAM,8BAA8B,EAAE,8BAyB5C,CAAC;AA6OF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BlC,CAAC"}
@@ -0,0 +1,289 @@
1
+ import * as THREE from 'three';
2
+ import { shaderMaterial } from '@react-three/drei';
3
+ import { extend } from '@react-three/fiber';
4
+ export const apollonianGridMaterialDefaults = {
5
+ u_time: 0,
6
+ u_cellSize: 2,
7
+ u_lineWidth: 1.1,
8
+ u_sectionSize: 2,
9
+ u_sectionWidth: 2,
10
+ u_lineColor: new THREE.Color('#6a90c8'),
11
+ u_sectionColor: new THREE.Color('#c9e4ff'),
12
+ u_cellColor: new THREE.Color('#1a2f5c'),
13
+ u_glowColor: new THREE.Color('#8fb8ff'),
14
+ u_bgColor: new THREE.Color('#03050c'),
15
+ u_bgOpacity: 0,
16
+ u_lineMode: 0,
17
+ u_cellMode: 1,
18
+ u_animSpeed: 1,
19
+ u_animScale: 0.5,
20
+ u_animIntensity: 0.6,
21
+ u_fadeDistance: 25,
22
+ u_fadeStrength: 0.15,
23
+ u_focus: new THREE.Vector2(0, 0),
24
+ u_mouse: new THREE.Vector2(0, 0),
25
+ u_displace: 0,
26
+ u_reveal: 1,
27
+ u_depth: 12,
28
+ u_morph: 0.25,
29
+ };
30
+ const vertex = /* glsl */ `
31
+ uniform float u_time;
32
+ uniform float u_cellSize;
33
+ uniform float u_displace;
34
+ uniform float u_animSpeed;
35
+ uniform float u_animScale;
36
+
37
+ varying vec2 vGridPos;
38
+
39
+
40
+ const float PI = 3.14159265359;
41
+ const float TAU = 6.28318530718;
42
+
43
+ float hash21(vec2 p){
44
+ p = fract(p * vec2(123.34, 456.21));
45
+ p += dot(p, p + 45.32);
46
+ return fract(p.x * p.y);
47
+ }
48
+
49
+
50
+ void main(){
51
+ vGridPos = position.xy;
52
+ vec3 pos = position;
53
+ if (u_displace > 0.0){
54
+ float t = u_time * u_animSpeed;
55
+ float d = length(position.xy) / max(u_cellSize, 1e-4);
56
+ pos.z += sin(d * u_animScale - t) * u_displace;
57
+ }
58
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
59
+ }
60
+ `;
61
+ const fragment = /* glsl */ `
62
+ precision highp float;
63
+
64
+ uniform float u_time;
65
+ uniform float u_cellSize;
66
+ uniform float u_lineWidth;
67
+ uniform float u_sectionSize;
68
+ uniform float u_sectionWidth;
69
+ uniform vec3 u_lineColor;
70
+ uniform vec3 u_sectionColor;
71
+ uniform vec3 u_cellColor;
72
+ uniform vec3 u_glowColor;
73
+ uniform vec3 u_bgColor;
74
+ uniform float u_bgOpacity;
75
+ uniform float u_lineMode;
76
+ uniform float u_cellMode;
77
+ uniform float u_animSpeed;
78
+ uniform float u_animScale;
79
+ uniform float u_animIntensity;
80
+ uniform float u_fadeDistance;
81
+ uniform float u_fadeStrength;
82
+ uniform vec2 u_focus;
83
+ uniform float u_reveal;
84
+
85
+ uniform float u_depth;
86
+ uniform float u_morph;
87
+
88
+ varying vec2 vGridPos;
89
+
90
+
91
+ const float PI = 3.14159265359;
92
+ const float TAU = 6.28318530718;
93
+
94
+ float hash21(vec2 p){
95
+ p = fract(p * vec2(123.34, 456.21));
96
+ p += dot(p, p + 45.32);
97
+ return fract(p.x * p.y);
98
+ }
99
+
100
+
101
+ float lineAt(float c, float width, float fp){
102
+ float d = abs(fract(c - 0.5) - 0.5);
103
+ return 1.0 - clamp(d / max(fp * max(width, 0.05), 1e-6), 0.0, 1.0);
104
+ }
105
+
106
+ vec2 cmul(vec2 a, vec2 b){ return vec2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
107
+ vec2 cdiv(vec2 a, vec2 b){ return vec2(a.x * b.x + a.y * b.y, a.y * b.x - a.x * b.y) / max(dot(b, b), 1e-8); }
108
+
109
+ void main(){
110
+ vec2 coord = vGridPos / max(u_cellSize, 1e-4);
111
+ vec2 focus = u_focus / max(u_cellSize, 1e-4);
112
+ float t = u_time * u_animSpeed;
113
+
114
+ // Apollonian gasket by circle inversion. Inside the unit circle sit three
115
+ // mutually tangent circles of radius 2*sqrt(3)-3. Each of the four
116
+ // curvilinear gaps between the circles is cut out by a "dual" circle through
117
+ // its three tangency points, orthogonal to the circles that bound it.
118
+ // Inverting in a gap's dual circle keeps those circles fixed and maps the
119
+ // fourth circle onto the gap's inscribed circle, so a point is walked out of
120
+ // nested gaps one inversion per level until it lands in a base circle. The
121
+ // number of inversions is its depth; the product of their scale factors takes
122
+ // distances back to the plane, so every circle gets a pixel-true stroke.
123
+ float R = u_fadeDistance * 0.9;
124
+ vec2 z = vGridPos / R;
125
+ float fpz = max(max(fwidth(z.x), fwidth(z.y)), 1e-6);
126
+
127
+ // A Mobius automorphism of the disk, z -> (z - a) / (1 - conj(a) z), maps the
128
+ // gasket onto another Apollonian gasket. Orbiting a slowly makes the packing
129
+ // flow and re-balance while every circle stays a circle and every tangency holds.
130
+ vec2 am = u_morph * 0.8 * vec2(cos(t * 0.13), sin(t * 0.19));
131
+ vec2 den = vec2(1.0, 0.0) - cmul(vec2(am.x, -am.y), z);
132
+ vec2 w = cdiv(z - am, den);
133
+ float J = (1.0 - dot(am, am)) / max(dot(den, den), 1e-8); // |dw/dz|
134
+
135
+ const float RHO = 0.46410161514; // 2 sqrt(3) - 3
136
+ const float DC = 0.53589838486; // 1 - RHO: centre distance of the three
137
+ const float SQ3 = 1.73205080757;
138
+ float maxD = clamp(floor(u_depth + 0.5), 1.0, 24.0);
139
+ float depth = 0.0;
140
+ float path = 0.37;
141
+ float term = -1.0;
142
+ vec2 cc = vec2(0.0);
143
+ float cr = 1.0;
144
+ for (int i = 0; i < 25; i++){
145
+ // landed in one of the three base circles (centres at 90, 210, 330 deg)?
146
+ for (int k = 0; k < 3; k++){
147
+ float ak = PI * 0.5 + float(k) * TAU / 3.0;
148
+ vec2 ck = DC * vec2(cos(ak), sin(ak));
149
+ if (length(w - ck) < RHO){ term = float(k) + 1.0; cc = ck; cr = RHO; }
150
+ }
151
+ if (term > 0.0) break;
152
+ if (length(w) > 1.0){ term = 0.0; cc = vec2(0.0); cr = 1.0; break; }
153
+ if (depth >= maxD) break;
154
+ // which gap: the central one, or the outer gap facing 30, 150 or 270 deg
155
+ vec2 dcen; float drad; float gap;
156
+ if (length(w) < DC * 0.5){
157
+ dcen = vec2(0.0); drad = DC * 0.5; gap = 0.0;
158
+ } else {
159
+ float ang = atan(w.y, w.x);
160
+ float kk = floor(mod(ang - PI / 6.0 + PI / 3.0, TAU) / (TAU / 3.0));
161
+ float ag = PI / 6.0 + kk * TAU / 3.0;
162
+ dcen = 2.0 * vec2(cos(ag), sin(ag)); drad = SQ3; gap = kk + 1.0;
163
+ }
164
+ vec2 v = w - dcen;
165
+ float v2 = max(dot(v, v), 1e-10);
166
+ w = dcen + drad * drad * v / v2;
167
+ J *= drad * drad / v2;
168
+ depth += 1.0;
169
+ path = hash21(vec2(path * 17.0 + gap, depth));
170
+ }
171
+
172
+ float found = step(-0.5, term);
173
+ float outside = found * step(term, 0.5) * step(depth, 0.5); // beyond the outer circle
174
+ float dz = abs(length(w - cc) - cr) / max(J, 1e-12); // distance to this circle, z units
175
+ // this circle's radius, z units. Inside an image of the outer circle the point
176
+ // can sit near the pole of the inversion, where cr/J collapses; the distance
177
+ // to the rim is the safe lower bound there.
178
+ float rz = max(cr / max(J, 1e-12), dz);
179
+ float dens = smoothstep(1.0, 3.0, rz / fpz) * found; // circles under ~2px fade out
180
+
181
+ float lines = (1.0 - clamp(dz / (fpz * max(u_lineWidth, 0.05)), 0.0, 1.0)) * dens;
182
+ float accent = 0.0;
183
+ if (u_sectionWidth > 0.0 && depth < u_sectionSize){
184
+ accent = (1.0 - clamp(dz / (fpz * max(u_sectionWidth, 0.05)), 0.0, 1.0)) * dens;
185
+ }
186
+
187
+ float dmin = clamp(dz / max(rz, 1e-9), 0.0, 1.0) * dens * (1.0 - outside);
188
+ // fills are per circle, so the wave and the ripple both step down the levels
189
+ float idAcc = depth * 20.0;
190
+ vec2 cellPos = focus + vec2(depth * 2.0, 0.0);
191
+ float cellH = hash21(vec2(path, term + 1.0));
192
+ float tone = step(0.55, cellH);
193
+
194
+ // a soft inner bevel along every rim, brightest on the shallow circles
195
+ float bevel = exp(-pow(dz / max(rz * 0.12, fpz), 2.0)) * dens * (1.0 - outside);
196
+ float lvl = 1.0 / (1.0 + depth * 0.45);
197
+ vec3 extraCol = u_glowColor * (bevel * 0.35 + lines * 0.5) * lvl;
198
+ float extraA = bevel * 0.3 * lvl;
199
+
200
+ // ---- line animation --------------------------------------------------
201
+ float lineAnim = 1.0;
202
+ // Mode 0 is static: the chain starts at 0.5 so 0 never falls into flow.
203
+ if (u_lineMode < 0.5){
204
+ } else if (u_lineMode < 1.5){
205
+ lineAnim = 0.5 + 0.5 * sin(length(cellPos - focus) * u_animScale - t);
206
+ } else if (u_lineMode < 2.5){
207
+ lineAnim = 0.5 + 0.5 * sin(dot(cellPos, vec2(0.5, 0.5)) * u_animScale - t);
208
+ } else if (u_lineMode < 3.5){
209
+ float s = fract((coord.x + coord.y) * 0.05 * u_animScale - t * 0.15);
210
+ lineAnim = 0.25 + smoothstep(0.0, 0.15, s) * (1.0 - smoothstep(0.15, 0.35, s));
211
+ } else if (u_lineMode < 4.5){
212
+ lineAnim = 0.5 + 0.5 * sin(t);
213
+ }
214
+ lineAnim = mix(1.0, lineAnim, u_animIntensity);
215
+
216
+ // ---- cell fill -------------------------------------------------------
217
+ float cell = 0.0;
218
+ if (u_cellMode < 0.5){
219
+ } else if (u_cellMode < 1.5){
220
+ cell = 0.5 + 0.5 * sin(idAcc * 0.05 * u_animScale - t);
221
+ } else if (u_cellMode < 2.5){
222
+ cell = 0.5 + 0.5 * sin(t * (0.6 + cellH) + cellH * TAU);
223
+ } else if (u_cellMode < 3.5){
224
+ cell = smoothstep(0.6, 1.0, sin(length(cellPos - focus) * u_animScale - t));
225
+ } else if (u_cellMode < 4.5){
226
+ cell = step(0.5, cellH) * (0.5 + 0.5 * sin(t));
227
+ }
228
+ cell *= u_animIntensity;
229
+ cell *= smoothstep(0.0, 0.16, dmin); // keep the fill off its own edges
230
+
231
+ float r = length(vGridPos) / max(u_fadeDistance, 1e-4);
232
+ float fade = 1.0 - smoothstep(1.0 - u_fadeStrength, 1.0, r);
233
+
234
+ vec3 col = u_bgColor * u_bgOpacity;
235
+ float a = u_bgOpacity;
236
+
237
+ col += mix(u_cellColor, u_cellColor * 2.2, tone) * cell;
238
+ a = max(a, cell * 0.9);
239
+ float linesI = lines * lineAnim;
240
+ col += u_lineColor * linesI; a = max(a, linesI);
241
+ float accentI = accent * lineAnim;
242
+ col += u_sectionColor * accentI; a = max(a, accentI);
243
+ col += u_glowColor * (linesI * 0.2 + cell * 0.35) * u_animIntensity;
244
+ col += extraCol; a = max(a, extraA);
245
+
246
+ col *= fade;
247
+ a *= fade;
248
+
249
+ // ---- reveal ----------------------------------------------------------
250
+ if (u_reveal < 0.999){
251
+ float rd = length(vGridPos - u_focus) / max(u_fadeDistance, 1e-4);
252
+ float edge = u_reveal * 1.1;
253
+ float mask = 1.0 - smoothstep(edge - 0.05, edge, rd);
254
+ float front = mask * smoothstep(edge - 0.22, edge - 0.05, rd);
255
+ col = col * mask + u_glowColor * front * (a * 1.8 + 0.08);
256
+ a = max(a * mask, front * 0.10);
257
+ }
258
+
259
+ if (a < 0.002) discard;
260
+ gl_FragColor = vec4(col, a);
261
+ }
262
+ `;
263
+ export const ApollonianGridMaterial = shaderMaterial({
264
+ u_time: apollonianGridMaterialDefaults.u_time,
265
+ u_cellSize: apollonianGridMaterialDefaults.u_cellSize,
266
+ u_lineWidth: apollonianGridMaterialDefaults.u_lineWidth,
267
+ u_sectionSize: apollonianGridMaterialDefaults.u_sectionSize,
268
+ u_sectionWidth: apollonianGridMaterialDefaults.u_sectionWidth,
269
+ u_lineColor: apollonianGridMaterialDefaults.u_lineColor.clone(),
270
+ u_sectionColor: apollonianGridMaterialDefaults.u_sectionColor.clone(),
271
+ u_cellColor: apollonianGridMaterialDefaults.u_cellColor.clone(),
272
+ u_glowColor: apollonianGridMaterialDefaults.u_glowColor.clone(),
273
+ u_bgColor: apollonianGridMaterialDefaults.u_bgColor.clone(),
274
+ u_bgOpacity: apollonianGridMaterialDefaults.u_bgOpacity,
275
+ u_lineMode: apollonianGridMaterialDefaults.u_lineMode,
276
+ u_cellMode: apollonianGridMaterialDefaults.u_cellMode,
277
+ u_animSpeed: apollonianGridMaterialDefaults.u_animSpeed,
278
+ u_animScale: apollonianGridMaterialDefaults.u_animScale,
279
+ u_animIntensity: apollonianGridMaterialDefaults.u_animIntensity,
280
+ u_fadeDistance: apollonianGridMaterialDefaults.u_fadeDistance,
281
+ u_fadeStrength: apollonianGridMaterialDefaults.u_fadeStrength,
282
+ u_focus: apollonianGridMaterialDefaults.u_focus.clone(),
283
+ u_mouse: apollonianGridMaterialDefaults.u_mouse.clone(),
284
+ u_displace: apollonianGridMaterialDefaults.u_displace,
285
+ u_reveal: apollonianGridMaterialDefaults.u_reveal,
286
+ u_depth: apollonianGridMaterialDefaults.u_depth,
287
+ u_morph: apollonianGridMaterialDefaults.u_morph,
288
+ }, vertex, fragment);
289
+ extend({ ApollonianGridMaterial });