@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.
Files changed (259) hide show
  1. package/dist/components/Clouds.d.ts.map +1 -1
  2. package/dist/components/Clouds.js +0 -1
  3. package/dist/components/CloudsGenerator.d.ts +32 -0
  4. package/dist/components/CloudsGenerator.d.ts.map +1 -0
  5. package/dist/components/CloudsGenerator.js +58 -0
  6. package/dist/components/EnvironmentManager.d.ts +47 -5
  7. package/dist/components/EnvironmentManager.d.ts.map +1 -1
  8. package/dist/components/EnvironmentManager.js +35 -66
  9. package/dist/components/HdrEnvironment.d.ts +20 -0
  10. package/dist/components/HdrEnvironment.d.ts.map +1 -0
  11. package/dist/components/HdrEnvironment.js +44 -0
  12. package/dist/components/LandscapeBuilder.d.ts +23 -0
  13. package/dist/components/LandscapeBuilder.d.ts.map +1 -0
  14. package/dist/components/LandscapeBuilder.js +25 -0
  15. package/dist/components/LandscapeObject.d.ts +24 -0
  16. package/dist/components/LandscapeObject.d.ts.map +1 -0
  17. package/dist/components/LandscapeObject.js +27 -0
  18. package/dist/components/ObjectNode.d.ts.map +1 -1
  19. package/dist/components/ObjectNode.js +10 -0
  20. package/dist/components/OceanBuilder.d.ts +35 -0
  21. package/dist/components/OceanBuilder.d.ts.map +1 -0
  22. package/dist/components/OceanBuilder.js +53 -0
  23. package/dist/components/SceneBuilder.d.ts.map +1 -1
  24. package/dist/components/SkySystem.d.ts +27 -6
  25. package/dist/components/SkySystem.d.ts.map +1 -1
  26. package/dist/components/SkySystem.js +6 -5
  27. package/dist/components/SunLight.d.ts.map +1 -1
  28. package/dist/components/SunLight.js +4 -1
  29. package/dist/components/TerrainBuilder.d.ts +30 -0
  30. package/dist/components/TerrainBuilder.d.ts.map +1 -0
  31. package/dist/components/TerrainBuilder.js +44 -0
  32. package/dist/components/index.d.ts +17 -1
  33. package/dist/components/index.d.ts.map +1 -1
  34. package/dist/components/index.js +10 -0
  35. package/dist/components/landscape/LandscapeMesh.d.ts +18 -0
  36. package/dist/components/landscape/LandscapeMesh.d.ts.map +1 -0
  37. package/dist/components/landscape/LandscapeMesh.js +278 -0
  38. package/dist/components/landscape/index.d.ts +3 -0
  39. package/dist/components/landscape/index.d.ts.map +1 -0
  40. package/dist/components/landscape/index.js +1 -0
  41. package/dist/components/landscape/types.d.ts +13 -0
  42. package/dist/components/landscape/types.d.ts.map +1 -0
  43. package/dist/components/landscape/types.js +1 -0
  44. package/dist/components/terrain/Canyon.d.ts +23 -0
  45. package/dist/components/terrain/Canyon.d.ts.map +1 -0
  46. package/dist/components/terrain/Canyon.js +29 -0
  47. package/dist/components/terrain/Dunes.d.ts +22 -0
  48. package/dist/components/terrain/Dunes.d.ts.map +1 -0
  49. package/dist/components/terrain/Dunes.js +25 -0
  50. package/dist/components/terrain/Hills.d.ts +17 -0
  51. package/dist/components/terrain/Hills.d.ts.map +1 -0
  52. package/dist/components/terrain/Hills.js +20 -0
  53. package/dist/components/terrain/Mountains.d.ts +19 -0
  54. package/dist/components/terrain/Mountains.d.ts.map +1 -0
  55. package/dist/components/terrain/Mountains.js +22 -0
  56. package/dist/components/terrain/TerrainSurface.d.ts +22 -0
  57. package/dist/components/terrain/TerrainSurface.d.ts.map +1 -0
  58. package/dist/components/terrain/TerrainSurface.js +94 -0
  59. package/dist/components/terrain/index.d.ts +7 -0
  60. package/dist/components/terrain/index.d.ts.map +1 -0
  61. package/dist/components/terrain/index.js +7 -0
  62. package/dist/components/terrain/types.d.ts +17 -0
  63. package/dist/components/terrain/types.d.ts.map +1 -0
  64. package/dist/components/terrain/types.js +1 -0
  65. package/dist/components/volumetricClouds/Cirrus.d.ts +14 -0
  66. package/dist/components/volumetricClouds/Cirrus.d.ts.map +1 -0
  67. package/dist/components/volumetricClouds/Cirrus.js +13 -0
  68. package/dist/components/volumetricClouds/Cumulonimbus.d.ts +17 -0
  69. package/dist/components/volumetricClouds/Cumulonimbus.d.ts.map +1 -0
  70. package/dist/components/volumetricClouds/Cumulonimbus.js +20 -0
  71. package/dist/components/volumetricClouds/Cumulus.d.ts +14 -0
  72. package/dist/components/volumetricClouds/Cumulus.d.ts.map +1 -0
  73. package/dist/components/volumetricClouds/Cumulus.js +17 -0
  74. package/dist/components/volumetricClouds/Stratocumulus.d.ts +12 -0
  75. package/dist/components/volumetricClouds/Stratocumulus.d.ts.map +1 -0
  76. package/dist/components/volumetricClouds/Stratocumulus.js +16 -0
  77. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +42 -0
  78. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -0
  79. package/dist/components/volumetricClouds/VolumetricCloudsPass.js +298 -0
  80. package/dist/components/volumetricClouds/index.d.ts +8 -0
  81. package/dist/components/volumetricClouds/index.d.ts.map +1 -0
  82. package/dist/components/volumetricClouds/index.js +7 -0
  83. package/dist/components/volumetricClouds/types.d.ts +17 -0
  84. package/dist/components/volumetricClouds/types.d.ts.map +1 -0
  85. package/dist/components/volumetricClouds/types.js +1 -0
  86. package/dist/components/water/Host.d.ts +12 -0
  87. package/dist/components/water/Host.d.ts.map +1 -0
  88. package/dist/components/water/Host.js +12 -0
  89. package/dist/components/water/Lake.d.ts +18 -0
  90. package/dist/components/water/Lake.d.ts.map +1 -0
  91. package/dist/components/water/Lake.js +21 -0
  92. package/dist/components/water/OceanSurface.d.ts +27 -0
  93. package/dist/components/water/OceanSurface.d.ts.map +1 -0
  94. package/dist/components/water/OceanSurface.js +60 -0
  95. package/dist/components/water/Sea.d.ts +18 -0
  96. package/dist/components/water/Sea.d.ts.map +1 -0
  97. package/dist/components/water/Sea.js +17 -0
  98. package/dist/components/water/Shore.d.ts +16 -0
  99. package/dist/components/water/Shore.d.ts.map +1 -0
  100. package/dist/components/water/Shore.js +15 -0
  101. package/dist/components/water/Storm.d.ts +14 -0
  102. package/dist/components/water/Storm.d.ts.map +1 -0
  103. package/dist/components/water/Storm.js +13 -0
  104. package/dist/components/water/WaterBody.d.ts +31 -0
  105. package/dist/components/water/WaterBody.d.ts.map +1 -0
  106. package/dist/components/water/WaterBody.js +76 -0
  107. package/dist/components/water/index.d.ts +9 -0
  108. package/dist/components/water/index.d.ts.map +1 -0
  109. package/dist/components/water/index.js +11 -0
  110. package/dist/components/water/types.d.ts +20 -0
  111. package/dist/components/water/types.d.ts.map +1 -0
  112. package/dist/components/water/types.js +1 -0
  113. package/dist/constants.d.ts.map +1 -1
  114. package/dist/constants.js +9 -0
  115. package/dist/hooks/index.d.ts +24 -1
  116. package/dist/hooks/index.d.ts.map +1 -1
  117. package/dist/hooks/index.js +12 -0
  118. package/dist/hooks/useClipmap.d.ts +71 -0
  119. package/dist/hooks/useClipmap.d.ts.map +1 -0
  120. package/dist/hooks/useClipmap.js +81 -0
  121. package/dist/hooks/useCloudLive.d.ts +29 -0
  122. package/dist/hooks/useCloudLive.d.ts.map +1 -0
  123. package/dist/hooks/useCloudLive.js +43 -0
  124. package/dist/hooks/useCloudNoise.d.ts +28 -0
  125. package/dist/hooks/useCloudNoise.d.ts.map +1 -0
  126. package/dist/hooks/useCloudNoise.js +128 -0
  127. package/dist/hooks/useCloudSun.d.ts +49 -0
  128. package/dist/hooks/useCloudSun.d.ts.map +1 -0
  129. package/dist/hooks/useCloudSun.js +84 -0
  130. package/dist/hooks/useCubeCamera.d.ts +27 -9
  131. package/dist/hooks/useCubeCamera.d.ts.map +1 -1
  132. package/dist/hooks/useCubeCamera.js +28 -70
  133. package/dist/hooks/useEnvironmentProbe.d.ts +32 -0
  134. package/dist/hooks/useEnvironmentProbe.d.ts.map +1 -0
  135. package/dist/hooks/useEnvironmentProbe.js +35 -0
  136. package/dist/hooks/useFrameRenderer.d.ts +15 -0
  137. package/dist/hooks/useFrameRenderer.d.ts.map +1 -0
  138. package/dist/hooks/useFrameRenderer.js +23 -0
  139. package/dist/hooks/useLandscapeLive.d.ts +29 -0
  140. package/dist/hooks/useLandscapeLive.d.ts.map +1 -0
  141. package/dist/hooks/useLandscapeLive.js +41 -0
  142. package/dist/hooks/useLandscapeMaps.d.ts +32 -0
  143. package/dist/hooks/useLandscapeMaps.d.ts.map +1 -0
  144. package/dist/hooks/useLandscapeMaps.js +138 -0
  145. package/dist/hooks/useOceanLive.d.ts +29 -0
  146. package/dist/hooks/useOceanLive.d.ts.map +1 -0
  147. package/dist/hooks/useOceanLive.js +38 -0
  148. package/dist/hooks/useOceanMaterial.d.ts +39 -0
  149. package/dist/hooks/useOceanMaterial.d.ts.map +1 -0
  150. package/dist/hooks/useOceanMaterial.js +65 -0
  151. package/dist/hooks/useTerrainClipmap.d.ts +12 -0
  152. package/dist/hooks/useTerrainClipmap.d.ts.map +1 -0
  153. package/dist/hooks/useTerrainClipmap.js +10 -0
  154. package/dist/hooks/useTerrainLive.d.ts +34 -0
  155. package/dist/hooks/useTerrainLive.d.ts.map +1 -0
  156. package/dist/hooks/useTerrainLive.js +45 -0
  157. package/dist/index.d.ts +26 -0
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.js +16 -0
  160. package/dist/presets/landscapePresets.d.ts +60 -0
  161. package/dist/presets/landscapePresets.d.ts.map +1 -0
  162. package/dist/presets/landscapePresets.js +194 -0
  163. package/dist/presets/landscapeTypes.d.ts +195 -0
  164. package/dist/presets/landscapeTypes.d.ts.map +1 -0
  165. package/dist/presets/landscapeTypes.js +315 -0
  166. package/dist/presets/oceanSurfacePresets.d.ts +33 -0
  167. package/dist/presets/oceanSurfacePresets.d.ts.map +1 -0
  168. package/dist/presets/oceanSurfacePresets.js +245 -0
  169. package/dist/presets/terrainPresets.d.ts +28 -0
  170. package/dist/presets/terrainPresets.d.ts.map +1 -0
  171. package/dist/presets/terrainPresets.js +293 -0
  172. package/dist/presets/volumetricCloudPresets.d.ts +38 -0
  173. package/dist/presets/volumetricCloudPresets.d.ts.map +1 -0
  174. package/dist/presets/volumetricCloudPresets.js +480 -0
  175. package/dist/shaders/clouds/CirrusMaterial.d.ts +84 -0
  176. package/dist/shaders/clouds/CirrusMaterial.d.ts.map +1 -0
  177. package/dist/shaders/clouds/CirrusMaterial.js +167 -0
  178. package/dist/shaders/clouds/CloudCompositeMaterial.d.ts +20 -0
  179. package/dist/shaders/clouds/CloudCompositeMaterial.d.ts.map +1 -0
  180. package/dist/shaders/clouds/CloudCompositeMaterial.js +82 -0
  181. package/dist/shaders/clouds/CloudResolveMaterial.d.ts +22 -0
  182. package/dist/shaders/clouds/CloudResolveMaterial.d.ts.map +1 -0
  183. package/dist/shaders/clouds/CloudResolveMaterial.js +77 -0
  184. package/dist/shaders/clouds/CloudVolumeMaterial.d.ts +143 -0
  185. package/dist/shaders/clouds/CloudVolumeMaterial.d.ts.map +1 -0
  186. package/dist/shaders/clouds/CloudVolumeMaterial.js +249 -0
  187. package/dist/shaders/clouds/SkyBackgroundMaterial.d.ts +21 -0
  188. package/dist/shaders/clouds/SkyBackgroundMaterial.d.ts.map +1 -0
  189. package/dist/shaders/clouds/SkyBackgroundMaterial.js +42 -0
  190. package/dist/shaders/glsl/cloudCore.glsl.d.ts +24 -0
  191. package/dist/shaders/glsl/cloudCore.glsl.d.ts.map +1 -0
  192. package/dist/shaders/glsl/cloudCore.glsl.js +348 -0
  193. package/dist/shaders/glsl/landscapeCore.glsl.d.ts +49 -0
  194. package/dist/shaders/glsl/landscapeCore.glsl.d.ts.map +1 -0
  195. package/dist/shaders/glsl/landscapeCore.glsl.js +518 -0
  196. package/dist/shaders/glsl/noiseBake.glsl.d.ts +30 -0
  197. package/dist/shaders/glsl/noiseBake.glsl.d.ts.map +1 -0
  198. package/dist/shaders/glsl/noiseBake.glsl.js +164 -0
  199. package/dist/shaders/glsl/oceanCore.glsl.d.ts +52 -0
  200. package/dist/shaders/glsl/oceanCore.glsl.d.ts.map +1 -0
  201. package/dist/shaders/glsl/oceanCore.glsl.js +421 -0
  202. package/dist/shaders/glsl/terrainCore.glsl.d.ts +78 -0
  203. package/dist/shaders/glsl/terrainCore.glsl.d.ts.map +1 -0
  204. package/dist/shaders/glsl/terrainCore.glsl.js +625 -0
  205. package/dist/shaders/landscape/LandscapeMaterial.d.ts +73 -0
  206. package/dist/shaders/landscape/LandscapeMaterial.d.ts.map +1 -0
  207. package/dist/shaders/landscape/LandscapeMaterial.js +136 -0
  208. package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +57 -0
  209. package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -0
  210. package/dist/shaders/ocean/OceanSurfaceMaterial.js +268 -0
  211. package/dist/shaders/terrain/TerrainMaterial.d.ts +80 -0
  212. package/dist/shaders/terrain/TerrainMaterial.d.ts.map +1 -0
  213. package/dist/shaders/terrain/TerrainMaterial.js +291 -0
  214. package/dist/types/cloudConfigs.d.ts +244 -0
  215. package/dist/types/cloudConfigs.d.ts.map +1 -0
  216. package/dist/types/cloudConfigs.js +282 -0
  217. package/dist/types/index.d.ts +8 -0
  218. package/dist/types/index.d.ts.map +1 -1
  219. package/dist/types/index.js +4 -1
  220. package/dist/types/landscapeConfigs.d.ts +218 -0
  221. package/dist/types/landscapeConfigs.d.ts.map +1 -0
  222. package/dist/types/landscapeConfigs.js +256 -0
  223. package/dist/types/oceanConfigs.d.ts +290 -0
  224. package/dist/types/oceanConfigs.d.ts.map +1 -0
  225. package/dist/types/oceanConfigs.js +380 -0
  226. package/dist/types/terrainConfigs.d.ts +251 -0
  227. package/dist/types/terrainConfigs.d.ts.map +1 -0
  228. package/dist/types/terrainConfigs.js +292 -0
  229. package/dist/utils/cloudUniforms.d.ts +14 -0
  230. package/dist/utils/cloudUniforms.d.ts.map +1 -0
  231. package/dist/utils/cloudUniforms.js +122 -0
  232. package/dist/utils/frameRenderer.d.ts +33 -0
  233. package/dist/utils/frameRenderer.d.ts.map +1 -0
  234. package/dist/utils/frameRenderer.js +24 -0
  235. package/dist/utils/handleCloudsAnimations.d.ts +16 -0
  236. package/dist/utils/handleCloudsAnimations.d.ts.map +1 -0
  237. package/dist/utils/handleCloudsAnimations.js +64 -0
  238. package/dist/utils/landscapeGeometry.d.ts +61 -0
  239. package/dist/utils/landscapeGeometry.d.ts.map +1 -0
  240. package/dist/utils/landscapeGeometry.js +126 -0
  241. package/dist/utils/landscapeHeight.d.ts +44 -0
  242. package/dist/utils/landscapeHeight.d.ts.map +1 -0
  243. package/dist/utils/landscapeHeight.js +65 -0
  244. package/dist/utils/landscapeTextures.d.ts +94 -0
  245. package/dist/utils/landscapeTextures.d.ts.map +1 -0
  246. package/dist/utils/landscapeTextures.js +290 -0
  247. package/dist/utils/landscapeUniforms.d.ts +20 -0
  248. package/dist/utils/landscapeUniforms.d.ts.map +1 -0
  249. package/dist/utils/landscapeUniforms.js +61 -0
  250. package/dist/utils/oceanUniforms.d.ts +47 -0
  251. package/dist/utils/oceanUniforms.d.ts.map +1 -0
  252. package/dist/utils/oceanUniforms.js +216 -0
  253. package/dist/utils/rtin.d.ts +63 -0
  254. package/dist/utils/rtin.d.ts.map +1 -0
  255. package/dist/utils/rtin.js +202 -0
  256. package/dist/utils/terrainUniforms.d.ts +14 -0
  257. package/dist/utils/terrainUniforms.d.ts.map +1 -0
  258. package/dist/utils/terrainUniforms.js +196 -0
  259. 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"}