@3driseai/3drise-viewer 0.1.7 → 0.1.8
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/components/Clouds.d.ts.map +1 -1
- package/dist/components/Clouds.js +0 -1
- package/dist/components/CloudsGenerator.d.ts +32 -0
- package/dist/components/CloudsGenerator.d.ts.map +1 -0
- package/dist/components/CloudsGenerator.js +58 -0
- package/dist/components/EnvironmentManager.d.ts +47 -5
- package/dist/components/EnvironmentManager.d.ts.map +1 -1
- package/dist/components/EnvironmentManager.js +35 -66
- package/dist/components/HdrEnvironment.d.ts +20 -0
- package/dist/components/HdrEnvironment.d.ts.map +1 -0
- package/dist/components/HdrEnvironment.js +44 -0
- package/dist/components/LandscapeBuilder.d.ts +23 -0
- package/dist/components/LandscapeBuilder.d.ts.map +1 -0
- package/dist/components/LandscapeBuilder.js +25 -0
- package/dist/components/LandscapeObject.d.ts +24 -0
- package/dist/components/LandscapeObject.d.ts.map +1 -0
- package/dist/components/LandscapeObject.js +27 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +10 -0
- package/dist/components/OceanBuilder.d.ts +35 -0
- package/dist/components/OceanBuilder.d.ts.map +1 -0
- package/dist/components/OceanBuilder.js +53 -0
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SkySystem.d.ts +27 -6
- package/dist/components/SkySystem.d.ts.map +1 -1
- package/dist/components/SkySystem.js +6 -5
- package/dist/components/SunLight.d.ts.map +1 -1
- package/dist/components/SunLight.js +4 -1
- package/dist/components/TerrainBuilder.d.ts +30 -0
- package/dist/components/TerrainBuilder.d.ts.map +1 -0
- package/dist/components/TerrainBuilder.js +44 -0
- package/dist/components/index.d.ts +17 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +10 -0
- package/dist/components/landscape/LandscapeMesh.d.ts +18 -0
- package/dist/components/landscape/LandscapeMesh.d.ts.map +1 -0
- package/dist/components/landscape/LandscapeMesh.js +278 -0
- package/dist/components/landscape/index.d.ts +3 -0
- package/dist/components/landscape/index.d.ts.map +1 -0
- package/dist/components/landscape/index.js +1 -0
- package/dist/components/landscape/types.d.ts +13 -0
- package/dist/components/landscape/types.d.ts.map +1 -0
- package/dist/components/landscape/types.js +1 -0
- package/dist/components/terrain/Canyon.d.ts +23 -0
- package/dist/components/terrain/Canyon.d.ts.map +1 -0
- package/dist/components/terrain/Canyon.js +29 -0
- package/dist/components/terrain/Dunes.d.ts +22 -0
- package/dist/components/terrain/Dunes.d.ts.map +1 -0
- package/dist/components/terrain/Dunes.js +25 -0
- package/dist/components/terrain/Hills.d.ts +17 -0
- package/dist/components/terrain/Hills.d.ts.map +1 -0
- package/dist/components/terrain/Hills.js +20 -0
- package/dist/components/terrain/Mountains.d.ts +19 -0
- package/dist/components/terrain/Mountains.d.ts.map +1 -0
- package/dist/components/terrain/Mountains.js +22 -0
- package/dist/components/terrain/TerrainSurface.d.ts +22 -0
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -0
- package/dist/components/terrain/TerrainSurface.js +94 -0
- package/dist/components/terrain/index.d.ts +7 -0
- package/dist/components/terrain/index.d.ts.map +1 -0
- package/dist/components/terrain/index.js +7 -0
- package/dist/components/terrain/types.d.ts +17 -0
- package/dist/components/terrain/types.d.ts.map +1 -0
- package/dist/components/terrain/types.js +1 -0
- package/dist/components/volumetricClouds/Cirrus.d.ts +14 -0
- package/dist/components/volumetricClouds/Cirrus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Cirrus.js +13 -0
- package/dist/components/volumetricClouds/Cumulonimbus.d.ts +17 -0
- package/dist/components/volumetricClouds/Cumulonimbus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Cumulonimbus.js +20 -0
- package/dist/components/volumetricClouds/Cumulus.d.ts +14 -0
- package/dist/components/volumetricClouds/Cumulus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Cumulus.js +17 -0
- package/dist/components/volumetricClouds/Stratocumulus.d.ts +12 -0
- package/dist/components/volumetricClouds/Stratocumulus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Stratocumulus.js +16 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +42 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.js +298 -0
- package/dist/components/volumetricClouds/index.d.ts +8 -0
- package/dist/components/volumetricClouds/index.d.ts.map +1 -0
- package/dist/components/volumetricClouds/index.js +7 -0
- package/dist/components/volumetricClouds/types.d.ts +17 -0
- package/dist/components/volumetricClouds/types.d.ts.map +1 -0
- package/dist/components/volumetricClouds/types.js +1 -0
- package/dist/components/water/Host.d.ts +12 -0
- package/dist/components/water/Host.d.ts.map +1 -0
- package/dist/components/water/Host.js +12 -0
- package/dist/components/water/Lake.d.ts +18 -0
- package/dist/components/water/Lake.d.ts.map +1 -0
- package/dist/components/water/Lake.js +21 -0
- package/dist/components/water/OceanSurface.d.ts +27 -0
- package/dist/components/water/OceanSurface.d.ts.map +1 -0
- package/dist/components/water/OceanSurface.js +60 -0
- package/dist/components/water/Sea.d.ts +18 -0
- package/dist/components/water/Sea.d.ts.map +1 -0
- package/dist/components/water/Sea.js +17 -0
- package/dist/components/water/Shore.d.ts +16 -0
- package/dist/components/water/Shore.d.ts.map +1 -0
- package/dist/components/water/Shore.js +15 -0
- package/dist/components/water/Storm.d.ts +14 -0
- package/dist/components/water/Storm.d.ts.map +1 -0
- package/dist/components/water/Storm.js +13 -0
- package/dist/components/water/WaterBody.d.ts +31 -0
- package/dist/components/water/WaterBody.d.ts.map +1 -0
- package/dist/components/water/WaterBody.js +76 -0
- package/dist/components/water/index.d.ts +9 -0
- package/dist/components/water/index.d.ts.map +1 -0
- package/dist/components/water/index.js +11 -0
- package/dist/components/water/types.d.ts +20 -0
- package/dist/components/water/types.d.ts.map +1 -0
- package/dist/components/water/types.js +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +9 -0
- package/dist/hooks/index.d.ts +24 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +12 -0
- package/dist/hooks/useClipmap.d.ts +71 -0
- package/dist/hooks/useClipmap.d.ts.map +1 -0
- package/dist/hooks/useClipmap.js +81 -0
- package/dist/hooks/useCloudLive.d.ts +29 -0
- package/dist/hooks/useCloudLive.d.ts.map +1 -0
- package/dist/hooks/useCloudLive.js +43 -0
- package/dist/hooks/useCloudNoise.d.ts +28 -0
- package/dist/hooks/useCloudNoise.d.ts.map +1 -0
- package/dist/hooks/useCloudNoise.js +128 -0
- package/dist/hooks/useCloudSun.d.ts +49 -0
- package/dist/hooks/useCloudSun.d.ts.map +1 -0
- package/dist/hooks/useCloudSun.js +84 -0
- package/dist/hooks/useCubeCamera.d.ts +27 -9
- package/dist/hooks/useCubeCamera.d.ts.map +1 -1
- package/dist/hooks/useCubeCamera.js +28 -70
- package/dist/hooks/useEnvironmentProbe.d.ts +32 -0
- package/dist/hooks/useEnvironmentProbe.d.ts.map +1 -0
- package/dist/hooks/useEnvironmentProbe.js +35 -0
- package/dist/hooks/useFrameRenderer.d.ts +15 -0
- package/dist/hooks/useFrameRenderer.d.ts.map +1 -0
- package/dist/hooks/useFrameRenderer.js +23 -0
- package/dist/hooks/useLandscapeLive.d.ts +29 -0
- package/dist/hooks/useLandscapeLive.d.ts.map +1 -0
- package/dist/hooks/useLandscapeLive.js +41 -0
- package/dist/hooks/useLandscapeMaps.d.ts +32 -0
- package/dist/hooks/useLandscapeMaps.d.ts.map +1 -0
- package/dist/hooks/useLandscapeMaps.js +138 -0
- package/dist/hooks/useOceanLive.d.ts +29 -0
- package/dist/hooks/useOceanLive.d.ts.map +1 -0
- package/dist/hooks/useOceanLive.js +38 -0
- package/dist/hooks/useOceanMaterial.d.ts +39 -0
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -0
- package/dist/hooks/useOceanMaterial.js +65 -0
- package/dist/hooks/useTerrainClipmap.d.ts +12 -0
- package/dist/hooks/useTerrainClipmap.d.ts.map +1 -0
- package/dist/hooks/useTerrainClipmap.js +10 -0
- package/dist/hooks/useTerrainLive.d.ts +34 -0
- package/dist/hooks/useTerrainLive.d.ts.map +1 -0
- package/dist/hooks/useTerrainLive.js +45 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/presets/landscapePresets.d.ts +60 -0
- package/dist/presets/landscapePresets.d.ts.map +1 -0
- package/dist/presets/landscapePresets.js +194 -0
- package/dist/presets/landscapeTypes.d.ts +195 -0
- package/dist/presets/landscapeTypes.d.ts.map +1 -0
- package/dist/presets/landscapeTypes.js +315 -0
- package/dist/presets/oceanSurfacePresets.d.ts +33 -0
- package/dist/presets/oceanSurfacePresets.d.ts.map +1 -0
- package/dist/presets/oceanSurfacePresets.js +245 -0
- package/dist/presets/terrainPresets.d.ts +28 -0
- package/dist/presets/terrainPresets.d.ts.map +1 -0
- package/dist/presets/terrainPresets.js +293 -0
- package/dist/presets/volumetricCloudPresets.d.ts +38 -0
- package/dist/presets/volumetricCloudPresets.d.ts.map +1 -0
- package/dist/presets/volumetricCloudPresets.js +480 -0
- package/dist/shaders/clouds/CirrusMaterial.d.ts +84 -0
- package/dist/shaders/clouds/CirrusMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CirrusMaterial.js +167 -0
- package/dist/shaders/clouds/CloudCompositeMaterial.d.ts +20 -0
- package/dist/shaders/clouds/CloudCompositeMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CloudCompositeMaterial.js +82 -0
- package/dist/shaders/clouds/CloudResolveMaterial.d.ts +22 -0
- package/dist/shaders/clouds/CloudResolveMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CloudResolveMaterial.js +77 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.d.ts +143 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.js +249 -0
- package/dist/shaders/clouds/SkyBackgroundMaterial.d.ts +21 -0
- package/dist/shaders/clouds/SkyBackgroundMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/SkyBackgroundMaterial.js +42 -0
- package/dist/shaders/glsl/cloudCore.glsl.d.ts +24 -0
- package/dist/shaders/glsl/cloudCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/cloudCore.glsl.js +348 -0
- package/dist/shaders/glsl/landscapeCore.glsl.d.ts +49 -0
- package/dist/shaders/glsl/landscapeCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/landscapeCore.glsl.js +518 -0
- package/dist/shaders/glsl/noiseBake.glsl.d.ts +30 -0
- package/dist/shaders/glsl/noiseBake.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/noiseBake.glsl.js +164 -0
- package/dist/shaders/glsl/oceanCore.glsl.d.ts +52 -0
- package/dist/shaders/glsl/oceanCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/oceanCore.glsl.js +421 -0
- package/dist/shaders/glsl/terrainCore.glsl.d.ts +78 -0
- package/dist/shaders/glsl/terrainCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/terrainCore.glsl.js +625 -0
- package/dist/shaders/landscape/LandscapeMaterial.d.ts +73 -0
- package/dist/shaders/landscape/LandscapeMaterial.d.ts.map +1 -0
- package/dist/shaders/landscape/LandscapeMaterial.js +136 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +57 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.js +268 -0
- package/dist/shaders/terrain/TerrainMaterial.d.ts +80 -0
- package/dist/shaders/terrain/TerrainMaterial.d.ts.map +1 -0
- package/dist/shaders/terrain/TerrainMaterial.js +291 -0
- package/dist/types/cloudConfigs.d.ts +244 -0
- package/dist/types/cloudConfigs.d.ts.map +1 -0
- package/dist/types/cloudConfigs.js +282 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -1
- package/dist/types/landscapeConfigs.d.ts +218 -0
- package/dist/types/landscapeConfigs.d.ts.map +1 -0
- package/dist/types/landscapeConfigs.js +256 -0
- package/dist/types/oceanConfigs.d.ts +290 -0
- package/dist/types/oceanConfigs.d.ts.map +1 -0
- package/dist/types/oceanConfigs.js +380 -0
- package/dist/types/terrainConfigs.d.ts +251 -0
- package/dist/types/terrainConfigs.d.ts.map +1 -0
- package/dist/types/terrainConfigs.js +292 -0
- package/dist/utils/cloudUniforms.d.ts +14 -0
- package/dist/utils/cloudUniforms.d.ts.map +1 -0
- package/dist/utils/cloudUniforms.js +122 -0
- package/dist/utils/frameRenderer.d.ts +33 -0
- package/dist/utils/frameRenderer.d.ts.map +1 -0
- package/dist/utils/frameRenderer.js +24 -0
- package/dist/utils/handleCloudsAnimations.d.ts +16 -0
- package/dist/utils/handleCloudsAnimations.d.ts.map +1 -0
- package/dist/utils/handleCloudsAnimations.js +64 -0
- package/dist/utils/landscapeGeometry.d.ts +61 -0
- package/dist/utils/landscapeGeometry.d.ts.map +1 -0
- package/dist/utils/landscapeGeometry.js +126 -0
- package/dist/utils/landscapeHeight.d.ts +44 -0
- package/dist/utils/landscapeHeight.d.ts.map +1 -0
- package/dist/utils/landscapeHeight.js +65 -0
- package/dist/utils/landscapeTextures.d.ts +94 -0
- package/dist/utils/landscapeTextures.d.ts.map +1 -0
- package/dist/utils/landscapeTextures.js +290 -0
- package/dist/utils/landscapeUniforms.d.ts +20 -0
- package/dist/utils/landscapeUniforms.d.ts.map +1 -0
- package/dist/utils/landscapeUniforms.js +61 -0
- package/dist/utils/oceanUniforms.d.ts +47 -0
- package/dist/utils/oceanUniforms.d.ts.map +1 -0
- package/dist/utils/oceanUniforms.js +216 -0
- package/dist/utils/rtin.d.ts +63 -0
- package/dist/utils/rtin.d.ts.map +1 -0
- package/dist/utils/rtin.js +202 -0
- package/dist/utils/terrainUniforms.d.ts +14 -0
- package/dist/utils/terrainUniforms.d.ts.map +1 -0
- package/dist/utils/terrainUniforms.js +196 -0
- package/package.json +2 -2
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { defaultLandscapeQuality, defaultLandscapeSurface } from '../types/landscapeConfigs.js';
|
|
2
|
+
const S = (pack, band, metres, surface) => ({ pack, band, metres, surface });
|
|
3
|
+
/** Texture repeats across the tile, from a real-world tile size. Clamped: below
|
|
4
|
+
* about half a metre a ground texture aliases before it reads as detail, and
|
|
5
|
+
* above about forty it is wallpaper. */
|
|
6
|
+
export function repeatForMetres(size, metres) {
|
|
7
|
+
return Math.max(1, Math.round(size / Math.min(Math.max(metres, 0.5), 40)));
|
|
8
|
+
}
|
|
9
|
+
export const landscapeTypes = [
|
|
10
|
+
{
|
|
11
|
+
id: 'grassland',
|
|
12
|
+
label: 'Grassland',
|
|
13
|
+
description: 'Green slopes, bare soil in the hollows, rock where it is too steep to hold.',
|
|
14
|
+
packs: [
|
|
15
|
+
S('grass_meadow', 0.15, 2.5, { saturation: 0.85, tint: '#b6c4a8', roughness: 0.95, normalStrength: 0.45 }),
|
|
16
|
+
S('soil_mud', 0.55, 3.0, { saturation: 0.8, roughness: 0.88 }),
|
|
17
|
+
S('rock_cliff', 0.9, 4.0, { triplanar: true, tint: '#cfc9c2', roughness: 0.82 }),
|
|
18
|
+
],
|
|
19
|
+
splat: { bandWidth: 0.5, slopeStart: 0.3, slopeEnd: 0.6, noise: 0.14, noiseSize: 350 },
|
|
20
|
+
settings: { macroVariation: 0.28, macroSize: 800 },
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'rocky',
|
|
24
|
+
label: 'Rocky',
|
|
25
|
+
description: 'Broken stone and scree with soil caught in the flats.',
|
|
26
|
+
packs: [
|
|
27
|
+
S('soil_mud', 0.1, 3.0, { saturation: 0.7 }),
|
|
28
|
+
S('rock_boulder', 0.5, 4.0, { triplanar: true, tint: '#c8c4bd' }),
|
|
29
|
+
S('rock_cliff', 0.85, 4.0, { triplanar: true }),
|
|
30
|
+
],
|
|
31
|
+
splat: { bandWidth: 0.55, slopeStart: 0.22, slopeEnd: 0.5, noise: 0.18, noiseSize: 280 },
|
|
32
|
+
settings: { macroVariation: 0.22, macroSize: 600 },
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'cliffs',
|
|
36
|
+
label: 'Cliffs',
|
|
37
|
+
description: 'Bare rock almost everywhere — the shape does the talking.',
|
|
38
|
+
packs: [
|
|
39
|
+
S('rock_boulder', 0.25, 4.0, { triplanar: true }),
|
|
40
|
+
S('rock_cliff', 0.8, 4.0, { triplanar: true, tint: '#cfc9c2' }),
|
|
41
|
+
],
|
|
42
|
+
splat: { bandWidth: 0.7, slopeStart: 0.12, slopeEnd: 0.38, noise: 0.2, noiseSize: 240 },
|
|
43
|
+
settings: { macroVariation: 0.18, macroSize: 900 },
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'meadow',
|
|
47
|
+
label: 'Meadow',
|
|
48
|
+
description: 'Lush low ground drying out as it rises.',
|
|
49
|
+
packs: [
|
|
50
|
+
S('grass_meadow', 0.12, 2.5, { tint: '#aec49c' }),
|
|
51
|
+
S('grass_dry', 0.55, 2.5, { tint: '#cbbf8e' }),
|
|
52
|
+
S('soil_mud', 0.92, 3.0, { repeat: 300 }),
|
|
53
|
+
],
|
|
54
|
+
splat: { bandWidth: 0.5, slopeStart: 0.4, slopeEnd: 0.72, noise: 0.16, noiseSize: 420 },
|
|
55
|
+
settings: { macroVariation: 0.32, macroSize: 900 },
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'snow',
|
|
59
|
+
label: 'Snow',
|
|
60
|
+
description: 'Snow on the tops and the flats, rock on the faces that are too steep to hold it.',
|
|
61
|
+
packs: [
|
|
62
|
+
// Order matters: the LAST pack is the slope layer (see the auto-splat
|
|
63
|
+
// block in landscapeCore.glsl), so it must be the rock. The first
|
|
64
|
+
// version listed snow last and therefore painted snow onto exactly
|
|
65
|
+
// the faces too steep to hold it - the inverse of the description.
|
|
66
|
+
S('rock_cliff', 0.12, 4.0, { triplanar: true, tint: '#b9bcc2' }),
|
|
67
|
+
S('snow_fresh', 0.75, 3.0, { roughness: 0.55, saturation: 0.6, tint: '#f2f6ff' }),
|
|
68
|
+
S('rock_boulder', 0.95, 4.0, { triplanar: true, tint: '#c6c9cf' }),
|
|
69
|
+
],
|
|
70
|
+
splat: { bandWidth: 0.42, slopeStart: 0.34, slopeEnd: 0.6, noise: 0.1, noiseSize: 500 },
|
|
71
|
+
settings: { macroVariation: 0.14, macroSize: 1200 },
|
|
72
|
+
thumbPack: 'snow_fresh',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'sand',
|
|
76
|
+
label: 'Sand',
|
|
77
|
+
description: 'Dune sand, rippled where the wind reaches, rock breaking through at the steepest angles.',
|
|
78
|
+
packs: [
|
|
79
|
+
S('sand_dune', 0.2, 4.0, { roughness: 0.6, saturation: 0.9 }),
|
|
80
|
+
S('sand_rippled', 0.65, 3.5, { roughness: 0.55 }),
|
|
81
|
+
S('rock_boulder', 0.95, 4.0, { triplanar: true }),
|
|
82
|
+
],
|
|
83
|
+
splat: { bandWidth: 0.6, slopeStart: 0.5, slopeEnd: 0.82, noise: 0.1, noiseSize: 600 },
|
|
84
|
+
settings: { macroVariation: 0.16, macroSize: 1600 },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'desert',
|
|
88
|
+
label: 'Desert',
|
|
89
|
+
description: 'Cracked pan between sand flats, mesa rock above.',
|
|
90
|
+
packs: [
|
|
91
|
+
S('sand_dune', 0.15, 4.0, { roughness: 0.62 }),
|
|
92
|
+
S('soil_cracked', 0.5, 3.5, { saturation: 0.75 }),
|
|
93
|
+
S('rock_mesa', 0.9, 4.5, { triplanar: true, tint: '#c98f63' }),
|
|
94
|
+
],
|
|
95
|
+
splat: { bandWidth: 0.5, slopeStart: 0.3, slopeEnd: 0.58, noise: 0.2, noiseSize: 380 },
|
|
96
|
+
settings: { macroVariation: 0.26, macroSize: 1100 },
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'forest_floor',
|
|
100
|
+
label: 'Forest floor',
|
|
101
|
+
description: 'Leaf litter and moss under the canopy, roots and rock on the banks.',
|
|
102
|
+
packs: [
|
|
103
|
+
S('forest_litter', 0.15, 2.5, { saturation: 0.8, tint: '#9c8a6c' }),
|
|
104
|
+
S('moss_ground', 0.55, 2.0, { tint: '#8ea882' }),
|
|
105
|
+
S('rock_boulder', 0.9, 4.0, { triplanar: true }),
|
|
106
|
+
],
|
|
107
|
+
splat: { bandWidth: 0.52, slopeStart: 0.36, slopeEnd: 0.66, noise: 0.22, noiseSize: 260 },
|
|
108
|
+
settings: { macroVariation: 0.34, macroSize: 500 },
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'tundra',
|
|
112
|
+
label: 'Tundra',
|
|
113
|
+
description: 'Low moss over gravel, frost-shattered rock on the ridges.',
|
|
114
|
+
packs: [
|
|
115
|
+
S('tundra_moss', 0.18, 2.0, { saturation: 0.7, tint: '#9aa383' }),
|
|
116
|
+
S('gravel', 0.55, 2.0, { saturation: 0.65 }),
|
|
117
|
+
S('rock_cliff', 0.9, 4.0, { triplanar: true, tint: '#b8b4ae' }),
|
|
118
|
+
],
|
|
119
|
+
splat: { bandWidth: 0.5, slopeStart: 0.28, slopeEnd: 0.55, noise: 0.18, noiseSize: 320 },
|
|
120
|
+
settings: { macroVariation: 0.24, macroSize: 700 },
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: 'volcanic',
|
|
124
|
+
label: 'Volcanic',
|
|
125
|
+
description: 'Ash fields over basalt, everything dark and matte.',
|
|
126
|
+
packs: [
|
|
127
|
+
S('ash_ground', 0.15, 3.0, { saturation: 0.4, tint: '#6b6663', roughness: 0.95 }),
|
|
128
|
+
S('basalt', 0.6, 3.5, { saturation: 0.35, tint: '#4f4c4a', triplanar: true }),
|
|
129
|
+
S('rock_boulder', 0.95, 4.0, { triplanar: true, tint: '#5a5652' }),
|
|
130
|
+
],
|
|
131
|
+
splat: { bandWidth: 0.55, slopeStart: 0.25, slopeEnd: 0.55, noise: 0.2, noiseSize: 300 },
|
|
132
|
+
settings: { macroVariation: 0.3, macroSize: 650 },
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
export function getLandscapeType(id) {
|
|
136
|
+
return landscapeTypes.find((t) => t.id === id);
|
|
137
|
+
}
|
|
138
|
+
/** Every surface pack any type refers to — for a client that wants to know what
|
|
139
|
+
* to upload, or which types it can offer. */
|
|
140
|
+
export function landscapeTypePacks(type) {
|
|
141
|
+
return type.packs.map((p) => p.pack);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Every type, with the reason each unavailable one is unavailable.
|
|
145
|
+
*
|
|
146
|
+
* The packs in a type are NOT interchangeable, so "needs all of them" is the
|
|
147
|
+
* wrong rule and this is the right one. Two of them are load-bearing:
|
|
148
|
+
*
|
|
149
|
+
* THE LAST PACK is the slope layer. The auto-splat block in
|
|
150
|
+
* `landscapeCore.glsl` bands every surface by height, multiplies all but the
|
|
151
|
+
* last by `1 - rock`, and then forces the last one on by slope. Drop it and
|
|
152
|
+
* the next pack up is silently promoted into that role — a ground texture
|
|
153
|
+
* smeared vertically up every cliff face, which is the ugliest thing this
|
|
154
|
+
* material can do.
|
|
155
|
+
*
|
|
156
|
+
* THE SIGNATURE PACK (`thumbPack`, else the first) is what makes the type
|
|
157
|
+
* that type. Snow without `snow_fresh` is rock, and offering it under the
|
|
158
|
+
* name Snow is worse than not offering it.
|
|
159
|
+
*
|
|
160
|
+
* Everything in between is a middle height band. Losing one widens the gap
|
|
161
|
+
* between the layers that remain; `resolveLandscapeType` already rebuilds the
|
|
162
|
+
* band array from the surfaces that actually resolved, so nothing lands at the
|
|
163
|
+
* wrong altitude. That is a poorer version of the biome, not a broken one, and
|
|
164
|
+
* it is not worth blocking a type over — Sand with dune sand and boulders but
|
|
165
|
+
* no ripple layer is still recognisably sand.
|
|
166
|
+
*/
|
|
167
|
+
export function landscapeTypeAvailability(havePacks) {
|
|
168
|
+
const have = new Set(havePacks);
|
|
169
|
+
return landscapeTypes.map((type) => {
|
|
170
|
+
const names = landscapeTypePacks(type);
|
|
171
|
+
const missingPacks = names.filter((p) => !have.has(p));
|
|
172
|
+
const loadBearing = new Set([names[names.length - 1], type.thumbPack ?? names[0]]);
|
|
173
|
+
const blockingPacks = missingPacks.filter((p) => loadBearing.has(p));
|
|
174
|
+
const reducedPacks = missingPacks.filter((p) => !loadBearing.has(p));
|
|
175
|
+
return {
|
|
176
|
+
type,
|
|
177
|
+
missingPacks,
|
|
178
|
+
blockingPacks,
|
|
179
|
+
reducedPacks,
|
|
180
|
+
available: blockingPacks.length === 0,
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
export const landscapeShapes = [
|
|
185
|
+
{ id: 'highlands', label: 'Highlands', description: 'Broad ridges and wide valleys.', size: 2048, elevation: 340, hasSplatMaps: true },
|
|
186
|
+
{ id: 'mountains', label: 'Mountains', description: 'Sharp peaks, deep cols.', size: 3000, elevation: 900 },
|
|
187
|
+
{ id: 'rolling_hills', label: 'Rolling hills', description: 'Gentle, walkable ground.', size: 2400, elevation: 120 },
|
|
188
|
+
{ id: 'foothills', label: 'Foothills', description: 'Low ridges rising toward a range.', size: 2200, elevation: 320 },
|
|
189
|
+
{ id: 'valley', label: 'Valley', description: 'One floor between two walls.', size: 2600, elevation: 420 },
|
|
190
|
+
{ id: 'dunes', label: 'Dunes', description: 'Wind-formed ridges, no rock.', size: 3000, elevation: 90 },
|
|
191
|
+
{ id: 'plateau', label: 'Plateau', description: 'Flat tops with steep sides.', size: 2800, elevation: 300 },
|
|
192
|
+
{ id: 'island', label: 'Island', description: 'Ground falling away to water on every side.', size: 2000, elevation: 260 },
|
|
193
|
+
{ id: 'canyon', label: 'Canyon', description: 'Incised channels below a flat rim.', size: 2600, elevation: 500 },
|
|
194
|
+
];
|
|
195
|
+
export function getLandscapeShape(id) {
|
|
196
|
+
return landscapeShapes.find((s) => s.id === id);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The six knobs a non-expert cannot reason about individually but has a clear
|
|
200
|
+
* opinion about collectively. `meshError` is in world units and therefore scales
|
|
201
|
+
* with the landscape's relief, so it is applied as a FRACTION of elevation
|
|
202
|
+
* rather than as a constant — 1.5 m of error on a 90 m dune field is invisible,
|
|
203
|
+
* on a 900 m range it is a stepped silhouette.
|
|
204
|
+
*/
|
|
205
|
+
export const LANDSCAPE_DETAIL = {
|
|
206
|
+
draft: {
|
|
207
|
+
label: 'Draft',
|
|
208
|
+
description: 'Fastest. Coarse mesh, one surface per pixel, no stochastic tiling — for blocking out a scene.',
|
|
209
|
+
meshErrorFraction: 0.006,
|
|
210
|
+
surfaceSamples: 1,
|
|
211
|
+
quality: { arrayResolution: 512, stochastic: false, triplanar: false, anisotropy: 1, chunks: 4 },
|
|
212
|
+
},
|
|
213
|
+
balanced: {
|
|
214
|
+
label: 'Balanced',
|
|
215
|
+
description: 'The default. Two surfaces blended per pixel with stochastic tiling on.',
|
|
216
|
+
meshErrorFraction: 0.0018,
|
|
217
|
+
surfaceSamples: 2,
|
|
218
|
+
quality: { arrayResolution: 1024, stochastic: true, triplanar: true, anisotropy: 4, chunks: 4 },
|
|
219
|
+
},
|
|
220
|
+
high: {
|
|
221
|
+
label: 'High',
|
|
222
|
+
description: 'Three surfaces per pixel and 2K textures. Costs about four times the memory of Balanced.',
|
|
223
|
+
meshErrorFraction: 0.0006,
|
|
224
|
+
surfaceSamples: 3,
|
|
225
|
+
quality: { arrayResolution: 2048, stochastic: true, triplanar: true, anisotropy: 8, chunks: 6 },
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
export function landscapeQualityForDetail(detail, elevation) {
|
|
229
|
+
const spec = LANDSCAPE_DETAIL[detail] ?? LANDSCAPE_DETAIL.balanced;
|
|
230
|
+
return {
|
|
231
|
+
...defaultLandscapeQuality,
|
|
232
|
+
...spec.quality,
|
|
233
|
+
meshError: Math.max(0.05, Math.round(elevation * spec.meshErrorFraction * 100) / 100),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/** Best guess at which detail level a config came from, so the Basic tab can
|
|
237
|
+
* show the right button after an Advanced edit — or show none, which is the
|
|
238
|
+
* honest answer once someone has hand-tuned it. */
|
|
239
|
+
export function detectLandscapeDetail(quality, surfaceSamples) {
|
|
240
|
+
for (const [id, spec] of Object.entries(LANDSCAPE_DETAIL)) {
|
|
241
|
+
const q = spec.quality;
|
|
242
|
+
if (quality.arrayResolution === q.arrayResolution
|
|
243
|
+
&& quality.stochastic === q.stochastic
|
|
244
|
+
&& quality.triplanar === q.triplanar
|
|
245
|
+
&& surfaceSamples === spec.surfaceSamples)
|
|
246
|
+
return id;
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Two picks and a detail level to a whole config.
|
|
252
|
+
*
|
|
253
|
+
* A pack with no albedo is dropped, not rendered as a hole — a surface with no
|
|
254
|
+
* albedo is skipped by the renderer anyway, and an empty slot in the middle of
|
|
255
|
+
* the list would shift the bands of every layer after it.
|
|
256
|
+
*
|
|
257
|
+
* The shape's own `size` and `elevation` are the starting point rather than a
|
|
258
|
+
* global default, because a dune field and an alpine range are not the same
|
|
259
|
+
* scene at the same numbers. The caller overrides them once the user touches a
|
|
260
|
+
* slider.
|
|
261
|
+
*/
|
|
262
|
+
export function resolveLandscapeType(typeId, shapeId, index, detail = 'balanced', override = {}) {
|
|
263
|
+
const type = getLandscapeType(typeId);
|
|
264
|
+
const shape = getLandscapeShape(shapeId);
|
|
265
|
+
const missing = [];
|
|
266
|
+
const heightMap = index.shape(shapeId, 'height');
|
|
267
|
+
if (!heightMap)
|
|
268
|
+
missing.push(`terrains/${shapeId}/height`);
|
|
269
|
+
const surfaces = [];
|
|
270
|
+
const bands = [];
|
|
271
|
+
for (const ref of type?.packs ?? []) {
|
|
272
|
+
const albedo = index.pack(ref.pack, 'albedo');
|
|
273
|
+
if (!albedo) {
|
|
274
|
+
missing.push(`surfaces/${ref.pack}/albedo`);
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
surfaces.push({
|
|
278
|
+
...defaultLandscapeSurface,
|
|
279
|
+
name: ref.pack,
|
|
280
|
+
...ref.surface,
|
|
281
|
+
repeat: repeatForMetres(override.size ?? shape?.size ?? 2048, ref.metres ?? 3),
|
|
282
|
+
diffuse: albedo,
|
|
283
|
+
normal: index.pack(ref.pack, 'normal') ?? '',
|
|
284
|
+
displacement: index.pack(ref.pack, 'height') ?? '',
|
|
285
|
+
});
|
|
286
|
+
bands.push(ref.band ?? 0.5);
|
|
287
|
+
}
|
|
288
|
+
const elevation = override.elevation ?? shape?.elevation ?? 340;
|
|
289
|
+
const size = override.size ?? shape?.size ?? 2048;
|
|
290
|
+
const splat = type?.splat ?? { bandWidth: 0.5, slopeStart: 0.35, slopeEnd: 0.62, noise: 0.12, noiseSize: 400 };
|
|
291
|
+
return {
|
|
292
|
+
config: {
|
|
293
|
+
...(type?.settings ?? {}),
|
|
294
|
+
enabled: !!heightMap && surfaces.length > 0,
|
|
295
|
+
landscapeType: type?.id ?? '',
|
|
296
|
+
shape: shape?.id ?? '',
|
|
297
|
+
heightMap: heightMap ?? '',
|
|
298
|
+
heightEncoding: 'grayscale',
|
|
299
|
+
// Always the generated splat: a type is a recipe for placing surfaces
|
|
300
|
+
// by height and slope, and no shape x type pairing has an authored
|
|
301
|
+
// splat map. The Advanced tab is where an authored one goes.
|
|
302
|
+
splatSource: 'auto',
|
|
303
|
+
splatMaps: [],
|
|
304
|
+
aoMap: index.shape(shapeId, 'ao') ?? '',
|
|
305
|
+
size,
|
|
306
|
+
elevationScale: elevation,
|
|
307
|
+
surfaces,
|
|
308
|
+
surfaceSamples: LANDSCAPE_DETAIL[detail].surfaceSamples,
|
|
309
|
+
autoSplat: { ...splat, bands },
|
|
310
|
+
preset: '',
|
|
311
|
+
},
|
|
312
|
+
quality: landscapeQualityForDetail(detail, elevation),
|
|
313
|
+
missing,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { OceanSurfaceConfig, WaterType } from '../types/oceanConfigs';
|
|
2
|
+
/**
|
|
3
|
+
* Presets for the ocean.
|
|
4
|
+
*
|
|
5
|
+
* They live here rather than in `core/src/presets` for the same reason the cloud
|
|
6
|
+
* and terrain presets do: they are `Partial<OceanSurfaceConfig>`, and that type
|
|
7
|
+
* is declared in this package next to the shader that consumes it. (Core's
|
|
8
|
+
* `oceanPresets.ts` is a different thing entirely — five *material* variants for
|
|
9
|
+
* the retired flat-plane ocean. Their five names are reused here on purpose:
|
|
10
|
+
* they were already the vocabulary, and `normalizeOcean` maps the old ones onto
|
|
11
|
+
* these.)
|
|
12
|
+
*
|
|
13
|
+
* Each entry is a *patch* over the type's defaults, not a full config, so a knob
|
|
14
|
+
* added to the renderer inherits its default everywhere instead of silently
|
|
15
|
+
* reverting to whatever a preset happened to be authored with — and switching
|
|
16
|
+
* between two presets never leaves a number behind from the previous one.
|
|
17
|
+
*
|
|
18
|
+
* The sea presets are named for the Beaufort scale, because a name someone can
|
|
19
|
+
* picture is worth more in a dropdown than "Ocean 3", and because the numbers
|
|
20
|
+
* behind them are the wind speeds that scale actually describes.
|
|
21
|
+
*/
|
|
22
|
+
export interface OceanPreset {
|
|
23
|
+
name: string;
|
|
24
|
+
waterType: WaterType;
|
|
25
|
+
description: string;
|
|
26
|
+
tags: string[];
|
|
27
|
+
settings: Partial<OceanSurfaceConfig>;
|
|
28
|
+
}
|
|
29
|
+
export declare const oceanSurfacePresets: OceanPreset[];
|
|
30
|
+
export declare function getOceanPresetsForType(type: WaterType): OceanPreset[];
|
|
31
|
+
export declare function getOceanPresetByName(name: string): OceanPreset | undefined;
|
|
32
|
+
export declare function searchOceanPresetsByTags(tags: string[]): OceanPreset[];
|
|
33
|
+
//# sourceMappingURL=oceanSurfacePresets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oceanSurfacePresets.d.ts","sourceRoot":"","sources":["../../src/presets/oceanSurfacePresets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACzC;AAgPD,eAAO,MAAM,mBAAmB,EAAE,WAAW,EAK5C,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,EAAE,CAErE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE1E;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAGtE"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Sea — open water, named for the wind that makes it
|
|
3
|
+
// =============================================================================
|
|
4
|
+
const seaPresets = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Glassy',
|
|
7
|
+
waterType: 'sea',
|
|
8
|
+
description: 'Almost no wind. A slow swell left over from weather somewhere else, and a mirror everywhere between the crests.',
|
|
9
|
+
tags: ['calm', 'mirror', 'still', 'dawn'],
|
|
10
|
+
settings: {
|
|
11
|
+
windSpeed: 1.5, fetch: 400, directionalSpread: 12, swell: 0.9,
|
|
12
|
+
choppiness: 0.35, foamAmount: 0, roughness: 0.03, specular: 1.4,
|
|
13
|
+
waveComponents: 14, detailStrength: 0.25,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'Light breeze',
|
|
18
|
+
waterType: 'sea',
|
|
19
|
+
description: 'Small wind waves over a low swell. The everyday sea, and the one most scenes want.',
|
|
20
|
+
tags: ['gentle', 'daylight', 'default'],
|
|
21
|
+
settings: {
|
|
22
|
+
windSpeed: 5.5, fetch: 250, directionalSpread: 28, swell: 0.45,
|
|
23
|
+
choppiness: 0.7, foamAmount: 0.15, roughness: 0.07,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Moderate sea',
|
|
28
|
+
waterType: 'sea',
|
|
29
|
+
description: 'Whitecaps starting to show on the steepest crests. Force 5.',
|
|
30
|
+
tags: ['whitecaps', 'wind', 'blue'],
|
|
31
|
+
settings: {
|
|
32
|
+
windSpeed: 9.5, fetch: 300, directionalSpread: 32, swell: 0.35,
|
|
33
|
+
choppiness: 0.9, foamAmount: 0.6,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'Rough',
|
|
38
|
+
waterType: 'sea',
|
|
39
|
+
description: 'Long crests breaking regularly, spray beginning to blow off them. Force 7.',
|
|
40
|
+
tags: ['rough', 'foam', 'grey', 'wind'],
|
|
41
|
+
settings: {
|
|
42
|
+
windSpeed: 15, fetch: 450, directionalSpread: 38, swell: 0.4,
|
|
43
|
+
choppiness: 1.0, foamAmount: 1.05, foamDecay: 0.7,
|
|
44
|
+
deepColor: '#082a3a', shallowColor: '#276c78', roughness: 0.12,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'Gale',
|
|
49
|
+
waterType: 'sea',
|
|
50
|
+
description: 'The whole surface breaking. Foam in streaks down the wind, and very little water left showing between them.',
|
|
51
|
+
tags: ['storm', 'gale', 'white', 'violent'],
|
|
52
|
+
settings: {
|
|
53
|
+
windSpeed: 21, fetch: 600, directionalSpread: 44, swell: 0.5,
|
|
54
|
+
choppiness: 1.15, steepness: 0.85, foamAmount: 1.6, foamDecay: 0.85, foamSize: 14,
|
|
55
|
+
deepColor: '#0a2028', shallowColor: '#2e6068', roughness: 0.17, sssStrength: 0.3,
|
|
56
|
+
aerialPerspective: 0.00018,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Lake — short fetch is the whole story
|
|
62
|
+
// =============================================================================
|
|
63
|
+
const lakePresets = [
|
|
64
|
+
{
|
|
65
|
+
name: 'Still',
|
|
66
|
+
waterType: 'lake',
|
|
67
|
+
description: 'A mirror with the faintest texture on it. Reflection is doing all the work.',
|
|
68
|
+
tags: ['calm', 'mirror', 'morning', 'reflection'],
|
|
69
|
+
settings: {
|
|
70
|
+
windSpeed: 1, fetch: 1.5, waveComponents: 10, choppiness: 0.3,
|
|
71
|
+
foamAmount: 0, roughness: 0.025, specular: 1.5, detailStrength: 0.4, detailSize: 1.6,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'Ripples',
|
|
76
|
+
waterType: 'lake',
|
|
77
|
+
description: 'Cat’s paws crossing an otherwise flat surface. The short end of the spectrum and nothing else.',
|
|
78
|
+
tags: ['ripple', 'light', 'texture'],
|
|
79
|
+
settings: {
|
|
80
|
+
windSpeed: 2.5, fetch: 1.5, waveComponents: 12, choppiness: 0.45,
|
|
81
|
+
roughness: 0.05, detailStrength: 0.8, detailSize: 0.9,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'Breeze',
|
|
86
|
+
waterType: 'lake',
|
|
87
|
+
description: 'Steady wind across open water. Short, regular waves with no swell under them at all.',
|
|
88
|
+
tags: ['wind', 'daylight', 'green'],
|
|
89
|
+
settings: {
|
|
90
|
+
windSpeed: 4.5, fetch: 3, choppiness: 0.6, foamAmount: 0.1,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'Choppy',
|
|
95
|
+
waterType: 'lake',
|
|
96
|
+
description: 'The steep, short, disorganised chop that inland water produces and open ocean does not.',
|
|
97
|
+
tags: ['chop', 'steep', 'short'],
|
|
98
|
+
settings: {
|
|
99
|
+
windSpeed: 8, fetch: 4, directionalSpread: 40, choppiness: 0.95,
|
|
100
|
+
steepness: 0.85, foamAmount: 0.35, waveComponents: 16,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'Wind-blown',
|
|
105
|
+
waterType: 'lake',
|
|
106
|
+
description: 'A gale on a lake: still small waves, because there is no room upwind for anything bigger, but every one of them breaking.',
|
|
107
|
+
tags: ['storm', 'chop', 'foam', 'grey'],
|
|
108
|
+
settings: {
|
|
109
|
+
windSpeed: 16, fetch: 5, directionalSpread: 45, choppiness: 1.1,
|
|
110
|
+
steepness: 0.9, foamAmount: 1.1, foamDecay: 0.6,
|
|
111
|
+
deepColor: '#12262a', shallowColor: '#38707a', roughness: 0.14,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
// =============================================================================
|
|
116
|
+
// Storm
|
|
117
|
+
// =============================================================================
|
|
118
|
+
const stormPresets = [
|
|
119
|
+
{
|
|
120
|
+
name: 'Building',
|
|
121
|
+
waterType: 'storm',
|
|
122
|
+
description: 'The sea before the weather arrives: long swell running ahead of the wind that made it.',
|
|
123
|
+
tags: ['swell', 'ominous', 'grey'],
|
|
124
|
+
settings: {
|
|
125
|
+
windSpeed: 14, swell: 0.75, choppiness: 0.85, foamAmount: 0.6,
|
|
126
|
+
deepColor: '#0d2430', shallowColor: '#33686e',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'Full storm',
|
|
131
|
+
waterType: 'storm',
|
|
132
|
+
description: 'Twenty-five metres a second. Crests folding through themselves, which is where the whitecaps come from — they are not painted on.',
|
|
133
|
+
tags: ['storm', 'violent', 'foam', 'break'],
|
|
134
|
+
settings: {
|
|
135
|
+
windSpeed: 25, choppiness: 1.2, steepness: 0.9, foamAmount: 1.7, foamDecay: 0.8,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'Hurricane',
|
|
140
|
+
waterType: 'storm',
|
|
141
|
+
description: 'The top of the scale. Confused, enormous, and almost entirely white.',
|
|
142
|
+
tags: ['hurricane', 'extreme', 'white', 'chaos'],
|
|
143
|
+
settings: {
|
|
144
|
+
windSpeed: 38, fetch: 900, directionalSpread: 55, waveComponents: 30,
|
|
145
|
+
choppiness: 1.3, steepness: 1, foamAmount: 2, foamDecay: 0.95, foamSize: 20,
|
|
146
|
+
deepColor: '#08171e', shallowColor: '#2a545c', roughness: 0.2,
|
|
147
|
+
sssStrength: 0.2, aerialPerspective: 0.00028,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'Squall line',
|
|
152
|
+
waterType: 'storm',
|
|
153
|
+
description: 'A narrow, aligned sea driven hard from one quarter. Less confused than a full storm and steeper for it.',
|
|
154
|
+
tags: ['squall', 'aligned', 'steep'],
|
|
155
|
+
settings: {
|
|
156
|
+
windSpeed: 20, fetch: 200, directionalSpread: 18, choppiness: 1.15,
|
|
157
|
+
steepness: 0.95, foamAmount: 1.3,
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'After the storm',
|
|
162
|
+
waterType: 'storm',
|
|
163
|
+
description: 'The wind has dropped and left its swell behind. Large, smooth, and slow — the sea takes a day to forget.',
|
|
164
|
+
tags: ['swell', 'aftermath', 'smooth', 'large'],
|
|
165
|
+
settings: {
|
|
166
|
+
windSpeed: 8, swell: 1, directionalSpread: 16, choppiness: 0.7,
|
|
167
|
+
foamAmount: 0.2, waveComponents: 18, roughness: 0.07,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
// =============================================================================
|
|
172
|
+
// Shore
|
|
173
|
+
// =============================================================================
|
|
174
|
+
const shorePresets = [
|
|
175
|
+
{
|
|
176
|
+
name: 'Tropical shallows',
|
|
177
|
+
waterType: 'shore',
|
|
178
|
+
description: 'Clear water over pale sand. Almost all of the colour is the bottom coming through.',
|
|
179
|
+
tags: ['tropical', 'clear', 'turquoise', 'shallow'],
|
|
180
|
+
settings: {
|
|
181
|
+
windSpeed: 4, deepColor: '#0a5a7a', shallowColor: '#4fd6c8', sssColor: '#39c8b0',
|
|
182
|
+
absorption: 0.04, clarity: 0.1, shoreDepth: 8, shoreFoam: 1.2,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'Rolling swell',
|
|
187
|
+
waterType: 'shore',
|
|
188
|
+
description: 'Long lines coming in square to the beach, the way waves do once they have refracted into the shallows.',
|
|
189
|
+
tags: ['swell', 'surf', 'aligned', 'beach'],
|
|
190
|
+
settings: {
|
|
191
|
+
windSpeed: 8, swell: 0.9, directionalSpread: 10, choppiness: 1.05,
|
|
192
|
+
foamAmount: 1.1, foamDecay: 0.85, shoreFoam: 1.6,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'Cold coast',
|
|
197
|
+
waterType: 'shore',
|
|
198
|
+
description: 'Grey-green water over dark rock, and a hard foam line where it meets it.',
|
|
199
|
+
tags: ['cold', 'north', 'rock', 'grey'],
|
|
200
|
+
settings: {
|
|
201
|
+
windSpeed: 12, deepColor: '#12333a', shallowColor: '#40808a', sssColor: '#4f9c93',
|
|
202
|
+
clarity: 0.55, absorption: 0.13, foamAmount: 1.2, shoreDepth: 4, shoreFoam: 1.5,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'Estuary',
|
|
207
|
+
waterType: 'shore',
|
|
208
|
+
description: 'Silty, slow and shallow. Barely any reflection left once the suspended matter has lifted the colour.',
|
|
209
|
+
tags: ['silt', 'brown', 'shallow', 'river'],
|
|
210
|
+
settings: {
|
|
211
|
+
windSpeed: 3, deepColor: '#2c3a2a', shallowColor: '#6b6c46', sssColor: '#7a7a4a',
|
|
212
|
+
clarity: 0.9, absorption: 0.35, foamAmount: 0.05, shoreDepth: 2, specular: 0.7,
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'Lagoon',
|
|
217
|
+
waterType: 'shore',
|
|
218
|
+
description: 'Enclosed and almost flat, with the reef taking the swell outside it.',
|
|
219
|
+
tags: ['lagoon', 'calm', 'clear', 'blue'],
|
|
220
|
+
settings: {
|
|
221
|
+
windSpeed: 2.5, fetch: 6, swell: 0.05, choppiness: 0.4,
|
|
222
|
+
deepColor: '#0d6b8c', shallowColor: '#63e0d2', absorption: 0.05, clarity: 0.12,
|
|
223
|
+
foamAmount: 0, shoreDepth: 5, detailStrength: 0.7, detailSize: 1,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
// =============================================================================
|
|
228
|
+
// Registry
|
|
229
|
+
// =============================================================================
|
|
230
|
+
export const oceanSurfacePresets = [
|
|
231
|
+
...seaPresets,
|
|
232
|
+
...lakePresets,
|
|
233
|
+
...stormPresets,
|
|
234
|
+
...shorePresets,
|
|
235
|
+
];
|
|
236
|
+
export function getOceanPresetsForType(type) {
|
|
237
|
+
return oceanSurfacePresets.filter((p) => p.waterType === type);
|
|
238
|
+
}
|
|
239
|
+
export function getOceanPresetByName(name) {
|
|
240
|
+
return oceanSurfacePresets.find((p) => p.name === name);
|
|
241
|
+
}
|
|
242
|
+
export function searchOceanPresetsByTags(tags) {
|
|
243
|
+
const wanted = tags.map((t) => t.toLowerCase());
|
|
244
|
+
return oceanSurfacePresets.filter((p) => p.tags.some((t) => wanted.includes(t.toLowerCase())));
|
|
245
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TerrainSurfaceConfig, TerrainType } from '../types/terrainConfigs';
|
|
2
|
+
/**
|
|
3
|
+
* Presets for the procedural terrain system.
|
|
4
|
+
*
|
|
5
|
+
* They live here rather than in `core/src/presets` for the same reason the cloud
|
|
6
|
+
* presets do: they are `Partial<TerrainSurfaceConfig>`, and that type is declared
|
|
7
|
+
* in this package next to the shader that consumes it.
|
|
8
|
+
*
|
|
9
|
+
* Each entry is a *patch* over the type's defaults, not a full config, so a knob
|
|
10
|
+
* added to the renderer inherits its default everywhere instead of silently
|
|
11
|
+
* reverting to whatever a preset happened to be authored with — and switching
|
|
12
|
+
* between two presets never leaves a number behind from the previous one.
|
|
13
|
+
*
|
|
14
|
+
* The names are places and landform terms, because a name someone can picture is
|
|
15
|
+
* worth more in a dropdown than "Terrain 3".
|
|
16
|
+
*/
|
|
17
|
+
export interface TerrainPreset {
|
|
18
|
+
name: string;
|
|
19
|
+
terrainType: TerrainType;
|
|
20
|
+
description: string;
|
|
21
|
+
tags: string[];
|
|
22
|
+
settings: Partial<TerrainSurfaceConfig>;
|
|
23
|
+
}
|
|
24
|
+
export declare const terrainPresets: TerrainPreset[];
|
|
25
|
+
export declare function getTerrainPresetsForType(type: TerrainType): TerrainPreset[];
|
|
26
|
+
export declare function getTerrainPresetByName(name: string): TerrainPreset | undefined;
|
|
27
|
+
export declare function searchTerrainPresetsByTags(tags: string[]): TerrainPreset[];
|
|
28
|
+
//# sourceMappingURL=terrainPresets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrainPresets.d.ts","sourceRoot":"","sources":["../../src/presets/terrainPresets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEjF;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AAgSD,eAAO,MAAM,cAAc,EAAE,aAAa,EAKzC,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,EAAE,CAE3E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE9E;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAG1E"}
|