@3driseai/3drise-viewer 0.1.29 → 0.1.31
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 +13 -0
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +115 -4
- 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 +5 -1
- package/dist/animationsV2/sequenceUtils.d.ts +5 -0
- package/dist/animationsV2/sequenceUtils.d.ts.map +1 -1
- package/dist/animationsV2/sequenceUtils.js +14 -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/animationsV2/types.d.ts +6 -0
- package/dist/animationsV2/types.d.ts.map +1 -1
- 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/EffectsGenerator.d.ts.map +1 -1
- package/dist/components/EffectsGenerator.js +43 -38
- package/dist/components/GeometryShape.d.ts.map +1 -1
- package/dist/components/GeometryShape.js +22 -2
- package/dist/components/MoonDisc.d.ts.map +1 -1
- package/dist/components/MoonDisc.js +2 -1
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +6 -17
- 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 +46 -24
- package/dist/components/PickVolume.d.ts +17 -0
- package/dist/components/PickVolume.d.ts.map +1 -0
- package/dist/components/PickVolume.js +20 -0
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +5 -2
- package/dist/components/SkyStars.d.ts.map +1 -1
- package/dist/components/SkyStars.js +83 -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/TextGenerator.d.ts.map +1 -1
- package/dist/components/TextGenerator.js +3 -2
- package/dist/components/index.d.ts +2 -8
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -4
- package/dist/components/lightBulb/LightBulb.d.ts.map +1 -1
- package/dist/components/lightBulb/LightBulb.js +7 -2
- package/dist/components/particles/BioluminescentWakeParticles.d.ts +5 -0
- package/dist/components/particles/BioluminescentWakeParticles.d.ts.map +1 -1
- package/dist/components/particles/BioluminescentWakeParticles.js +2 -1
- package/dist/components/particles/BrownianDustParticles.d.ts +5 -0
- package/dist/components/particles/BrownianDustParticles.d.ts.map +1 -1
- package/dist/components/particles/BrownianDustParticles.js +2 -0
- package/dist/components/particles/ChladniSandParticles.d.ts +5 -0
- package/dist/components/particles/ChladniSandParticles.d.ts.map +1 -1
- package/dist/components/particles/ChladniSandParticles.js +2 -1
- package/dist/components/particles/ElectronOrbitalsParticles.d.ts +5 -0
- package/dist/components/particles/ElectronOrbitalsParticles.d.ts.map +1 -1
- package/dist/components/particles/ElectronOrbitalsParticles.js +2 -1
- package/dist/components/particles/FaradayPowderParticles.d.ts +5 -0
- package/dist/components/particles/FaradayPowderParticles.d.ts.map +1 -1
- package/dist/components/particles/FaradayPowderParticles.js +2 -1
- 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/GrinderSparksParticles.d.ts +5 -0
- package/dist/components/particles/GrinderSparksParticles.d.ts.map +1 -1
- package/dist/components/particles/GrinderSparksParticles.js +2 -1
- package/dist/components/particles/MagneticBottleParticles.d.ts +5 -0
- package/dist/components/particles/MagneticBottleParticles.d.ts.map +1 -1
- package/dist/components/particles/MagneticBottleParticles.js +2 -1
- package/dist/components/particles/NeonRainParticles.d.ts +5 -0
- package/dist/components/particles/NeonRainParticles.d.ts.map +1 -1
- package/dist/components/particles/NeonRainParticles.js +2 -1
- package/dist/components/particles/ShapeBurstParticles.d.ts +5 -0
- package/dist/components/particles/ShapeBurstParticles.d.ts.map +1 -1
- package/dist/components/particles/ShapeBurstParticles.js +2 -1
- package/dist/components/particles/ShapeFlowParticles.d.ts +5 -0
- package/dist/components/particles/ShapeFlowParticles.d.ts.map +1 -1
- package/dist/components/particles/ShapeFlowParticles.js +2 -1
- package/dist/components/particles/TidalStreamParticles.d.ts +5 -0
- package/dist/components/particles/TidalStreamParticles.d.ts.map +1 -1
- package/dist/components/particles/TidalStreamParticles.js +2 -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/text/PlainText.d.ts +15 -0
- package/dist/components/text/PlainText.d.ts.map +1 -0
- package/dist/components/text/PlainText.js +4 -0
- package/dist/components/text/TextObjectView.d.ts +3 -1
- package/dist/components/text/TextObjectView.d.ts.map +1 -1
- package/dist/components/text/TextObjectView.js +9 -3
- package/dist/components/text/engine/looks/index.d.ts.map +1 -1
- package/dist/components/text/engine/looks/index.js +2 -1
- package/dist/components/text/engine/looks/plain.d.ts +146 -0
- package/dist/components/text/engine/looks/plain.d.ts.map +1 -0
- package/dist/components/text/engine/looks/plain.js +104 -0
- package/dist/components/text/fonts/bebas-neue.outline.d.ts +3 -0
- package/dist/components/text/fonts/bebas-neue.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/bebas-neue.outline.js +4 -0
- package/dist/components/text/fonts/bebas-neue.strokes.d.ts +3 -0
- package/dist/components/text/fonts/bebas-neue.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/bebas-neue.strokes.js +4 -0
- package/dist/components/text/fonts/index.d.ts +1 -1
- package/dist/components/text/fonts/index.d.ts.map +1 -1
- package/dist/components/text/fonts/index.js +15 -1
- package/dist/components/text/fonts/inter.outline.d.ts +3 -0
- package/dist/components/text/fonts/inter.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/inter.outline.js +4 -0
- package/dist/components/text/fonts/inter.strokes.d.ts +3 -0
- package/dist/components/text/fonts/inter.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/inter.strokes.js +4 -0
- package/dist/components/text/fonts/lora.outline.d.ts +3 -0
- package/dist/components/text/fonts/lora.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/lora.outline.js +4 -0
- package/dist/components/text/fonts/lora.strokes.d.ts +3 -0
- package/dist/components/text/fonts/lora.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/lora.strokes.js +4 -0
- package/dist/components/text/fonts/montserrat.outline.d.ts +3 -0
- package/dist/components/text/fonts/montserrat.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/montserrat.outline.js +4 -0
- package/dist/components/text/fonts/montserrat.strokes.d.ts +3 -0
- package/dist/components/text/fonts/montserrat.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/montserrat.strokes.js +4 -0
- package/dist/components/text/fonts/oswald.outline.d.ts +3 -0
- package/dist/components/text/fonts/oswald.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/oswald.outline.js +4 -0
- package/dist/components/text/fonts/oswald.strokes.d.ts +3 -0
- package/dist/components/text/fonts/oswald.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/oswald.strokes.js +4 -0
- package/dist/components/text/fonts/playfair-display.outline.d.ts +3 -0
- package/dist/components/text/fonts/playfair-display.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/playfair-display.outline.js +4 -0
- package/dist/components/text/fonts/playfair-display.strokes.d.ts +3 -0
- package/dist/components/text/fonts/playfair-display.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/playfair-display.strokes.js +4 -0
- package/dist/components/text/fonts/roboto.outline.d.ts +3 -0
- package/dist/components/text/fonts/roboto.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/roboto.outline.js +4 -0
- package/dist/components/text/fonts/roboto.strokes.d.ts +3 -0
- package/dist/components/text/fonts/roboto.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/roboto.strokes.js +4 -0
- package/dist/components/text/index.d.ts +2 -0
- package/dist/components/text/index.d.ts.map +1 -1
- package/dist/components/text/index.js +1 -0
- package/dist/components/text/useTextObject.d.ts +1 -0
- package/dist/components/text/useTextObject.d.ts.map +1 -1
- package/dist/components/text/useTextObject.js +23 -11
- 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/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -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 +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/operations/catalogue/flock.d.ts.map +1 -1
- package/dist/operations/catalogue/flock.js +44 -9
- package/dist/operations/catalogue/inkBloom.d.ts.map +1 -1
- package/dist/operations/catalogue/inkBloom.js +46 -9
- package/dist/operations/catalogue/liquidMetal.d.ts.map +1 -1
- package/dist/operations/catalogue/liquidMetal.js +41 -12
- package/dist/operations/catalogue/particleSwarm.d.ts.map +1 -1
- package/dist/operations/catalogue/particleSwarm.js +29 -9
- package/dist/operations/catalogue/petalPeel.d.ts.map +1 -1
- package/dist/operations/catalogue/petalPeel.js +33 -9
- package/dist/operations/catalogue/portal.d.ts.map +1 -1
- package/dist/operations/catalogue/portal.js +33 -11
- package/dist/operations/catalogue/sandErosion.d.ts.map +1 -1
- package/dist/operations/catalogue/sandErosion.js +36 -14
- package/dist/operations/catalogue/teleport.d.ts.map +1 -1
- package/dist/operations/catalogue/teleport.js +43 -12
- package/dist/operations/catalogue/unweave.d.ts.map +1 -1
- package/dist/operations/catalogue/unweave.js +34 -15
- package/dist/operations/catalogue/voxelize.d.ts.map +1 -1
- package/dist/operations/catalogue/voxelize.js +37 -10
- 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/engine.d.ts +1 -1
- package/dist/triggers/engine.d.ts.map +1 -1
- package/dist/triggers/engine.js +3 -0
- package/dist/triggers/hosts/actions.d.ts.map +1 -1
- package/dist/triggers/hosts/actions.js +3 -1
- package/dist/triggers/hosts/interactions.d.ts.map +1 -1
- package/dist/triggers/hosts/interactions.js +1 -1
- 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/pickProxy.d.ts +11 -0
- package/dist/utils/pickProxy.d.ts.map +1 -0
- package/dist/utils/pickProxy.js +36 -0
- package/dist/utils/shapes.d.ts +4 -0
- package/dist/utils/shapes.d.ts.map +1 -1
- package/dist/utils/shapes.js +4 -1
- 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/dist/utils/textShape.d.ts +24 -0
- package/dist/utils/textShape.d.ts.map +1 -0
- package/dist/utils/textShape.js +102 -0
- package/package.json +2 -2
|
@@ -26,8 +26,14 @@
|
|
|
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 declare const terrainFormUniforms = "\nuniform int u_terrainType;\n\nuniform float u_elevation;\nuniform float u_seaLevel;\nuniform float u_baseScale; // 1 / featureSize\nuniform int u_octaves;\nuniform float u_lacunarity;\nuniform float u_gain;\nuniform float u_ridge;\nuniform float u_warpStrength;\nuniform float u_warpScale;\nuniform float u_erosion;\nuniform float u_terraces;\nuniform float u_terraceSharp;\nuniform vec2 u_bearingDir;\nuniform float u_duneFreq; // 2pi / duneWavelength\nuniform float u_duneAsym;\nuniform float u_plateau;\nuniform float u_valleyDepth;\nuniform float u_valleyWidth;\n\n// The analytic sun-shadow march (terrainShadow) - shared with the ocean, which\n// marches the same field to put headland shadows on the water.\nuniform float u_sunShadow, u_shadowSoftness;\nuniform float u_shadowDistance;\nuniform int u_shadowSteps;\n\n// A land object: a bounded patch of this field, placed by its object's transform.\n// Its \"terrain space\" is metres from the object's origin, unrotated, plus a seed\n// offset; height is above the object's base. See TerrainMaterial's patch vertex.\n#ifdef TERRAIN_PATCH\nuniform vec2 u_patchSize; // footprint in metres (object scale x / z)\nuniform vec2 u_patchOffset; // terrain-space centre: the seed's offset into the field\nuniform float u_edgeWidth; // metres over which the land eases down to its base\nuniform vec3 u_camTerrain; // the camera, in terrain space\nuniform float u_scaleY; // object scale y: terrain metres = local y x this\nuniform float u_patchCell; // metres per grid cell\n#define TERRAIN_CAM u_camTerrain\n#else\n#define TERRAIN_CAM cameraPosition\n#endif\n";
|
|
35
|
+
/** The terrain surface's own uniforms: shading, lighting, textures. */
|
|
36
|
+
export declare const terrainSurfaceUniforms = "\nuniform float u_cellSize;\nuniform float u_curvature;\n\n// surface\nuniform vec3 u_lowColor, u_midColor, u_rockColor, u_peakColor;\nuniform float u_slopeRockStart, u_slopeRockEnd;\nuniform float u_peakLevel, u_peakBlend, u_peakSlopeFalloff;\nuniform float u_macroVariation, u_macroScale;\nuniform float u_detailStrength, u_detailScale, u_detailFade;\nuniform float u_roughness, u_specular;\n\n// lighting. u_skyAmbient and u_groundAmbient come from useCloudSun through\n// applySunUniforms - the same objects that light the clouds. They are constant\n// across the frame, so computing them on the CPU rather than calling skyRadiance\n// per pixel removes an acos, a pow and three exps from every fragment.\nuniform vec3 u_skyAmbient;\nuniform vec3 u_groundAmbient;\nuniform float u_ambient, u_bounce;\nuniform float u_fogDensity, u_exposure;\n\n// Ground textures. The far colour per layer is always set: the flat colour for an\n// untextured layer, the texture's own mean x tint for a textured one, so the\n// near-to-far fade has no colour jump.\nuniform vec3 u_tFar[4];\n#ifdef TERRAIN_TEXTURED\nuniform sampler2DArray u_tColor; // albedo, sRGB\nuniform sampler2DArray u_tNormal; // rgb tangent normal (GL), a surface height\nuniform sampler2DArray u_tOrm; // r ambient occlusion, g roughness\nuniform vec4 u_tLayer[4]; // 1/tileSize, normalStrength, textured 0|1, -\nuniform vec3 u_tTint[4]; // layer colour / texture mean: the texture averages to the layer colour\nuniform vec4 u_tMeanC[4]; // per-array layer means, for the stochastic blend\nuniform vec4 u_tMeanN[4];\nuniform vec4 u_tMeanO[4];\nuniform float u_tDistance;\nuniform float u_tHeightBlend;\n#endif\n\n";
|
|
31
37
|
/**
|
|
32
38
|
* Gradient noise with an analytic derivative.
|
|
33
39
|
*
|
|
@@ -70,7 +76,8 @@ export declare const terrainHeight = "\n#define TERRAIN_MOUNTAINS 0\n#define TER
|
|
|
70
76
|
* The terminator itself stays per-pixel: `terrainLight` takes N·L from the
|
|
71
77
|
* fragment's own normal, so only the CAST shadow is interpolated.
|
|
72
78
|
*/
|
|
73
|
-
export declare const
|
|
79
|
+
export declare const terrainShadow = "\n/** 1 lit, 0 shadowed, soft in between. */\nfloat terrainSunShadow(vec3 p, vec3 n, float lodCell, int steps){\n if (steps < 1 || u_sunShadow <= 0.0) return 1.0;\n // Below the horizon there is nothing to shadow; the march would also walk\n // downhill forever.\n if (u_sunDir.y <= 0.015) return 1.0;\n // A surface facing away from the sun is shadowed by definition, and marching\n // from it only finds the ground it is already part of.\n if (dot(n, u_sunDir) <= 0.0) return 0.0;\n\n // Lift off the surface before starting, or every sample on a steep face - a\n // terrace riser above all - reads its own ground as an occluder and the whole\n // wall goes black in a grid of triangles. Start ON the offset surface and\n // compare raw heights; subtracting the bias from the height difference instead\n // makes the first sample fail on any slope tilted a few degrees from the sun.\n float bias = max(lodCell, u_elevation * 0.003);\n vec3 origin = p + n * bias;\n\n float shadowLod = (1.0 / max(u_baseScale, 1e-9)) * 0.008;\n\n float res = 1.0;\n float t = bias * 3.0;\n float maxT = (u_elevation * 2.5) / max(u_sunDir.y, 0.05);\n\n for (int i = 0; i < 48; i++){\n if (i >= steps || t > maxT) break;\n vec3 sp = origin + u_sunDir * t;\n // The occluder is sampled at the SHADING lod, coarsening with distance -\n // never at a fixed coarse lod. Testing a fine surface point against a coarse\n // height field puts the whole valley floor in shadow, because the coarse\n // field sits above the fine one wherever the fine one has been cut down.\n // Sampled MUCH coarser than the surface being shaded. A shadow does not need\n // nine octaves: what casts a visible shadow is the landform, and marching the\n // fine field costs the same nine octaves per step for detail that is below a\n // pixel by the time it lands. Floored against the landform's own size, so the\n // march runs about five octaves instead of nine wherever it starts.\n float h = terrainOccluderAt(sp.xz, max(max(lodCell * 2.0, t * 0.06), shadowLod));\n float diff = sp.y - h;\n res = min(res, u_shadowSoftness * diff / t);\n if (res <= 0.0) return 0.0;\n // Geometric growth: near the surface the occluder is metres away, at the end\n // of the march it is kilometres, and a linear step wastes every sample at one\n // end or the other. 1.7 rather than 1.42 so twelve steps actually reach maxT -\n // at 1.42 the march ran out around 700 m and long shadows at low sun simply\n // did not exist, which is a quality bug that happened to look like a cheap one.\n t = t * 1.7 + bias;\n }\n return saturate(res);\n}\n\n/**\n * The shadow, faded out with distance and given a step budget that falls with it.\n *\n * The march is the most expensive thing left in the renderer, and past a few\n * kilometres it is buying nothing: aerial perspective has already washed most of\n * the contrast out of the ground, and a ridge shadow out there is a couple of\n * pixels wide. Skipping it entirely beyond u_shadowDistance drops the outer\n * clipmap rings - which are two thirds of the vertices - out of the march\n * completely, and the rings in between run four steps instead of fourteen.\n *\n * Faded rather than cut, or the cut-off would draw a visible circle on the ground.\n */\nfloat terrainShadowAt(vec3 p, vec3 n, float lodCell, float dist){\n float fade = 1.0 - saturate(dist / max(u_shadowDistance, 1.0));\n if (fade <= 0.002) return 1.0;\n int steps = int(mix(4.0, float(u_shadowSteps), fade));\n return mix(1.0, terrainSunShadow(p, n, lodCell, steps), fade);\n}\n\n";
|
|
80
|
+
export declare const terrainShading = "\n/**\n * Albedo.\n *\n * Rock is splatted by SLOPE, everything else by height. That ordering is the\n * whole trick: it means a cliff is bare rock whether it is in a valley or on a\n * summit, which is how real ground works and why height-only splatting always\n * reads as a painted contour map.\n */\n/**\n * Splat weights for the four layers, in layer order: low, mid, rock, peak.\n * Exactly the old colour mixes written as weights \u2014 low/mid by height, the peak\n * held back on steep ground (snow does not sit on a vertical face), rock by slope\n * and applied last, which is why a cliff reads as a cliff at any altitude.\n */\nvec4 terrainLayerWeights(float h01, float slope){\n float m = smoothstep(0.05, 0.55, h01);\n float p = saturate(smoothstep(u_peakLevel, u_peakLevel + u_peakBlend, h01 - slope * u_peakSlopeFalloff * 0.6));\n float r = smoothstep(u_slopeRockStart, u_slopeRockEnd, slope);\n return vec4((1.0 - m) * (1.0 - p) * (1.0 - r), m * (1.0 - p) * (1.0 - r), r, p * (1.0 - r));\n}\n\n/** Large-scale variation. Without it a splat layer is one flat colour across\n * kilometres, and the eye reads flat colour as untextured rather than as ground. */\nfloat terrainMacro(vec3 wp){\n float macro = tNoise(wp.xz * u_macroScale) * 0.5 + 0.5;\n return 1.0 + u_macroVariation * (macro - 0.5) * 2.0;\n}\n\n/** The far-field albedo: each layer's far colour by its weight. */\nvec3 terrainAlbedo(vec3 wp, vec4 w){\n vec3 col = u_tFar[0] * w.x + u_tFar[1] * w.y + u_tFar[2] * w.z + u_tFar[3] * w.w;\n return col * terrainMacro(wp);\n}\n\n/** High-frequency bump, well below the mesh resolution, faded out with distance\n * so it never becomes a field of crawling pixels on the horizon. One evaluation:\n * the noise carries its own derivative, so the three taps a finite difference\n * would need are not. */\nvec3 terrainDetailNormal(vec3 n, vec3 wp, float dist){\n float fade = 1.0 - saturate(dist * u_detailFade);\n float amt = u_detailStrength * fade * fade;\n if (amt <= 0.001) return n;\n vec3 d = tNoised(wp.xz * u_detailScale);\n return normalize(n + vec3(-d.y, 0.0, -d.z) * amt * 0.9);\n}\n\n/**\n * Direct sun, sky fill and ground bounce.\n *\n * Sun irradiance is in the units skyRadiance returns, calibrated against it rather\n * than guessed: a 0.3-albedo surface in full sun lands a little below the sky at\n * the horizon, which is the relationship the eye reads as daylight. Set it to the\n * clouds' SUN_RADIANCE and every ground surface clips to white.\n */\nconst float TERRAIN_SUN = 2.2;\n\nvec3 terrainLight(vec3 albedo, vec3 n, vec3 viewDir, float shadow, float sceneShadow, float roughness, float ao){\n float ndl = max(dot(n, u_sunDir), 0.0);\n // Wrap the terminator slightly: bare ground is not a Lambertian sphere, and a\n // hard terminator across a whole hillside reads as CG.\n float wrap = max((dot(n, u_sunDir) + 0.2) / 1.2, 0.0);\n float diff = mix(ndl, wrap, 0.4);\n\n vec3 sun = u_sunColor * u_sunIntensity * TERRAIN_SUN * diff * shadow * sceneShadow;\n\n // Sky fill from the same atmosphere the sky is drawn with, so it darkens and\n // warms with the sun instead of freezing at a constant blue - but supplied as a\n // uniform rather than evaluated here, since it is the same for every pixel.\n // Whitened a little: a single-scattering zenith colour is very saturated, and\n // at full saturation every shadowed slope - snow above all - comes out cyan.\n vec3 fill = mix(u_skyAmbient, vec3(dot(u_skyAmbient, vec3(0.3333))), 0.4);\n vec3 ambient = fill * (0.5 + 0.5 * n.y) * u_ambient * 1.05;\n\n // Ground bounce, tinted by whatever the ground is. Keeps overhangs and shaded\n // faces off pure black without flattening them the way raising ambient does.\n vec3 bounce = u_tFar[0] * u_groundAmbient * (0.5 - 0.5 * n.y) * u_bounce * 1.3;\n\n // Occlusion is a property of the small-scale surface, so it darkens the light\n // that arrives from everywhere \u2014 sky fill and bounce \u2014 and leaves the sun alone.\n vec3 col = albedo * (sun + (ambient + bounce) * ao);\n\n // A single specular lobe. Rock barely needs it; wet sand and snow at low sun\n // are almost entirely this.\n if (u_specular > 0.0){\n vec3 hv = normalize(u_sunDir - viewDir);\n float a = max(roughness * roughness, 0.002);\n float nh = max(dot(n, hv), 0.0);\n float dd = nh * nh * (a - 1.0) + 1.0;\n float d = a / max(3.14159265 * dd * dd, 1e-4);\n col += u_sunColor * u_sunIntensity * TERRAIN_SUN * d * u_specular * shadow * sceneShadow * ndl;\n }\n\n return col;\n}\n\n/**\n * Aerial perspective.\n *\n * The single most important line in this shader for the horizon. Ground fades\n * into the exact sky colour it is seen through, at a rate that thins with\n * altitude because the atmosphere does \u2014 so a distant ridge sits behind the haze\n * and a peak above it stands clear of it, which is what tells you the scene is\n * kilometres across rather than metres.\n *\n * The one remaining per-pixel skyRadiance call, and it has to be: the colour is\n * the sky in the view direction, which is different for every fragment.\n */\nvec3 terrainAerial(vec3 col, vec3 rd, float dist, float height){\n float scaleHeight = exp(-max(height - u_seaLevel, 0.0) / 1400.0);\n float f = 1.0 - exp(-dist * u_fogDensity * scaleHeight);\n if (f < 0.002) return col;\n return mix(col, skyRadiance(rd), saturate(f));\n}\n";
|
|
74
81
|
/**
|
|
75
82
|
* The textured near field. Needs `surfaceSampling` (surfaceCore.glsl) before it.
|
|
76
83
|
*
|
|
@@ -86,6 +93,14 @@ export declare const terrainShading = "\n/** 1 lit, 0 shadowed, soft in between.
|
|
|
86
93
|
export declare const terrainTextured = "\n#ifdef TERRAIN_TEXTURED\nstruct TerrainGrads { vec2 topX; vec2 topY; vec2 sideXX; vec2 sideXY; vec2 sideZX; vec2 sideZY; };\n\n// The large-scale sample is the same texture, T_MACRO times bigger.\n#define T_MACRO 8.0\n\n/**\n * One layer's three arrays at one projection, at two scales.\n *\n * A ground scan is millimetres per texel: a gravel tile shows its pebbles for a\n * few metres and is a flat average colour from fifty. So past the point where a\n * pixel covers a fifth of a tile, the same texture is sampled again T_MACRO times\n * larger, and its pebbles become patches, its cracks become streaks \u2014 the set's\n * character survives out to hundreds of metres instead of dissolving into a flat\n * colour, and picking a different set is visible from where people actually look\n * at terrain. The switch is by pixel footprint, so it is the same at any tile\n * size and any camera height. Each scale is skipped when its weight is zero.\n */\nvoid terrainTap(int L, vec2 uv, vec2 dx, vec2 dy, out vec4 c, out vec4 nh, out vec4 o){\n float layer = float(L);\n float fp = max(length(dx), length(dy));\n float m = smoothstep(0.04, 0.25, fp);\n vec4 cd = vec4(0.0);\n vec4 nd = vec4(0.0);\n vec4 od = vec4(0.0);\n vec4 cm = vec4(0.0);\n vec4 nm = vec4(0.0);\n vec4 om = vec4(0.0);\n if (m < 0.999){\n cd = sfSample(u_tColor, uv, dx, dy, layer, u_tMeanC[L]);\n nd = sfSample(u_tNormal, uv, dx, dy, layer, u_tMeanN[L]);\n od = sfSample(u_tOrm, uv, dx, dy, layer, u_tMeanO[L]);\n }\n if (m > 0.001){\n vec2 mu = uv / T_MACRO;\n vec2 mdx = dx / T_MACRO;\n vec2 mdy = dy / T_MACRO;\n cm = sfSample(u_tColor, mu, mdx, mdy, layer, u_tMeanC[L]);\n nm = sfSample(u_tNormal, mu, mdx, mdy, layer, u_tMeanN[L]);\n om = sfSample(u_tOrm, mu, mdx, mdy, layer, u_tMeanO[L]);\n // No height blending at the large scale. A height map blown up 8x has\n // tens-of-metres blobs, and blending layers along those contours paints\n // the ground in camouflage. Mid height = an ordinary cross-fade.\n nm.a = 0.5;\n }\n c = mix(cd, cm, m);\n nh = mix(nd, nm, m);\n o = mix(od, om, m);\n}\n\n/** One layer: albedo (tinted), an unnormalised world normal, surface height,\n * roughness and occlusion. An untextured layer returns its flat colour. */\nvoid terrainLayerSample(int L, vec3 wp, vec3 n, TerrainGrads g,\n out vec3 col, out vec3 wn, out float h, out float rough, out float ao){\n col = u_tFar[L];\n wn = n;\n h = 0.5;\n rough = u_roughness;\n ao = 1.0;\n if (u_tLayer[L].z > 0.5){\n float inv = u_tLayer[L].x;\n float ns = u_tLayer[L].y;\n vec4 c = vec4(0.0);\n vec4 nh = vec4(0.0);\n vec4 o = vec4(0.0);\n vec3 acc = vec3(0.0);\n if (L == 2){\n // Biplanar: the two strongest axes. The third adds a fraction of a percent\n // anywhere that is not an exact corner and costs a third of the fetches.\n vec3 an = abs(n);\n an = an * an * an;\n an /= max(an.x + an.y + an.z, 1e-4);\n float lo = min(an.x, min(an.y, an.z));\n vec3 bw = max(an - lo, 0.0);\n bw /= max(bw.x + bw.y + bw.z, 1e-4);\n vec4 c1, n1, o1;\n if (bw.y > 0.002){\n terrainTap(L, wp.xz * inv, g.topX * inv, g.topY * inv, c1, n1, o1);\n c += c1 * bw.y; nh += n1 * bw.y; o += o1 * bw.y;\n acc += sfWhiteoutTop(n, sfUnpackNormal(n1.rgb, ns)) * bw.y;\n }\n if (bw.x > 0.002){\n terrainTap(L, wp.zy * inv, g.sideXX * inv, g.sideXY * inv, c1, n1, o1);\n c += c1 * bw.x; nh += n1 * bw.x; o += o1 * bw.x;\n acc += sfWhiteoutX(n, sfUnpackNormal(n1.rgb, ns)) * bw.x;\n }\n if (bw.z > 0.002){\n terrainTap(L, wp.xy * inv, g.sideZX * inv, g.sideZY * inv, c1, n1, o1);\n c += c1 * bw.z; nh += n1 * bw.z; o += o1 * bw.z;\n acc += sfWhiteoutZ(n, sfUnpackNormal(n1.rgb, ns)) * bw.z;\n }\n } else {\n terrainTap(L, wp.xz * inv, g.topX * inv, g.topY * inv, c, nh, o);\n acc = sfWhiteoutTop(n, sfUnpackNormal(nh.rgb, ns));\n }\n col = c.rgb * u_tTint[L];\n wn = acc;\n h = nh.a;\n rough = o.g;\n ao = o.r;\n }\n}\n\n/** Near-field surface for weights w. Outputs albedo (no macro), normal,\n * roughness and occlusion. */\nvoid terrainSurfaceNear(vec3 wp, vec3 n, vec4 w, TerrainGrads g,\n out vec3 albedo, out vec3 nrm, out float rough, out float ao){\n float ws[4];\n ws[0] = w.x; ws[1] = w.y; ws[2] = w.z; ws[3] = w.w;\n int i0 = 0;\n float b0 = -1.0;\n for (int i = 0; i < 4; i++){ if (ws[i] > b0){ b0 = ws[i]; i0 = i; } }\n ws[i0] = -1.0;\n int i1 = 0;\n float b1 = -1.0;\n for (int i = 0; i < 4; i++){ if (ws[i] > b1){ b1 = ws[i]; i1 = i; } }\n b0 = max(b0, 0.0);\n b1 = max(b1, 0.0);\n float bs = max(b0 + b1, 1e-4);\n b0 /= bs;\n b1 /= bs;\n\n vec3 c0, n0, c1, n1;\n float h0, r0, a0, h1, r1, a1;\n terrainLayerSample(i0, wp, n, g, c0, n0, h0, r0, a0);\n if (b1 > 0.001){\n terrainLayerSample(i1, wp, n, g, c1, n1, h1, r1, a1);\n } else {\n c1 = c0; n1 = n0; h1 = h0; r1 = r0; a1 = a0;\n }\n\n // Height blend: the layer whose own surface is higher at this texel wins, so\n // gravel comes through grass along the gravel's grain and rock emerges from\n // soil along its cracks, instead of the two cross-fading into mud.\n float hb = u_tHeightBlend;\n float range = mix(1.0, 0.04, hb);\n float v0 = b0 + h0 * hb;\n float v1 = b1 + h1 * hb;\n float peak = max(v0, v1);\n float w0 = max(v0 - (peak - range), 0.0);\n float w1 = max(v1 - (peak - range), 0.0);\n if (b1 <= 0.001) w1 = 0.0;\n float ws2 = max(w0 + w1, 1e-4);\n w0 /= ws2;\n w1 /= ws2;\n\n albedo = c0 * w0 + c1 * w1;\n nrm = normalize(n0 * w0 + n1 * w1);\n rough = r0 * w0 + r1 * w1;\n ao = a0 * w0 + a1 * w1;\n}\n#endif\n";
|
|
87
94
|
/** Everything a surface material needs, in include order. Requires three's
|
|
88
95
|
* `<common>` and `skyLib` from cloudCore before it. */
|
|
96
|
+
/** Every uniform the terrain material reads. */
|
|
97
|
+
export declare const terrainUniforms: string;
|
|
89
98
|
export declare const terrainField: string;
|
|
99
|
+
/**
|
|
100
|
+
* The height field and its sun-shadow march, with only the uniforms they read.
|
|
101
|
+
* What another material includes to stand water (or anything else) on the
|
|
102
|
+
* terrain: the ocean uses it for shoreline depth and headland shadows.
|
|
103
|
+
*/
|
|
104
|
+
export declare const terrainFieldOnly: string;
|
|
90
105
|
export declare const terrainFull: string;
|
|
91
106
|
//# sourceMappingURL=terrainCore.glsl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrainCore.glsl.d.ts","sourceRoot":"","sources":["../../../src/shaders/glsl/terrainCore.glsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,
|
|
1
|
+
{"version":3,"file":"terrainCore.glsl.d.ts","sourceRoot":"","sources":["../../../src/shaders/glsl/terrainCore.glsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,ooDA0C/B,CAAA;AAED,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,8rDAsClC,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,uiCAiCxB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,mqbAiVzB,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,gjHAsEzB,CAAA;AAED,eAAO,MAAM,cAAc,6xKAkH1B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,4pLAyJ3B,CAAA;AAED;wDACwD;AACxD,gDAAgD;AAChD,eAAO,MAAM,eAAe,QAA2D,CAAA;AAEvF,eAAO,MAAM,YAAY,QAA4D,CAAA;AAErF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAA+E,CAAA;AAE5G,eAAO,MAAM,WAAW,QAA2D,CAAA"}
|
|
@@ -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(),
|
|
@@ -17,7 +17,7 @@ export interface RunOptions {
|
|
|
17
17
|
catalog?: TriggerCatalog;
|
|
18
18
|
effects?: boolean;
|
|
19
19
|
}
|
|
20
|
-
export type RunResult = 'ran' | 'queued' | 'waiting' | 'cycle' | 'refused' | 'unknown' | 'invalid';
|
|
20
|
+
export type RunResult = 'ran' | 'queued' | 'waiting' | 'cycle' | 'refused' | 'unknown' | 'invalid' | 'off';
|
|
21
21
|
export interface EngineContext extends TriggerContext {
|
|
22
22
|
catalog: TriggerCatalog;
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/triggers/engine.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjE,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC3B,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAChD,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACrD,KAAK,CAAC,IAAI,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9B,sFAAsF;IACtF,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/triggers/engine.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjE,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC3B,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAChD,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACrD,KAAK,CAAC,IAAI,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9B,sFAAsF;IACtF,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;AAE3G,MAAM,WAAW,aAAc,SAAQ,cAAc;IACjD,OAAO,EAAE,cAAc,CAAC;CAC3B;AAmBD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,IAAI,CAG1E;AAYD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAI7E;AAED,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,OAAO,CAIrF;AAED,uEAAuE;AACvE,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,aAAa,GAAG,SAA4B,CAAC;AAEvF,oEAAoE;AACpE,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAG9C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,SAAS,CAmCzE;AA6CD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAGrI;AAED,oDAAoD;AACpD,wBAAgB,kBAAkB,IAAI,IAAI,CAAoB"}
|
package/dist/triggers/engine.js
CHANGED
|
@@ -62,6 +62,9 @@ export function currentChain() {
|
|
|
62
62
|
export function runCommand(cmd, opts) {
|
|
63
63
|
if (!cmd || typeof cmd !== 'object' || !cmd.kind)
|
|
64
64
|
return 'invalid';
|
|
65
|
+
// an effect switched off in its list is kept but never runs (a revert still goes through: it may have been on)
|
|
66
|
+
if (cmd.kind === 'effect' && cmd.effect?.enabled === false && cmd.command !== 'revert')
|
|
67
|
+
return 'off';
|
|
65
68
|
const top = stack[stack.length - 1];
|
|
66
69
|
const ctx = {
|
|
67
70
|
source: opts.source,
|
|
@@ -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,
|
|
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"}
|
|
@@ -2,7 +2,7 @@ import { runCommand } from '../engine.js';
|
|
|
2
2
|
/** An action's commands, in the order they run. */
|
|
3
3
|
export const actionCommandsOf = (action) => (Array.isArray(action?.commands) ? action.commands : []);
|
|
4
4
|
/** The effects among an action's commands (to pre-warm their shaders). */
|
|
5
|
-
export const actionEffectsOf = (action) => actionCommandsOf(action).flatMap(c => (c.kind === 'effect' ? [c.effect] : []));
|
|
5
|
+
export const actionEffectsOf = (action) => actionCommandsOf(action).flatMap(c => (c.kind === 'effect' && c.effect.enabled !== false ? [c.effect] : []));
|
|
6
6
|
/** Switch an action's commands on (apply) or off (revert). */
|
|
7
7
|
export function runActionCommands(action, mode) {
|
|
8
8
|
const source = { host: 'action', id: action.id };
|
|
@@ -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')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../../../src/triggers/hosts/interactions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEvE,wDAAwD;AACxD,eAAO,MAAM,UAAU,GAAI,aAAa,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,YAAY,EACvB,CAAC;AAExE,+EAA+E;AAC/E,eAAO,MAAM,SAAS,GAAI,aAAa,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../../../src/triggers/hosts/interactions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEvE,wDAAwD;AACxD,eAAO,MAAM,UAAU,GAAI,aAAa,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,YAAY,EACvB,CAAC;AAExE,+EAA+E;AAC/E,eAAO,MAAM,SAAS,GAAI,aAAa,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,sDACiC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** An interaction's commands, in the order they run. */
|
|
2
2
|
export const commandsOf = (interaction) => (Array.isArray(interaction?.commands) ? interaction.commands : []);
|
|
3
3
|
/** The effects among an interaction's commands (to pre-warm their shaders). */
|
|
4
|
-
export const effectsOf = (interaction) => commandsOf(interaction).flatMap(c => (c.kind === 'effect' ? [c.effect] : []));
|
|
4
|
+
export const effectsOf = (interaction) => commandsOf(interaction).flatMap(c => (c.kind === 'effect' && c.effect.enabled !== false ? [c.effect] : []));
|
|
@@ -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;
|