@3driseai/3drise-viewer 0.1.30 → 0.1.32
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/animationsV2/ClipPlayer.d.ts.map +1 -1
- package/dist/animationsV2/ClipPlayer.js +14 -12
- package/dist/animationsV2/ClipsRuntime.d.ts +9 -0
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +54 -7
- package/dist/animationsV2/appliers.d.ts.map +1 -1
- package/dist/animationsV2/appliers.js +21 -2
- package/dist/animationsV2/clipUtils.d.ts.map +1 -1
- package/dist/animationsV2/clipUtils.js +4 -0
- package/dist/animationsV2/sequenceUtils.js +4 -5
- package/dist/animationsV2/sunSystemLive.d.ts +12 -0
- package/dist/animationsV2/sunSystemLive.d.ts.map +1 -0
- package/dist/animationsV2/sunSystemLive.js +8 -0
- package/dist/api/sceneHandle.d.ts +3 -1
- package/dist/api/sceneHandle.d.ts.map +1 -1
- package/dist/api/sceneHandle.js +2 -2
- package/dist/components/AdaptiveResolution.d.ts +9 -0
- package/dist/components/AdaptiveResolution.d.ts.map +1 -0
- package/dist/components/AdaptiveResolution.js +61 -0
- package/dist/components/CameraController.d.ts.map +1 -1
- package/dist/components/CameraController.js +24 -7
- package/dist/components/MoonDisc.d.ts.map +1 -1
- package/dist/components/MoonDisc.js +2 -1
- package/dist/components/OceanBuilder.d.ts +4 -1
- package/dist/components/OceanBuilder.d.ts.map +1 -1
- package/dist/components/OceanBuilder.js +2 -1
- package/dist/components/ParticlesGenerator.d.ts.map +1 -1
- package/dist/components/ParticlesGenerator.js +2 -0
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +5 -2
- package/dist/components/Skybox.d.ts.map +1 -1
- package/dist/components/Skybox.js +2 -1
- package/dist/components/SunLight.d.ts.map +1 -1
- package/dist/components/SunLight.js +3 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/lightBulb/LightBulb.d.ts.map +1 -1
- package/dist/components/lightBulb/LightBulb.js +7 -2
- package/dist/components/particles/FireworksParticles.d.ts +22 -0
- package/dist/components/particles/FireworksParticles.d.ts.map +1 -0
- package/dist/components/particles/FireworksParticles.js +1649 -0
- package/dist/components/particles/index.d.ts +2 -0
- package/dist/components/particles/index.d.ts.map +1 -1
- package/dist/components/particles/index.js +1 -0
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
- package/dist/components/terrain/TerrainSurface.js +26 -4
- package/dist/components/water/OceanSurface.d.ts.map +1 -1
- package/dist/components/water/OceanSurface.js +5 -1
- package/dist/components/water/types.d.ts +3 -1
- package/dist/components/water/types.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.d.ts +6 -2
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.js +22 -2
- package/dist/hooks/useOrbitTargetFollow.d.ts +10 -0
- package/dist/hooks/useOrbitTargetFollow.d.ts.map +1 -0
- package/dist/hooks/useOrbitTargetFollow.js +194 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/shaders/glsl/terrainCore.glsl.d.ts +18 -3
- package/dist/shaders/glsl/terrainCore.glsl.d.ts.map +1 -1
- package/dist/shaders/glsl/terrainCore.glsl.js +42 -21
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +36 -11
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -1
- package/dist/shaders/ocean/OceanSurfaceMaterial.js +96 -5
- package/dist/triggers/hosts/actions.d.ts.map +1 -1
- package/dist/triggers/hosts/actions.js +2 -0
- package/dist/triggers/hosts/timelineCues.js +1 -1
- package/dist/triggers/kinds/change.d.ts +4 -0
- package/dist/triggers/kinds/change.d.ts.map +1 -0
- package/dist/triggers/kinds/change.js +50 -0
- package/dist/triggers/kinds/index.d.ts +1 -0
- package/dist/triggers/kinds/index.d.ts.map +1 -1
- package/dist/triggers/kinds/index.js +1 -0
- package/dist/utils/CameraSingleton.d.ts +4 -0
- package/dist/utils/CameraSingleton.d.ts.map +1 -1
- package/dist/utils/CameraSingleton.js +4 -0
- package/dist/utils/deviceTier.d.ts +2 -0
- package/dist/utils/deviceTier.d.ts.map +1 -0
- package/dist/utils/deviceTier.js +16 -0
- package/dist/utils/environmentDrawOrder.d.ts +23 -0
- package/dist/utils/environmentDrawOrder.d.ts.map +1 -0
- package/dist/utils/environmentDrawOrder.js +22 -0
- package/dist/utils/terrainUniforms.d.ts +7 -0
- package/dist/utils/terrainUniforms.d.ts.map +1 -1
- package/dist/utils/terrainUniforms.js +15 -2
- package/package.json +2 -2
|
@@ -26,8 +26,12 @@
|
|
|
26
26
|
* per octave, nine octaves, several evaluations per pixel puts it into the
|
|
27
27
|
* billions of transcendentals per frame.
|
|
28
28
|
*/
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/**
|
|
30
|
+
* The uniforms the height field and the sun-shadow march read — and nothing else,
|
|
31
|
+
* so another material (the ocean) can include the field without redeclaring its
|
|
32
|
+
* own u_curvature, u_exposure, u_roughness… GLSL refuses a uniform declared twice.
|
|
33
|
+
*/
|
|
34
|
+
export const terrainFormUniforms = /* glsl */ `
|
|
31
35
|
uniform int u_terrainType;
|
|
32
36
|
|
|
33
37
|
uniform float u_elevation;
|
|
@@ -49,6 +53,29 @@ uniform float u_plateau;
|
|
|
49
53
|
uniform float u_valleyDepth;
|
|
50
54
|
uniform float u_valleyWidth;
|
|
51
55
|
|
|
56
|
+
// The analytic sun-shadow march (terrainShadow) - shared with the ocean, which
|
|
57
|
+
// marches the same field to put headland shadows on the water.
|
|
58
|
+
uniform float u_sunShadow, u_shadowSoftness;
|
|
59
|
+
uniform float u_shadowDistance;
|
|
60
|
+
uniform int u_shadowSteps;
|
|
61
|
+
|
|
62
|
+
// A land object: a bounded patch of this field, placed by its object's transform.
|
|
63
|
+
// Its "terrain space" is metres from the object's origin, unrotated, plus a seed
|
|
64
|
+
// offset; height is above the object's base. See TerrainMaterial's patch vertex.
|
|
65
|
+
#ifdef TERRAIN_PATCH
|
|
66
|
+
uniform vec2 u_patchSize; // footprint in metres (object scale x / z)
|
|
67
|
+
uniform vec2 u_patchOffset; // terrain-space centre: the seed's offset into the field
|
|
68
|
+
uniform float u_edgeWidth; // metres over which the land eases down to its base
|
|
69
|
+
uniform vec3 u_camTerrain; // the camera, in terrain space
|
|
70
|
+
uniform float u_scaleY; // object scale y: terrain metres = local y x this
|
|
71
|
+
uniform float u_patchCell; // metres per grid cell
|
|
72
|
+
#define TERRAIN_CAM u_camTerrain
|
|
73
|
+
#else
|
|
74
|
+
#define TERRAIN_CAM cameraPosition
|
|
75
|
+
#endif
|
|
76
|
+
`;
|
|
77
|
+
/** The terrain surface's own uniforms: shading, lighting, textures. */
|
|
78
|
+
export const terrainSurfaceUniforms = /* glsl */ `
|
|
52
79
|
uniform float u_cellSize;
|
|
53
80
|
uniform float u_curvature;
|
|
54
81
|
|
|
@@ -66,10 +93,8 @@ uniform float u_roughness, u_specular;
|
|
|
66
93
|
// per pixel removes an acos, a pow and three exps from every fragment.
|
|
67
94
|
uniform vec3 u_skyAmbient;
|
|
68
95
|
uniform vec3 u_groundAmbient;
|
|
69
|
-
uniform float u_ambient, u_bounce
|
|
70
|
-
uniform float u_shadowDistance;
|
|
96
|
+
uniform float u_ambient, u_bounce;
|
|
71
97
|
uniform float u_fogDensity, u_exposure;
|
|
72
|
-
uniform int u_shadowSteps;
|
|
73
98
|
|
|
74
99
|
// Ground textures. The far colour per layer is always set: the flat colour for an
|
|
75
100
|
// untextured layer, the texture's own mean x tint for a textured one, so the
|
|
@@ -88,20 +113,6 @@ uniform float u_tDistance;
|
|
|
88
113
|
uniform float u_tHeightBlend;
|
|
89
114
|
#endif
|
|
90
115
|
|
|
91
|
-
// A land object: a bounded patch of this field, placed by its object's transform.
|
|
92
|
-
// Its "terrain space" is metres from the object's origin, unrotated, plus a seed
|
|
93
|
-
// offset; height is above the object's base. See TerrainMaterial's patch vertex.
|
|
94
|
-
#ifdef TERRAIN_PATCH
|
|
95
|
-
uniform vec2 u_patchSize; // footprint in metres (object scale x / z)
|
|
96
|
-
uniform vec2 u_patchOffset; // terrain-space centre: the seed's offset into the field
|
|
97
|
-
uniform float u_edgeWidth; // metres over which the land eases down to its base
|
|
98
|
-
uniform vec3 u_camTerrain; // the camera, in terrain space
|
|
99
|
-
uniform float u_scaleY; // object scale y: terrain metres = local y x this
|
|
100
|
-
uniform float u_patchCell; // metres per grid cell
|
|
101
|
-
#define TERRAIN_CAM u_camTerrain
|
|
102
|
-
#else
|
|
103
|
-
#define TERRAIN_CAM cameraPosition
|
|
104
|
-
#endif
|
|
105
116
|
`;
|
|
106
117
|
/**
|
|
107
118
|
* Gradient noise with an analytic derivative.
|
|
@@ -515,7 +526,7 @@ float terrainOccluderAt(vec2 p, float lodCell){ return terrainHeightAt(p, lodCel
|
|
|
515
526
|
* The terminator itself stays per-pixel: `terrainLight` takes N·L from the
|
|
516
527
|
* fragment's own normal, so only the CAST shadow is interpolated.
|
|
517
528
|
*/
|
|
518
|
-
export const
|
|
529
|
+
export const terrainShadow = /* glsl */ `
|
|
519
530
|
/** 1 lit, 0 shadowed, soft in between. */
|
|
520
531
|
float terrainSunShadow(vec3 p, vec3 n, float lodCell, int steps){
|
|
521
532
|
if (steps < 1 || u_sunShadow <= 0.0) return 1.0;
|
|
@@ -585,6 +596,8 @@ float terrainShadowAt(vec3 p, vec3 n, float lodCell, float dist){
|
|
|
585
596
|
return mix(1.0, terrainSunShadow(p, n, lodCell, steps), fade);
|
|
586
597
|
}
|
|
587
598
|
|
|
599
|
+
`;
|
|
600
|
+
export const terrainShading = /* glsl */ `
|
|
588
601
|
/**
|
|
589
602
|
* Albedo.
|
|
590
603
|
*
|
|
@@ -867,5 +880,13 @@ void terrainSurfaceNear(vec3 wp, vec3 n, vec4 w, TerrainGrads g,
|
|
|
867
880
|
`;
|
|
868
881
|
/** Everything a surface material needs, in include order. Requires three's
|
|
869
882
|
* `<common>` and `skyLib` from cloudCore before it. */
|
|
883
|
+
/** Every uniform the terrain material reads. */
|
|
884
|
+
export const terrainUniforms = [terrainFormUniforms, terrainSurfaceUniforms].join('\n');
|
|
870
885
|
export const terrainField = [terrainUniforms, terrainNoise, terrainHeight].join('\n');
|
|
871
|
-
|
|
886
|
+
/**
|
|
887
|
+
* The height field and its sun-shadow march, with only the uniforms they read.
|
|
888
|
+
* What another material includes to stand water (or anything else) on the
|
|
889
|
+
* terrain: the ocean uses it for shoreline depth and headland shadows.
|
|
890
|
+
*/
|
|
891
|
+
export const terrainFieldOnly = [terrainFormUniforms, terrainNoise, terrainHeight, terrainShadow].join('\n');
|
|
892
|
+
export const terrainFull = [terrainField, terrainShadow, terrainShading].join('\n');
|
|
@@ -6,6 +6,40 @@ export interface OceanMaterialUniforms {
|
|
|
6
6
|
/** Uniform-space defaults. Config units are converted by `applyOceanUniforms`;
|
|
7
7
|
* these are only what the material holds before anything is applied. */
|
|
8
8
|
export declare const oceanMaterialDefaults: {
|
|
9
|
+
u_sunDir: THREE.Vector3;
|
|
10
|
+
u_sunColor: THREE.Color;
|
|
11
|
+
u_skyAmbient: THREE.Color;
|
|
12
|
+
u_groundAmbient: THREE.Color;
|
|
13
|
+
u_sunIntensity: number;
|
|
14
|
+
u_moonDir: THREE.Vector3;
|
|
15
|
+
u_moonColor: THREE.Color;
|
|
16
|
+
u_turbidity: number;
|
|
17
|
+
u_rayleigh: number;
|
|
18
|
+
u_mieCoefficient: number;
|
|
19
|
+
u_mieG: number;
|
|
20
|
+
u_terrainType: number;
|
|
21
|
+
u_elevation: number;
|
|
22
|
+
u_seaLevel: number;
|
|
23
|
+
u_baseScale: number;
|
|
24
|
+
u_octaves: number;
|
|
25
|
+
u_lacunarity: number;
|
|
26
|
+
u_gain: number;
|
|
27
|
+
u_ridge: number;
|
|
28
|
+
u_warpStrength: number;
|
|
29
|
+
u_warpScale: number;
|
|
30
|
+
u_erosion: number;
|
|
31
|
+
u_terraces: number;
|
|
32
|
+
u_terraceSharp: number;
|
|
33
|
+
u_bearingDir: THREE.Vector2;
|
|
34
|
+
u_duneFreq: number;
|
|
35
|
+
u_duneAsym: number;
|
|
36
|
+
u_plateau: number;
|
|
37
|
+
u_valleyDepth: number;
|
|
38
|
+
u_valleyWidth: number;
|
|
39
|
+
u_sunShadow: number;
|
|
40
|
+
u_shadowSoftness: number;
|
|
41
|
+
u_shadowDistance: number;
|
|
42
|
+
u_shadowSteps: number;
|
|
9
43
|
u_waveA: THREE.Vector4[];
|
|
10
44
|
u_waveB: THREE.Vector4[];
|
|
11
45
|
u_waveCount: number;
|
|
@@ -36,17 +70,8 @@ export declare const oceanMaterialDefaults: {
|
|
|
36
70
|
u_exposure: number;
|
|
37
71
|
u_curvature: number;
|
|
38
72
|
u_receiveShadows: number;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
u_skyAmbient: THREE.Color;
|
|
42
|
-
u_groundAmbient: THREE.Color;
|
|
43
|
-
u_sunIntensity: number;
|
|
44
|
-
u_moonDir: THREE.Vector3;
|
|
45
|
-
u_moonColor: THREE.Color;
|
|
46
|
-
u_turbidity: number;
|
|
47
|
-
u_rayleigh: number;
|
|
48
|
-
u_mieCoefficient: number;
|
|
49
|
-
u_mieG: number;
|
|
73
|
+
u_shoreDepth: number;
|
|
74
|
+
u_shoreFoam: number;
|
|
50
75
|
};
|
|
51
76
|
export declare class OceanSurfaceMaterial extends THREE.ShaderMaterial {
|
|
52
77
|
constructor();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OceanSurfaceMaterial.d.ts","sourceRoot":"","sources":["../../../src/shaders/ocean/OceanSurfaceMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"OceanSurfaceMaterial.d.ts","sourceRoot":"","sources":["../../../src/shaders/ocean/OceanSurfaceMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AA0R9D,MAAM,WAAW,qBAAqB;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAA;CAChC;AAMD;yEACyE;AACzE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDjC,CAAA;AAgBD,qBAAa,oBAAqB,SAAQ,KAAK,CAAC,cAAc;;CAa7D;AAID,OAAO,QAAQ,oBAAoB,CAAC;IAChC,UAAU,aAAa;QACnB,oBAAoB,EAAE,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAA;KAClE;CACJ"}
|
|
@@ -2,6 +2,7 @@ import * as THREE from 'three';
|
|
|
2
2
|
import { extend } from '@react-three/fiber';
|
|
3
3
|
import { skyLib } from '../glsl/cloudCore.glsl.js';
|
|
4
4
|
import { oceanFull, MAX_WAVES } from '../glsl/oceanCore.glsl.js';
|
|
5
|
+
import { terrainFieldOnly } from '../glsl/terrainCore.glsl.js';
|
|
5
6
|
/**
|
|
6
7
|
* The water surface material. Used by both hosts — the world clipmap and a
|
|
7
8
|
* placed body — and by all four water types, which differ in the spectrum the
|
|
@@ -44,6 +45,16 @@ const vertex = /* glsl */ `
|
|
|
44
45
|
${skyLib}
|
|
45
46
|
${oceanFull}
|
|
46
47
|
|
|
48
|
+
// The ground under the water (phase 4 of the ocean plan). Only the height field
|
|
49
|
+
// and its sun-shadow march, with only their own uniforms - the ocean has its own
|
|
50
|
+
// u_curvature, u_exposure... and GLSL refuses a uniform declared twice. Mind the
|
|
51
|
+
// trap in oceanCore: the field's u_seaLevel is the TERRAIN's; the water's level
|
|
52
|
+
// is u_waterLevel.
|
|
53
|
+
#ifdef OCEAN_TERRAIN
|
|
54
|
+
${terrainFieldOnly}
|
|
55
|
+
#endif
|
|
56
|
+
uniform float u_shoreDepth;
|
|
57
|
+
|
|
47
58
|
/** World size of this vertex's cell. Per-vertex so one material serves every
|
|
48
59
|
* clipmap ring, and a placed body sets it from its own grid. */
|
|
49
60
|
attribute float aCell;
|
|
@@ -59,6 +70,8 @@ varying float vFoam;
|
|
|
59
70
|
varying float vRelHeight;
|
|
60
71
|
varying float vDist;
|
|
61
72
|
varying float vDepthFactor;
|
|
73
|
+
varying float vShoreDepth;
|
|
74
|
+
varying float vTerrainShadow;
|
|
62
75
|
|
|
63
76
|
void main(){
|
|
64
77
|
// Geomorph first, waves second. The other order blends two different points on
|
|
@@ -85,15 +98,41 @@ void main(){
|
|
|
85
98
|
bool isBody = u_bodyHalf.x > 0.0;
|
|
86
99
|
vec2 fieldXZ = isBody ? local : wxz;
|
|
87
100
|
|
|
101
|
+
// Water depth from the terrain height field under this vertex.
|
|
102
|
+
//
|
|
103
|
+
// Waves lose their height as the water shoals and are gone at the waterline.
|
|
104
|
+
// That is the physics, and it is also the fix for the shoreline: an open-sea
|
|
105
|
+
// swell heaving a couple of metres up and down a 1:4 beach swept the waterline
|
|
106
|
+
// ~8 m in and out on every wave, and with the edge being a hard depth-buffer
|
|
107
|
+
// cut through the rock, that read as jitter. With the amplitude gone at depth
|
|
108
|
+
// 0, the line sits still where the ground meets the level. Waves get twice the
|
|
109
|
+
// shore depth to die in, because they need more room than the colour does.
|
|
110
|
+
float shoal = 1.0;
|
|
111
|
+
vShoreDepth = 1.0e4;
|
|
112
|
+
vTerrainShadow = 1.0;
|
|
113
|
+
#ifdef OCEAN_TERRAIN
|
|
114
|
+
if (!isBody) {
|
|
115
|
+
float ground = terrainHeightAt(wxz, max(cellLod, 0.5));
|
|
116
|
+
vShoreDepth = u_waterLevel - ground;
|
|
117
|
+
shoal = smoothstep(0.0, max(u_shoreDepth, 0.05) * 2.0, vShoreDepth);
|
|
118
|
+
// A headland's shadow across the bay: the terrain's own analytic march, from
|
|
119
|
+
// the flat water level, faded and stepped by distance exactly as on land.
|
|
120
|
+
vec3 sp = vec3(wxz.x, u_waterLevel, wxz.y);
|
|
121
|
+
float shadow = terrainShadowAt(sp, vec3(0.0, 1.0, 0.0), cellLod, distance(sp, cameraPosition));
|
|
122
|
+
vTerrainShadow = mix(1.0, shadow, saturate(u_sunShadow));
|
|
123
|
+
}
|
|
124
|
+
#endif
|
|
125
|
+
|
|
88
126
|
vec3 disp; vec3 nrm; float jac; float rel;
|
|
89
|
-
oceanWaveSum(fieldXZ, cellLod, u_amplitudeScale * edge, disp, nrm, jac, rel);
|
|
127
|
+
oceanWaveSum(fieldXZ, cellLod, u_amplitudeScale * edge * shoal, disp, nrm, jac, rel);
|
|
90
128
|
|
|
91
129
|
vFoam = oceanFoam(jac, rel, vec3(fieldXZ.x, 0.0, fieldXZ.y));
|
|
92
130
|
vRelHeight = rel;
|
|
93
131
|
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
|
|
132
|
+
// 1 in open water, ramping to 0 as the bottom comes up (shallow colour). Open
|
|
133
|
+
// water everywhere without terrain, until the refraction grab gives depth for
|
|
134
|
+
// anything else standing in the water.
|
|
135
|
+
vDepthFactor = saturate(vShoreDepth / max(u_shoreDepth, 0.05));
|
|
97
136
|
|
|
98
137
|
// Displacement is in field space, which for both hosts is object space up to a
|
|
99
138
|
// translation - so it can be added to transformed directly. Deriving it from
|
|
@@ -148,6 +187,11 @@ varying float vFoam;
|
|
|
148
187
|
varying float vRelHeight;
|
|
149
188
|
varying float vDist;
|
|
150
189
|
varying float vDepthFactor;
|
|
190
|
+
varying float vShoreDepth;
|
|
191
|
+
varying float vTerrainShadow;
|
|
192
|
+
|
|
193
|
+
uniform float u_shoreDepth;
|
|
194
|
+
uniform float u_shoreFoam;
|
|
151
195
|
|
|
152
196
|
void main(){
|
|
153
197
|
vec3 viewDir = normalize(vWorld - cameraPosition);
|
|
@@ -179,7 +223,19 @@ void main(){
|
|
|
179
223
|
sceneShadow = mix(1.0, getShadowMask(), u_receiveShadows);
|
|
180
224
|
#endif
|
|
181
225
|
|
|
182
|
-
|
|
226
|
+
sceneShadow *= vTerrainShadow;
|
|
227
|
+
|
|
228
|
+
// Shore foam: a band where the ground comes up through the surface, broken by
|
|
229
|
+
// drifting noise so it reads as wash rather than a painted outline. It also
|
|
230
|
+
// covers the hard depth-buffer edge where the water plane meets the rock.
|
|
231
|
+
float foam = vFoam;
|
|
232
|
+
if (u_shoreFoam > 0.0 && vShoreDepth < 1.0e3) {
|
|
233
|
+
float band = 1.0 - smoothstep(0.0, max(u_shoreDepth * 0.35, 0.05), vShoreDepth);
|
|
234
|
+
float wash = oNoised(vWorld.xz * 0.35 + vec2(u_time * 0.15, -u_time * 0.07)).x * 0.5 + 0.5;
|
|
235
|
+
foam = max(foam, saturate(band * (0.45 + 0.55 * wash) * u_shoreFoam));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
vec3 col = oceanLight(vWorld, n, viewDir, foam, vRelHeight, sceneShadow, vDepthFactor, roughAA, vec3(0.0));
|
|
183
239
|
col = oceanAerial(col, viewDir, vDist);
|
|
184
240
|
col *= u_exposure;
|
|
185
241
|
|
|
@@ -190,6 +246,36 @@ void main(){
|
|
|
190
246
|
#include <fog_fragment>
|
|
191
247
|
}
|
|
192
248
|
`;
|
|
249
|
+
/** The terrain field's uniforms (terrainFormUniforms), at harmless values until
|
|
250
|
+
* applyTerrainFieldUniforms fills them. u_sunShadow here is the WATER's
|
|
251
|
+
* terrainShadow strength, steps and distance its own quality knobs. */
|
|
252
|
+
function terrainFieldDefaults() {
|
|
253
|
+
return {
|
|
254
|
+
u_terrainType: 2,
|
|
255
|
+
u_elevation: 180,
|
|
256
|
+
u_seaLevel: 0,
|
|
257
|
+
u_baseScale: 1 / 2600,
|
|
258
|
+
u_octaves: 8,
|
|
259
|
+
u_lacunarity: 2.06,
|
|
260
|
+
u_gain: 0.46,
|
|
261
|
+
u_ridge: 0.05,
|
|
262
|
+
u_warpStrength: 0.35,
|
|
263
|
+
u_warpScale: 0.6,
|
|
264
|
+
u_erosion: 0.45,
|
|
265
|
+
u_terraces: 0,
|
|
266
|
+
u_terraceSharp: 0.6,
|
|
267
|
+
u_bearingDir: new THREE.Vector2(0.978, 0.208),
|
|
268
|
+
u_duneFreq: (2 * Math.PI) / 340,
|
|
269
|
+
u_duneAsym: 0.62,
|
|
270
|
+
u_plateau: 0,
|
|
271
|
+
u_valleyDepth: 0,
|
|
272
|
+
u_valleyWidth: 0.25,
|
|
273
|
+
u_sunShadow: 1,
|
|
274
|
+
u_shadowSoftness: 12,
|
|
275
|
+
u_shadowDistance: 4000,
|
|
276
|
+
u_shadowSteps: 10,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
193
279
|
function emptyWaveTable() {
|
|
194
280
|
return Array.from({ length: MAX_WAVES }, () => new THREE.Vector4());
|
|
195
281
|
}
|
|
@@ -226,6 +312,11 @@ export const oceanMaterialDefaults = {
|
|
|
226
312
|
u_exposure: 1,
|
|
227
313
|
u_curvature: 1 / (2 * 6371000),
|
|
228
314
|
u_receiveShadows: 1,
|
|
315
|
+
// Shoreline (applyOceanShore). Read with or without terrain; the terrain
|
|
316
|
+
// field's own uniforms below only when OCEAN_TERRAIN is defined.
|
|
317
|
+
u_shoreDepth: 3,
|
|
318
|
+
u_shoreFoam: 1,
|
|
319
|
+
...terrainFieldDefaults(),
|
|
229
320
|
// Shared with the cloud and terrain materials, set by the same
|
|
230
321
|
// applySunUniforms() off the same useCloudSun state.
|
|
231
322
|
u_sunDir: new THREE.Vector3(0.35, 0.42, 0.84).normalize(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/triggers/hosts/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG3F,mDAAmD;AACnD,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,YAAY,EACrC,CAAC;AAE9D,0EAA0E;AAC1E,eAAO,MAAM,eAAe,GAAI,QAAQ,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,eAAe,EACY,CAAC;AAEjH,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/triggers/hosts/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG3F,mDAAmD;AACnD,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,YAAY,EACrC,CAAC;AAE9D,0EAA0E;AAC1E,eAAO,MAAM,eAAe,GAAI,QAAQ,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,eAAe,EACY,CAAC;AAEjH,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAWxF"}
|
|
@@ -14,6 +14,8 @@ export function runActionCommands(action, mode) {
|
|
|
14
14
|
runCommand({ ...c, command: mode }, { source });
|
|
15
15
|
else if (c.kind === 'action')
|
|
16
16
|
runCommand({ ...c, command: mode }, { source });
|
|
17
|
+
else if (c.kind === 'change')
|
|
18
|
+
runCommand({ ...c, command: mode }, { source });
|
|
17
19
|
else if (mode === 'apply')
|
|
18
20
|
runCommand(c, { source });
|
|
19
21
|
else if (c.command === 'play' || c.command === 'toggle')
|
|
@@ -16,7 +16,7 @@ ClipsRuntime.setCueRunner((cmd, mode, { effects, host, timelineId, getAction })
|
|
|
16
16
|
// fire: one-shot — an effect plays (apply), anything else runs its own command
|
|
17
17
|
const run = mode === 'fire'
|
|
18
18
|
? (cmd.kind === 'effect' ? { ...cmd, command: 'apply' } : cmd)
|
|
19
|
-
: cmd.kind === 'effect' || cmd.kind === 'effectClip' || cmd.kind === 'action' ? { ...cmd, command: mode } : cmd;
|
|
19
|
+
: cmd.kind === 'effect' || cmd.kind === 'effectClip' || cmd.kind === 'action' || cmd.kind === 'change' ? { ...cmd, command: mode } : cmd;
|
|
20
20
|
runCommand(run, { source, chain: [], effects, ...(catalog ? { catalog } : {}) });
|
|
21
21
|
return true;
|
|
22
22
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change.d.ts","sourceRoot":"","sources":["../../../src/triggers/kinds/change.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,aAAa,GAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,WAAqB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Triggerable: an inline change — an action's targets (element + settings patch) without
|
|
2
|
+
// the action. On lays the patches over the elements as a silent SceneActions layer
|
|
3
|
+
// (`change:<id>`): the elements re-render with them, exactly as with an action, but nothing
|
|
4
|
+
// lists it as an applied action. Off removes the layer. A timeline's Change cue.
|
|
5
|
+
//
|
|
6
|
+
// Collisions: when another action / change / the timeline's switch tracks already set the
|
|
7
|
+
// same settings on an element, it is logged as a clash — not resolved (the last one to
|
|
8
|
+
// change sits on top).
|
|
9
|
+
import { SceneActions } from '@3driseai/3drise-core';
|
|
10
|
+
import { defineTriggerable } from '../registry.js';
|
|
11
|
+
import { logTrigger } from '../log.js';
|
|
12
|
+
import { currentChain } from '../engine.js';
|
|
13
|
+
const ENV = new Set(['camera', 'sky', 'clouds', 'ocean', 'terrain']);
|
|
14
|
+
export const changeLayerId = (c) => `change:${c.id}`;
|
|
15
|
+
const ownerName = (o) => (o.startsWith('layer:change:') ? `change ${o.slice(13)}` : o === 'layer:timeline' ? 'a switch track' : `action ${o}`);
|
|
16
|
+
const patchesOf = (c) => {
|
|
17
|
+
const out = {};
|
|
18
|
+
for (const t of c.targets ?? [])
|
|
19
|
+
if (t?.state && t.patch && Object.keys(t.patch).length)
|
|
20
|
+
out[t.state] = t.patch;
|
|
21
|
+
return out;
|
|
22
|
+
};
|
|
23
|
+
defineTriggerable({
|
|
24
|
+
kind: 'change',
|
|
25
|
+
commands: ['apply', 'revert', 'toggle'],
|
|
26
|
+
timeline: 'state',
|
|
27
|
+
targets: (c) => (c.targets ?? []).map(t => t.state).filter(s => s && !ENV.has(s)),
|
|
28
|
+
subject: (c) => c.label || `change ${c.id}`,
|
|
29
|
+
claimKey: (c) => `change:${c.id}`,
|
|
30
|
+
isOn: (c) => SceneActions.hasLayer(changeLayerId(c)),
|
|
31
|
+
run: (c, ctx) => {
|
|
32
|
+
const id = changeLayerId(c);
|
|
33
|
+
const on = c.command === 'apply' || (c.command === 'toggle' && !SceneActions.hasLayer(id));
|
|
34
|
+
if (!on) {
|
|
35
|
+
SceneActions.setLayer(id, null);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const patches = patchesOf(c);
|
|
39
|
+
for (const [state, patch] of Object.entries(patches)) {
|
|
40
|
+
const others = SceneActions.overlaps(state, patch, `layer:${id}`);
|
|
41
|
+
if (others.length) {
|
|
42
|
+
logTrigger({
|
|
43
|
+
type: 'clash', kind: 'change', subject: c.label || id, source: ctx.source, chain: currentChain(),
|
|
44
|
+
detail: `sets the same settings on ${state} as ${others.map(ownerName).join(', ')} — the last one to change wins`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
SceneActions.setLayer(id, patches);
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/triggers/kinds/index.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,CAAC;AACnB,OAAO,UAAU,CAAC;AAClB,OAAO,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/triggers/kinds/index.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,CAAC;AACnB,OAAO,UAAU,CAAC;AAClB,OAAO,cAAc,CAAC;AACtB,OAAO,UAAU,CAAC"}
|
|
@@ -13,6 +13,10 @@ declare class CameraSingleton {
|
|
|
13
13
|
animateCameraPosition(position: Vector3Array): Promise<void>;
|
|
14
14
|
setCamera(camera: PerspectiveCamera): void;
|
|
15
15
|
getCamera(): PerspectiveCamera | null;
|
|
16
|
+
/** The live OrbitControls (registered by CameraController) — controllers drag it directly. */
|
|
17
|
+
private controls;
|
|
18
|
+
setControls(controls: any): void;
|
|
19
|
+
getControls(): any;
|
|
16
20
|
getPosition(): Vector3;
|
|
17
21
|
getRotation(): Euler;
|
|
18
22
|
isSynced(position: Vector3Array, orientation: Vector3Array | [number, number, number, number]): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CameraSingleton.d.ts","sourceRoot":"","sources":["../../src/utils/CameraSingleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAsB,OAAO,EAAE,KAAK,EAAc,MAAM,OAAO,CAAC;AAC1F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAExF,cAAM,eAAe;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;IACxB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAe;;IAEnC,MAAM,CAAC,WAAW,IAAI,eAAe;IAMrC,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB5D,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAM1C,SAAS,IAAI,iBAAiB,GAAG,IAAI;IACrC,WAAW,IAAI,OAAO;IACtB,WAAW,IAAI,KAAK;IACpB,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO;IAyBvG,iBAAiB,IAAI,OAAO;IAI5B,MAAM,IAAI,MAAM;IAChB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAI3C,OAAO,CAAC,eAAe;IAGvB,WAAW,IAAI,OAAO;IACtB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM;IAG5C,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAM7B,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG;QAC9C,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAClB;IAeT,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG;QAC5B,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,OAAO,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,EAAE,OAAO,CAAC;KACnB;IAqBT,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,OAAO,GAAE,MAAU,GAAG,OAAO;IA6CvH,YAAY,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,IAAI,GAAG,MAAM,IAAI;IAIhF,mBAAmB,CAAC,OAAO,GAAE,MAAc,GAAG,OAAO;CAiBxD;AACD,eAAO,MAAM,aAAa,EAAE,eAA+C,CAAC;AAC5E,eAAe,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"CameraSingleton.d.ts","sourceRoot":"","sources":["../../src/utils/CameraSingleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAsB,OAAO,EAAE,KAAK,EAAc,MAAM,OAAO,CAAC;AAC1F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAExF,cAAM,eAAe;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;IACxB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAe;;IAEnC,MAAM,CAAC,WAAW,IAAI,eAAe;IAMrC,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB5D,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAM1C,SAAS,IAAI,iBAAiB,GAAG,IAAI;IACrC,8FAA8F;IAC9F,OAAO,CAAC,QAAQ,CAAa;IAC7B,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IAChC,WAAW,IAAI,GAAG;IAClB,WAAW,IAAI,OAAO;IACtB,WAAW,IAAI,KAAK;IACpB,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO;IAyBvG,iBAAiB,IAAI,OAAO;IAI5B,MAAM,IAAI,MAAM;IAChB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAI3C,OAAO,CAAC,eAAe;IAGvB,WAAW,IAAI,OAAO;IACtB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM;IAG5C,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAM7B,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG;QAC9C,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAClB;IAeT,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG;QAC5B,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,OAAO,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,EAAE,OAAO,CAAC;KACnB;IAqBT,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,OAAO,GAAE,MAAU,GAAG,OAAO;IA6CvH,YAAY,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,IAAI,GAAG,MAAM,IAAI;IAIhF,mBAAmB,CAAC,OAAO,GAAE,MAAc,GAAG,OAAO;CAiBxD;AACD,eAAO,MAAM,aAAa,EAAE,eAA+C,CAAC;AAC5E,eAAe,aAAa,CAAC"}
|
|
@@ -43,6 +43,10 @@ class CameraSingleton {
|
|
|
43
43
|
this.notifyCallbacks();
|
|
44
44
|
}
|
|
45
45
|
getCamera() { return this.camera; }
|
|
46
|
+
/** The live OrbitControls (registered by CameraController) — controllers drag it directly. */
|
|
47
|
+
controls = null;
|
|
48
|
+
setControls(controls) { this.controls = controls; }
|
|
49
|
+
getControls() { return this.controls; }
|
|
46
50
|
getPosition() { return this.camera ? this.camera.position.clone() : new Vector3(); }
|
|
47
51
|
getRotation() { return this.camera ? this.camera.rotation.clone() : new Euler(); }
|
|
48
52
|
isSynced(position, orientation) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceTier.d.ts","sourceRoot":"","sources":["../../src/utils/deviceTier.ts"],"names":[],"mappings":"AAOA,wBAAgB,cAAc,IAAI,OAAO,CAOxC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coarse device tier, for render-time quality caps. A phone or tablet: a coarse
|
|
3
|
+
* primary pointer on a small screen. Read once — it does not change while a page
|
|
4
|
+
* is open, and render code must not branch on something that flickers.
|
|
5
|
+
*/
|
|
6
|
+
let cached = null;
|
|
7
|
+
export function isMobileDevice() {
|
|
8
|
+
if (cached !== null)
|
|
9
|
+
return cached;
|
|
10
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function')
|
|
11
|
+
return (cached = false);
|
|
12
|
+
const coarse = window.matchMedia('(pointer: coarse)').matches;
|
|
13
|
+
const shortSide = Math.min(window.screen?.width ?? 0, window.screen?.height ?? 0);
|
|
14
|
+
cached = coarse && shortSide > 0 && shortSide < 1000;
|
|
15
|
+
return cached;
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Draw order of the camera-centred environment surfaces.
|
|
3
|
+
*
|
|
4
|
+
* three sorts opaque objects by renderOrder, then by MATERIAL ID, then by depth.
|
|
5
|
+
* The world ocean and the terrain clipmaps are both centred on the camera, so the
|
|
6
|
+
* depth tie never helps, and with renderOrder left at 0 the material id decides:
|
|
7
|
+
* whichever surface was created last draws last. That made the frame cost depend
|
|
8
|
+
* on mount order — measured 13 ms vs 22-27 ms GPU in the same view — because when
|
|
9
|
+
* the terrain drew first, every terrain pixel under the sea ran the full terrain
|
|
10
|
+
* shader (textures, 8 noise octaves) and was then painted over by water.
|
|
11
|
+
*
|
|
12
|
+
* Fixed order instead, all below the scene's objects (0):
|
|
13
|
+
* 1. water, inner rings first (cheap shader; hides the seabed from the depth test)
|
|
14
|
+
* 2. terrain, inner rings first (near ground hides far ground: front to back)
|
|
15
|
+
* Drawing near-to-far is what lets the early depth test throw hidden pixels away
|
|
16
|
+
* before their shader runs. Wasted water pixels behind land are cheap; wasted
|
|
17
|
+
* terrain pixels under water were most of the frame.
|
|
18
|
+
*/
|
|
19
|
+
export declare const OCEAN_DRAW_ORDER = -40;
|
|
20
|
+
export declare const TERRAIN_DRAW_ORDER = -20;
|
|
21
|
+
/** Inner ring (level 0) first, then outward. */
|
|
22
|
+
export declare const ringDrawOrder: (base: number, level: number) => number;
|
|
23
|
+
//# sourceMappingURL=environmentDrawOrder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environmentDrawOrder.d.ts","sourceRoot":"","sources":["../../src/utils/environmentDrawOrder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,gDAAgD;AAChD,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,WAAiB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Draw order of the camera-centred environment surfaces.
|
|
3
|
+
*
|
|
4
|
+
* three sorts opaque objects by renderOrder, then by MATERIAL ID, then by depth.
|
|
5
|
+
* The world ocean and the terrain clipmaps are both centred on the camera, so the
|
|
6
|
+
* depth tie never helps, and with renderOrder left at 0 the material id decides:
|
|
7
|
+
* whichever surface was created last draws last. That made the frame cost depend
|
|
8
|
+
* on mount order — measured 13 ms vs 22-27 ms GPU in the same view — because when
|
|
9
|
+
* the terrain drew first, every terrain pixel under the sea ran the full terrain
|
|
10
|
+
* shader (textures, 8 noise octaves) and was then painted over by water.
|
|
11
|
+
*
|
|
12
|
+
* Fixed order instead, all below the scene's objects (0):
|
|
13
|
+
* 1. water, inner rings first (cheap shader; hides the seabed from the depth test)
|
|
14
|
+
* 2. terrain, inner rings first (near ground hides far ground: front to back)
|
|
15
|
+
* Drawing near-to-far is what lets the early depth test throw hidden pixels away
|
|
16
|
+
* before their shader runs. Wasted water pixels behind land are cheap; wasted
|
|
17
|
+
* terrain pixels under water were most of the frame.
|
|
18
|
+
*/
|
|
19
|
+
export const OCEAN_DRAW_ORDER = -40;
|
|
20
|
+
export const TERRAIN_DRAW_ORDER = -20;
|
|
21
|
+
/** Inner ring (level 0) first, then outward. */
|
|
22
|
+
export const ringDrawOrder = (base, level) => base + level;
|
|
@@ -2,6 +2,13 @@ import * as THREE from 'three';
|
|
|
2
2
|
import type { TerrainConfig, TerrainQualityConfig } from '@3driseai/3drise-core';
|
|
3
3
|
import type { TerrainTextureState } from '../hooks/useTerrainTextures';
|
|
4
4
|
import type { CloudSunState } from '../hooks/useCloudSun';
|
|
5
|
+
/**
|
|
6
|
+
* The height field's own uniforms (terrainFormUniforms): landform, scale, octaves,
|
|
7
|
+
* warp, erosion, shaping. Shared by the terrain material and by every material that
|
|
8
|
+
* includes `terrainFieldOnly` to read the ground — the ocean, for its shoreline —
|
|
9
|
+
* so the two can never disagree about where the ground is.
|
|
10
|
+
*/
|
|
11
|
+
export declare function applyTerrainFieldUniforms(material: THREE.ShaderMaterial, config: TerrainConfig): void;
|
|
5
12
|
export declare function applyTerrainUniforms(material: THREE.ShaderMaterial, config: TerrainConfig, quality: TerrainQualityConfig): void;
|
|
6
13
|
export default applyTerrainUniforms;
|
|
7
14
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrainUniforms.d.ts","sourceRoot":"","sources":["../../src/utils/terrainUniforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAe,MAAM,uBAAuB,CAAC;AAE9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAoD1D,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAC9B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,oBAAoB,GAC9B,IAAI,
|
|
1
|
+
{"version":3,"file":"terrainUniforms.d.ts","sourceRoot":"","sources":["../../src/utils/terrainUniforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAe,MAAM,uBAAuB,CAAC;AAE9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAoD1D;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAwBrG;AAED,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAC9B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,oBAAoB,GAC9B,IAAI,CAqCN;AAED,eAAe,oBAAoB,CAAC;AAUpC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAC9B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,mBAAmB,GACzB,IAAI,CAyDN;AAiCD,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CA4BlG;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAwC5F"}
|
|
@@ -45,9 +45,15 @@ function setColor(uniform, hex) {
|
|
|
45
45
|
return;
|
|
46
46
|
uniform.value.setStyle(hex, THREE.SRGBColorSpace);
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The height field's own uniforms (terrainFormUniforms): landform, scale, octaves,
|
|
50
|
+
* warp, erosion, shaping. Shared by the terrain material and by every material that
|
|
51
|
+
* includes `terrainFieldOnly` to read the ground — the ocean, for its shoreline —
|
|
52
|
+
* so the two can never disagree about where the ground is.
|
|
53
|
+
*/
|
|
54
|
+
export function applyTerrainFieldUniforms(material, config) {
|
|
49
55
|
const u = material.uniforms;
|
|
50
|
-
if (!u)
|
|
56
|
+
if (!u || !u.u_terrainType)
|
|
51
57
|
return;
|
|
52
58
|
u.u_terrainType.value = TYPE_INDEX[config.terrainType] ?? 2;
|
|
53
59
|
u.u_elevation.value = Math.max(config.elevation, 0.01);
|
|
@@ -68,6 +74,13 @@ export function applyTerrainUniforms(material, config, quality) {
|
|
|
68
74
|
u.u_plateau.value = config.plateau;
|
|
69
75
|
u.u_valleyDepth.value = config.valleyDepth;
|
|
70
76
|
u.u_valleyWidth.value = config.valleyWidth;
|
|
77
|
+
u.u_shadowSoftness.value = config.shadowSoftness;
|
|
78
|
+
}
|
|
79
|
+
export function applyTerrainUniforms(material, config, quality) {
|
|
80
|
+
const u = material.uniforms;
|
|
81
|
+
if (!u)
|
|
82
|
+
return;
|
|
83
|
+
applyTerrainFieldUniforms(material, config);
|
|
71
84
|
setColor(u.u_lowColor, config.lowColor);
|
|
72
85
|
setColor(u.u_midColor, config.midColor);
|
|
73
86
|
setColor(u.u_rockColor, config.rockColor);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@3driseai/3drise-viewer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -39,6 +39,6 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@3driseai/3drise-common": "^1.0.1",
|
|
42
|
-
"@3driseai/3drise-core": "^1.0.
|
|
42
|
+
"@3driseai/3drise-core": "^1.0.24"
|
|
43
43
|
}
|
|
44
44
|
}
|