@3driseai/3drise-core 1.0.20 → 1.0.22
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/autoAnimate/composer.d.ts +6 -0
- package/dist/autoAnimate/composer.d.ts.map +1 -1
- package/dist/autoAnimate/composer.js +4 -3
- package/dist/autoAnimate/describeScene.js +1 -1
- package/dist/catalog/catalogInfo.d.ts +22 -0
- package/dist/catalog/catalogInfo.d.ts.map +1 -0
- package/dist/catalog/catalogInfo.js +204 -0
- package/dist/catalog/index.d.ts +3 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +2 -0
- package/dist/catalog/objectCatalog.d.ts +33 -0
- package/dist/catalog/objectCatalog.d.ts.map +1 -0
- package/dist/catalog/objectCatalog.js +99 -0
- package/dist/data/allMaterials.js +2 -2
- package/dist/data/environmentDefaults.d.ts +10 -0
- package/dist/data/environmentDefaults.d.ts.map +1 -0
- package/dist/data/environmentDefaults.js +126 -0
- package/dist/data/gridsDefaults.d.ts +2 -0
- package/dist/data/gridsDefaults.d.ts.map +1 -1
- package/dist/data/gridsDefaults.js +186 -0
- package/dist/data/index.d.ts +4 -0
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +4 -0
- package/dist/data/landDefaults.d.ts +26 -0
- package/dist/data/landDefaults.d.ts.map +1 -0
- package/dist/data/landDefaults.js +76 -0
- package/dist/data/spaceDefaults.d.ts +10 -0
- package/dist/data/spaceDefaults.d.ts.map +1 -0
- package/dist/data/spaceDefaults.js +46 -0
- package/dist/data/textDefaults.d.ts +16 -0
- package/dist/data/textDefaults.d.ts.map +1 -0
- package/dist/data/textDefaults.js +199 -0
- package/dist/environment/oceanConfigs.d.ts +5 -4
- package/dist/environment/oceanConfigs.d.ts.map +1 -1
- package/dist/environment/oceanConfigs.js +2 -2
- package/dist/environment/terrainConfigs.d.ts +78 -0
- package/dist/environment/terrainConfigs.d.ts.map +1 -1
- package/dist/environment/terrainConfigs.js +72 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/properties/registry.d.ts +10 -1
- package/dist/properties/registry.d.ts.map +1 -1
- package/dist/properties/registry.js +60 -9
- package/dist/properties/tables/environmentProperties.d.ts +9 -0
- package/dist/properties/tables/environmentProperties.d.ts.map +1 -0
- package/dist/properties/tables/environmentProperties.js +127 -0
- package/dist/properties/tables/gridProperties.d.ts.map +1 -1
- package/dist/properties/tables/gridProperties.js +184 -82
- package/dist/properties/tables/index.d.ts +4 -1
- package/dist/properties/tables/index.d.ts.map +1 -1
- package/dist/properties/tables/index.js +4 -1
- package/dist/properties/tables/landProperties.d.ts +5 -0
- package/dist/properties/tables/landProperties.d.ts.map +1 -0
- package/dist/properties/tables/landProperties.js +24 -0
- package/dist/properties/tables/lightProperties.js +1 -1
- package/dist/properties/tables/materialBounds.js +1 -1
- package/dist/properties/tables/optionalProperties.d.ts +1 -2
- package/dist/properties/tables/optionalProperties.d.ts.map +1 -1
- package/dist/properties/tables/optionalProperties.js +21 -0
- package/dist/properties/tables/spaceProperties.d.ts +8 -0
- package/dist/properties/tables/spaceProperties.d.ts.map +1 -0
- package/dist/properties/tables/spaceProperties.js +42 -0
- package/dist/properties/tables/textProperties.d.ts +4 -0
- package/dist/properties/tables/textProperties.d.ts.map +1 -0
- package/dist/properties/tables/textProperties.js +361 -0
- package/dist/properties/types.d.ts +1 -1
- package/dist/properties/types.d.ts.map +1 -1
- package/dist/services/MaterialRegistry.d.ts.map +1 -1
- package/dist/services/MaterialRegistry.js +2 -0
- package/dist/services/SkySystemManager.d.ts +22 -0
- package/dist/services/SkySystemManager.d.ts.map +1 -1
- package/dist/services/SkySystemManager.js +50 -18
- package/dist/services/TextureResolver.d.ts.map +1 -1
- package/dist/services/TextureResolver.js +22 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -1
- package/dist/shaders/ApollonianGridMaterial.d.ts +70 -0
- package/dist/shaders/ApollonianGridMaterial.d.ts.map +1 -0
- package/dist/shaders/ApollonianGridMaterial.js +289 -0
- package/dist/shaders/ConformalGridMaterial.d.ts +91 -0
- package/dist/shaders/ConformalGridMaterial.d.ts.map +1 -0
- package/dist/shaders/ConformalGridMaterial.js +335 -0
- package/dist/shaders/HilbertGridMaterial.d.ts +79 -0
- package/dist/shaders/HilbertGridMaterial.d.ts.map +1 -0
- package/dist/shaders/HilbertGridMaterial.js +329 -0
- package/dist/shaders/LensingGridMaterial.d.ts +73 -0
- package/dist/shaders/LensingGridMaterial.d.ts.map +1 -0
- package/dist/shaders/LensingGridMaterial.js +253 -0
- package/dist/shaders/ParastichyGridMaterial.d.ts +76 -0
- package/dist/shaders/ParastichyGridMaterial.d.ts.map +1 -0
- package/dist/shaders/ParastichyGridMaterial.js +282 -0
- package/dist/shaders/PhyllotaxisGridMaterial.d.ts +85 -0
- package/dist/shaders/PhyllotaxisGridMaterial.d.ts.map +1 -0
- package/dist/shaders/PhyllotaxisGridMaterial.js +532 -0
- package/dist/shaders/SkyboxMaterial.js +3 -3
- package/dist/shaders/StarsMaterial.d.ts +5 -0
- package/dist/shaders/StarsMaterial.d.ts.map +1 -1
- package/dist/shaders/StarsMaterial.js +59 -57
- package/dist/shaders/TruchetGridMaterial.d.ts +76 -0
- package/dist/shaders/TruchetGridMaterial.d.ts.map +1 -0
- package/dist/shaders/TruchetGridMaterial.js +290 -0
- package/dist/shaders/index.d.ts +7 -0
- package/dist/shaders/index.d.ts.map +1 -1
- package/dist/shaders/index.js +7 -0
- package/dist/types/actions.d.ts +6 -5
- package/dist/types/actions.d.ts.map +1 -1
- package/dist/types/commands.d.ts +61 -0
- package/dist/types/commands.d.ts.map +1 -0
- package/dist/types/commands.js +1 -0
- package/dist/types/environment.d.ts +34 -1
- package/dist/types/environment.d.ts.map +1 -1
- package/dist/types/environment.js +15 -0
- package/dist/types/environmentObjects.d.ts +152 -0
- package/dist/types/environmentObjects.d.ts.map +1 -0
- package/dist/types/environmentObjects.js +10 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/landObjects.d.ts +15 -0
- package/dist/types/landObjects.d.ts.map +1 -0
- package/dist/types/landObjects.js +1 -0
- package/dist/types/objectSettings.d.ts +187 -16
- package/dist/types/objectSettings.d.ts.map +1 -1
- package/dist/types/objectsConfigs.d.ts +0 -3
- package/dist/types/objectsConfigs.d.ts.map +1 -1
- package/dist/types/scene3d.d.ts +8 -5
- package/dist/types/scene3d.d.ts.map +1 -1
- package/dist/types/spaceObjects.d.ts +65 -0
- package/dist/types/spaceObjects.d.ts.map +1 -0
- package/dist/types/spaceObjects.js +11 -0
- package/dist/types/textObjects.d.ts +352 -0
- package/dist/types/textObjects.d.ts.map +1 -0
- package/dist/types/textObjects.js +14 -0
- package/dist/types/types.d.ts +3 -6
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/users.d.ts +3 -1
- package/dist/types/users.d.ts.map +1 -1
- package/dist/types/users.js +2 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +4 -0
- package/dist/ui/uiBindings.d.ts +45 -0
- package/dist/ui/uiBindings.d.ts.map +1 -0
- package/dist/ui/uiBindings.js +172 -0
- package/dist/ui/uiKeys.d.ts +14 -0
- package/dist/ui/uiKeys.d.ts.map +1 -0
- package/dist/ui/uiKeys.js +22 -0
- package/dist/ui/uiSanitize.d.ts +18 -0
- package/dist/ui/uiSanitize.d.ts.map +1 -0
- package/dist/ui/uiSanitize.js +251 -0
- package/dist/ui/uiSpec.d.ts +116 -0
- package/dist/ui/uiSpec.d.ts.map +1 -0
- package/dist/ui/uiSpec.js +173 -0
- package/dist/utils/environmentMigration.d.ts +3 -0
- package/dist/utils/environmentMigration.d.ts.map +1 -0
- package/dist/utils/environmentMigration.js +50 -0
- package/dist/utils/generativeAnimatable.d.ts +1 -1
- package/dist/utils/generativeAnimatable.d.ts.map +1 -1
- package/dist/utils/generativeAnimatable.js +12 -0
- package/dist/utils/getAnimatableProperties.d.ts +1 -1
- package/dist/utils/getAnimatableProperties.d.ts.map +1 -1
- package/dist/utils/getAnimatableProperties.js +1 -1
- package/dist/utils/gridMigration.d.ts +3 -0
- package/dist/utils/gridMigration.d.ts.map +1 -0
- package/dist/utils/gridMigration.js +34 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/objectEffects.d.ts +24 -2
- package/dist/utils/objectEffects.d.ts.map +1 -1
- package/dist/utils/objectEffects.js +29 -2
- package/dist/utils/objectMigration.d.ts +9 -0
- package/dist/utils/objectMigration.d.ts.map +1 -0
- package/dist/utils/objectMigration.js +12 -0
- package/dist/utils/skyPhase.d.ts +61 -0
- package/dist/utils/skyPhase.d.ts.map +1 -0
- package/dist/utils/skyPhase.js +93 -0
- package/dist/utils/spaceMigration.d.ts +3 -0
- package/dist/utils/spaceMigration.d.ts.map +1 -0
- package/dist/utils/spaceMigration.js +46 -0
- package/dist/utils/sunUtils.d.ts +26 -1
- package/dist/utils/sunUtils.d.ts.map +1 -1
- package/dist/utils/sunUtils.js +37 -6
- package/package.json +1 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
+
import { sunDirectionFromAngles } from '../utils/sunUtils.js';
|
|
3
|
+
import { SKY_PHASE_ELEVATIONS } from '../utils/skyPhase.js';
|
|
2
4
|
const SUNRISE = 6;
|
|
3
5
|
const SUNSET = 21;
|
|
4
6
|
const MAX_ELEVATION = 42;
|
|
@@ -9,6 +11,11 @@ const HORIZON_OFFSET = 5;
|
|
|
9
11
|
const MAX_NIGHT_DEPTH = 21;
|
|
10
12
|
/** Real seconds between playback write-backs to the host. */
|
|
11
13
|
const SYNC_INTERVAL_SECONDS = 0.25;
|
|
14
|
+
const DEFAULT_MOON_PHASE = 0.5;
|
|
15
|
+
const wrap01 = (v) => ((v % 1) + 1) % 1;
|
|
16
|
+
const wrap24 = (h) => ((h % 24) + 24) % 24;
|
|
17
|
+
/** Lit fraction of the moon's disc for a phase in 0..1. */
|
|
18
|
+
export const moonIlluminationForPhase = (phase) => (1 - Math.cos(2 * Math.PI * phase)) / 2;
|
|
12
19
|
export class SkySystemManager {
|
|
13
20
|
static instance = null;
|
|
14
21
|
timeInHours = 12;
|
|
@@ -20,6 +27,9 @@ export class SkySystemManager {
|
|
|
20
27
|
sunElevation = 37;
|
|
21
28
|
sunAzimuth = 270;
|
|
22
29
|
sunDirection = new THREE.Vector3(0, 1, 0);
|
|
30
|
+
moonPhase = DEFAULT_MOON_PHASE;
|
|
31
|
+
moonElevation = 0;
|
|
32
|
+
moonDirection = new THREE.Vector3(0, -1, 0);
|
|
23
33
|
enabled = false;
|
|
24
34
|
timescale = 60;
|
|
25
35
|
autoAnimate = false;
|
|
@@ -38,7 +48,7 @@ export class SkySystemManager {
|
|
|
38
48
|
* otherwise double-tick it and stomp its settings. */
|
|
39
49
|
driver = null;
|
|
40
50
|
constructor() {
|
|
41
|
-
this.
|
|
51
|
+
this.recalculateState();
|
|
42
52
|
}
|
|
43
53
|
static getInstance() {
|
|
44
54
|
if (!SkySystemManager.instance) {
|
|
@@ -67,6 +77,9 @@ export class SkySystemManager {
|
|
|
67
77
|
return this.driver !== null;
|
|
68
78
|
}
|
|
69
79
|
setTimeSettings(settings) {
|
|
80
|
+
const moonPhase = wrap01(settings.moonPhase ?? DEFAULT_MOON_PHASE);
|
|
81
|
+
const phaseChanged = moonPhase !== this.moonPhase;
|
|
82
|
+
this.moonPhase = moonPhase;
|
|
70
83
|
this.enabled = settings.enabled;
|
|
71
84
|
this.timescale = settings.timescale;
|
|
72
85
|
this.autoAnimate = settings.autoAnimate;
|
|
@@ -94,6 +107,9 @@ export class SkySystemManager {
|
|
|
94
107
|
this.syncAccumulator = 0;
|
|
95
108
|
this.recalculateState();
|
|
96
109
|
}
|
|
110
|
+
else if (phaseChanged) {
|
|
111
|
+
this.recalculateState();
|
|
112
|
+
}
|
|
97
113
|
}
|
|
98
114
|
setOnTimeSync(callback) {
|
|
99
115
|
this.onTimeSync = callback;
|
|
@@ -139,14 +155,16 @@ export class SkySystemManager {
|
|
|
139
155
|
elapsedTime: this.elapsedTime,
|
|
140
156
|
autoAnimate: this.autoAnimate,
|
|
141
157
|
advancing: this.isAdvancing(),
|
|
158
|
+
moonDirection: this.moonDirection,
|
|
159
|
+
moonElevation: this.moonElevation,
|
|
160
|
+
moonPhase: this.moonPhase,
|
|
161
|
+
moonIllumination: moonIlluminationForPhase(this.moonPhase),
|
|
142
162
|
};
|
|
143
163
|
}
|
|
144
164
|
getStateByTime(timeOfDay) {
|
|
145
165
|
const state = this.calculateTimeState(timeOfDay);
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const distance = 0.5;
|
|
149
|
-
const sunDirection = new THREE.Vector3(distance * Math.cos(el) * Math.sin(az), distance * Math.sin(el), distance * Math.cos(el) * Math.cos(az)).normalize();
|
|
166
|
+
const sunDirection = sunDirectionFromAngles(state.sunElevation, this.transformAzimuth(state.sunAzimuth), new THREE.Vector3());
|
|
167
|
+
const moon = this.calculateMoon(timeOfDay, new THREE.Vector3());
|
|
150
168
|
return {
|
|
151
169
|
timeInHours: timeOfDay,
|
|
152
170
|
normalizedTime: state.normalizedTime,
|
|
@@ -159,6 +177,10 @@ export class SkySystemManager {
|
|
|
159
177
|
elapsedTime: this.elapsedTime,
|
|
160
178
|
autoAnimate: this.autoAnimate,
|
|
161
179
|
advancing: this.isAdvancing(),
|
|
180
|
+
moonDirection: moon.direction,
|
|
181
|
+
moonElevation: moon.elevation,
|
|
182
|
+
moonPhase: this.moonPhase,
|
|
183
|
+
moonIllumination: moonIlluminationForPhase(this.moonPhase),
|
|
162
184
|
};
|
|
163
185
|
}
|
|
164
186
|
getTime() {
|
|
@@ -240,6 +262,18 @@ export class SkySystemManager {
|
|
|
240
262
|
this.sunElevation = state.sunElevation;
|
|
241
263
|
this.sunAzimuth = state.sunAzimuth;
|
|
242
264
|
this.updateSunDirection();
|
|
265
|
+
this.moonElevation = this.calculateMoon(this.timeInHours, this.moonDirection).elevation;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* The moon runs the sun's own daily arc, `moonPhase` of a day behind it:
|
|
269
|
+
* a new moon rides with the sun, a full moon is 12 h behind — rising at
|
|
270
|
+
* sunset, highest at midnight, setting at sunrise — which is where the real
|
|
271
|
+
* one is. Same curve, same convention, so the two can never cross wrongly.
|
|
272
|
+
*/
|
|
273
|
+
calculateMoon(timeInHours, out) {
|
|
274
|
+
const m = this.calculateTimeState(wrap24(timeInHours - this.moonPhase * 24));
|
|
275
|
+
sunDirectionFromAngles(m.sunElevation, this.transformAzimuth(m.sunAzimuth), out);
|
|
276
|
+
return { elevation: m.sunElevation, direction: out };
|
|
243
277
|
}
|
|
244
278
|
/**
|
|
245
279
|
* Sun elevation and azimuth for a given hour.
|
|
@@ -277,14 +311,14 @@ export class SkySystemManager {
|
|
|
277
311
|
sunElevation = -HORIZON_OFFSET - Math.cos(Math.PI * (normalizedTime - 0.5)) * MAX_NIGHT_DEPTH;
|
|
278
312
|
sunAzimuth = 360 + 180 * normalizedTime;
|
|
279
313
|
}
|
|
314
|
+
// Labels follow the sun's height (skyPhase), the same keys the atmosphere
|
|
315
|
+
// and the stars turn on, so the label never says Midday under a red sky.
|
|
280
316
|
let timeOfDay = 'Nighttime';
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
else
|
|
287
|
-
timeOfDay = 'Sunset';
|
|
317
|
+
if (sunElevation >= SKY_PHASE_ELEVATIONS.day)
|
|
318
|
+
timeOfDay = 'Midday';
|
|
319
|
+
else if (sunElevation > SKY_PHASE_ELEVATIONS.twilight) {
|
|
320
|
+
const morning = isDaytime ? normalizedTime < 0.5 : timeInHours < 12;
|
|
321
|
+
timeOfDay = morning ? 'Sunrise' : 'Sunset';
|
|
288
322
|
}
|
|
289
323
|
return { normalizedTime, isDaytime, timeOfDay, sunElevation, sunAzimuth };
|
|
290
324
|
}
|
|
@@ -295,13 +329,11 @@ export class SkySystemManager {
|
|
|
295
329
|
const wrapped = (((270 - rawAzimuth) % 360) + 360) % 360;
|
|
296
330
|
return wrapped - 180;
|
|
297
331
|
}
|
|
332
|
+
/** Same convention as the Preetham sky (sunUtils), so the direction this
|
|
333
|
+
* publishes is exactly where SkyController draws the disc for the same
|
|
334
|
+
* elevation/azimuth. */
|
|
298
335
|
updateSunDirection() {
|
|
299
|
-
|
|
300
|
-
const az = THREE.MathUtils.degToRad(this.transformAzimuth(this.sunAzimuth));
|
|
301
|
-
const distance = 0.5;
|
|
302
|
-
this.sunDirection
|
|
303
|
-
.set(distance * Math.cos(el) * Math.sin(az), distance * Math.sin(el), distance * Math.cos(el) * Math.cos(az))
|
|
304
|
-
.normalize();
|
|
336
|
+
sunDirectionFromAngles(this.sunElevation, this.transformAzimuth(this.sunAzimuth), this.sunDirection);
|
|
305
337
|
}
|
|
306
338
|
}
|
|
307
339
|
export const skySystemManager = SkySystemManager.getInstance();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextureResolver.d.ts","sourceRoot":"","sources":["../../src/services/TextureResolver.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"TextureResolver.d.ts","sourceRoot":"","sources":["../../src/services/TextureResolver.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AAKhD,cAAM,sBAAsB;IAExB,OAAO,CAAC,KAAK,CAAa;IAC1B;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe5C;;OAEG;IACH,YAAY,CAAC,IAAI,GAAE,MAAiB,GAAG,OAAO;IAG9C;;;;;;;;;;OAUG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAoDnG;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAG9B;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAG3C;;OAEG;IACH,UAAU,IAAI,IAAI;IAMlB;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOxB;;OAEG;IACH,QAAQ,IAAI;QACA,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,EAAE,CAAC;KACxB;CAMZ;AAED,eAAO,MAAM,eAAe,EAAE,sBAAqD,CAAC;AAEpF,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
import { loadTextureAsync } from '../utils/loadingManager.js';
|
|
14
14
|
import { NoiseGenerator } from './NoiseGenerator.js';
|
|
15
15
|
import MaterialRegistryAPI from '../services/MaterialRegistry.js';
|
|
16
|
+
import { SRGBColorSpace } from "three";
|
|
17
|
+
/** Texture slots that hold colour (sRGB) data; the rest (normal, roughness…) are linear. */
|
|
18
|
+
const SRGB_TEXTURE_KEYS = new Set(['map', 'emissiveMap', 'specularColorMap', 'sheenColorMap']);
|
|
16
19
|
class TextureResolverService {
|
|
17
20
|
// Cache: URL string → loaded Texture
|
|
18
21
|
cache = new Map();
|
|
@@ -87,6 +90,25 @@ class TextureResolverService {
|
|
|
87
90
|
}
|
|
88
91
|
// Wait for all texture loads to complete
|
|
89
92
|
await Promise.all(texturePromises);
|
|
93
|
+
// Per-material texture state on a copy (the loaded texture is cached and shared):
|
|
94
|
+
// tiling from settings.textureRepeat ([x, y] or a number), and sRGB for colour maps.
|
|
95
|
+
const rep = settings.textureRepeat;
|
|
96
|
+
const repeat = Array.isArray(rep) && rep.length === 2 ? rep : typeof rep === 'number' ? [rep, rep] : null;
|
|
97
|
+
for (const key of textureKeys) {
|
|
98
|
+
const tex = resolved[key];
|
|
99
|
+
if (!tex || !tex.isTexture || typeof settings[key] !== 'string')
|
|
100
|
+
continue;
|
|
101
|
+
const srgb = SRGB_TEXTURE_KEYS.has(key);
|
|
102
|
+
if (!repeat && !srgb)
|
|
103
|
+
continue;
|
|
104
|
+
const copy = tex.clone();
|
|
105
|
+
if (srgb)
|
|
106
|
+
copy.colorSpace = SRGBColorSpace;
|
|
107
|
+
if (repeat)
|
|
108
|
+
copy.repeat.set(Number(repeat[0]) || 1, Number(repeat[1]) || 1);
|
|
109
|
+
copy.needsUpdate = true;
|
|
110
|
+
resolved[key] = copy;
|
|
111
|
+
}
|
|
90
112
|
return resolved;
|
|
91
113
|
}
|
|
92
114
|
/**
|
package/dist/services/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export { PositionsCreator } from './PositionsCreator';
|
|
|
12
12
|
export * from './NoiseGenerator';
|
|
13
13
|
export { TextureResolverService, textureResolver } from './TextureResolver';
|
|
14
14
|
export { UniformConverter, UniformProcessor, uniformConverter } from './UniformConverter';
|
|
15
|
-
export { SkySystemManager, skySystemManager } from './SkySystemManager';
|
|
15
|
+
export { SkySystemManager, skySystemManager, moonIlluminationForPhase } from './SkySystemManager';
|
|
16
16
|
export { CubeCameraManager, cubeCameraManager } from './CubeCameraManager';
|
|
17
17
|
export { default as SceneStore } from './SceneStore';
|
|
18
18
|
export { default as SceneActions } from './SceneActions';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,GAAG,MAAM,oBAAoB,CAAC;AAE5H,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACtF,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,GAAG,MAAM,oBAAoB,CAAC;AAE5H,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACtF,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/services/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { PositionsCreator } from './PositionsCreator.js';
|
|
|
9
9
|
export * from './NoiseGenerator.js';
|
|
10
10
|
export { TextureResolverService, textureResolver } from './TextureResolver.js';
|
|
11
11
|
export { UniformConverter, UniformProcessor, uniformConverter } from './UniformConverter.js';
|
|
12
|
-
export { SkySystemManager, skySystemManager } from './SkySystemManager.js';
|
|
12
|
+
export { SkySystemManager, skySystemManager, moonIlluminationForPhase } from './SkySystemManager.js';
|
|
13
13
|
export { CubeCameraManager, cubeCameraManager } from './CubeCameraManager.js';
|
|
14
14
|
export { default as SceneStore } from './SceneStore.js';
|
|
15
15
|
export { default as SceneActions } from './SceneActions.js';
|
|
@@ -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 });
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
export interface ConformalGridMaterialUniforms {
|
|
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
|
+
/** The flow: 0 source + sink, 1 spiral vortex, 2 spinning cylinder, 3 corner */
|
|
32
|
+
u_flowMap: number;
|
|
33
|
+
/** Distance from the centre to the poles, or the cylinder radius, in world units */
|
|
34
|
+
u_poleSpread: number;
|
|
35
|
+
/** Lattice lines per turn round a pole (whole number, so the log seam closes) */
|
|
36
|
+
u_spokes: number;
|
|
37
|
+
/** Spiral arms of the vortex flow; 0 gives a plain polar web */
|
|
38
|
+
u_arms: number;
|
|
39
|
+
/** Circulation round the cylinder (lift); at ±2 both stagnation points meet */
|
|
40
|
+
u_circulation: number;
|
|
41
|
+
/** How fast the lattice streams along the flow; negative reverses it */
|
|
42
|
+
u_drift: number;
|
|
43
|
+
/** Strength of the speed-coloured stream-tube fill */
|
|
44
|
+
u_fill: number;
|
|
45
|
+
/** Brightness of the dashes carried along the streamlines */
|
|
46
|
+
u_dye: number;
|
|
47
|
+
/** accumulated on the CPU from drift (never multiplied by time in the shader) */
|
|
48
|
+
u_flowPhase: number;
|
|
49
|
+
}
|
|
50
|
+
declare module '@react-three/fiber' {
|
|
51
|
+
interface ThreeElements {
|
|
52
|
+
conformalGridMaterial: ThreeElements['shaderMaterial'] & Partial<ConformalGridMaterialUniforms>;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export declare const conformalGridMaterialDefaults: ConformalGridMaterialUniforms;
|
|
56
|
+
export declare const ConformalGridMaterial: import("@react-three/fiber").ConstructorRepresentation<THREE.ShaderMaterial & {
|
|
57
|
+
u_time: number;
|
|
58
|
+
u_cellSize: number;
|
|
59
|
+
u_lineWidth: number;
|
|
60
|
+
u_sectionSize: number;
|
|
61
|
+
u_sectionWidth: number;
|
|
62
|
+
u_lineColor: THREE.Color;
|
|
63
|
+
u_sectionColor: THREE.Color;
|
|
64
|
+
u_cellColor: THREE.Color;
|
|
65
|
+
u_glowColor: THREE.Color;
|
|
66
|
+
u_bgColor: THREE.Color;
|
|
67
|
+
u_bgOpacity: number;
|
|
68
|
+
u_lineMode: number;
|
|
69
|
+
u_cellMode: number;
|
|
70
|
+
u_animSpeed: number;
|
|
71
|
+
u_animScale: number;
|
|
72
|
+
u_animIntensity: number;
|
|
73
|
+
u_fadeDistance: number;
|
|
74
|
+
u_fadeStrength: number;
|
|
75
|
+
u_focus: THREE.Vector2;
|
|
76
|
+
u_mouse: THREE.Vector2;
|
|
77
|
+
u_displace: number;
|
|
78
|
+
u_reveal: number;
|
|
79
|
+
u_flowMap: number;
|
|
80
|
+
u_poleSpread: number;
|
|
81
|
+
u_spokes: number;
|
|
82
|
+
u_arms: number;
|
|
83
|
+
u_circulation: number;
|
|
84
|
+
u_drift: number;
|
|
85
|
+
u_fill: number;
|
|
86
|
+
u_dye: number;
|
|
87
|
+
u_flowPhase: number;
|
|
88
|
+
}> & {
|
|
89
|
+
key: string;
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=ConformalGridMaterial.d.ts.map
|