super-three 0.184.0 → 0.185.0

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 (366) hide show
  1. package/build/three.cjs +1260 -927
  2. package/build/three.core.js +1104 -829
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +156 -98
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +11 -4
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +7538 -3367
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +7538 -3366
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +3 -0
  13. package/examples/jsm/controls/ArcballControls.js +6 -2
  14. package/examples/jsm/controls/FirstPersonControls.js +79 -42
  15. package/examples/jsm/controls/TransformControls.js +68 -15
  16. package/examples/jsm/csm/CSMFrustum.js +31 -6
  17. package/examples/jsm/csm/CSMShadowNode.js +4 -1
  18. package/examples/jsm/effects/AsciiEffect.js +14 -1
  19. package/examples/jsm/exporters/DRACOExporter.js +27 -6
  20. package/examples/jsm/exporters/GLTFExporter.js +114 -12
  21. package/examples/jsm/exporters/PLYExporter.js +286 -73
  22. package/examples/jsm/exporters/USDZExporter.js +347 -112
  23. package/examples/jsm/generators/CityGenerator.js +346 -0
  24. package/examples/jsm/generators/ForestGenerator.js +347 -0
  25. package/examples/jsm/generators/TerrainGenerator.js +504 -0
  26. package/examples/jsm/generators/TreeGenerator.js +377 -0
  27. package/examples/jsm/generators/city/SidewalkGenerator.js +253 -0
  28. package/examples/jsm/generators/city/SkyscraperGenerator.js +1357 -0
  29. package/examples/jsm/geometries/LoftGeometry.js +355 -0
  30. package/examples/jsm/helpers/LightProbeGridHelper.js +1 -1
  31. package/examples/jsm/helpers/LightProbeHelper.js +5 -4
  32. package/examples/jsm/helpers/ViewHelper.js +16 -6
  33. package/examples/jsm/inspector/Inspector.js +53 -15
  34. package/examples/jsm/inspector/RendererInspector.js +152 -36
  35. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +1 -1
  36. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -1
  37. package/examples/jsm/inspector/tabs/Console.js +200 -18
  38. package/examples/jsm/inspector/tabs/Memory.js +8 -0
  39. package/examples/jsm/inspector/tabs/Parameters.js +64 -4
  40. package/examples/jsm/inspector/tabs/Performance.js +21 -6
  41. package/examples/jsm/inspector/tabs/Settings.js +51 -9
  42. package/examples/jsm/inspector/tabs/Timeline.js +178 -93
  43. package/examples/jsm/inspector/tabs/Viewer.js +628 -16
  44. package/examples/jsm/inspector/ui/Graph.js +162 -25
  45. package/examples/jsm/inspector/ui/Item.js +92 -13
  46. package/examples/jsm/inspector/ui/List.js +1 -1
  47. package/examples/jsm/inspector/ui/Profiler.js +90 -45
  48. package/examples/jsm/inspector/ui/Style.js +1788 -1401
  49. package/examples/jsm/inspector/ui/Tab.js +5 -3
  50. package/examples/jsm/inspector/ui/Values.js +71 -6
  51. package/examples/jsm/inspector/ui/utils.js +130 -10
  52. package/examples/jsm/libs/basis/README.md +0 -1
  53. package/examples/jsm/libs/demuxer_mp4.js +3 -3
  54. package/examples/jsm/libs/draco/README.md +0 -1
  55. package/examples/jsm/libs/meshopt_clusterizer.module.js +421 -0
  56. package/examples/jsm/libs/meshopt_simplifier.module.js +627 -0
  57. package/examples/jsm/libs/mikktspace.module.js +34 -9
  58. package/examples/jsm/lighting/ClusteredLighting.js +55 -0
  59. package/examples/jsm/lighting/LightProbeGrid.js +106 -76
  60. package/examples/jsm/lines/LineMaterial.js +38 -15
  61. package/examples/jsm/lines/LineSegments2.js +8 -0
  62. package/examples/jsm/lines/webgpu/LineSegments2.js +8 -0
  63. package/examples/jsm/loaders/3DMLoader.js +1 -1
  64. package/examples/jsm/loaders/DRACOLoader.js +46 -13
  65. package/examples/jsm/loaders/EXRLoader.js +27 -55
  66. package/examples/jsm/loaders/HDRLoader.js +6 -28
  67. package/examples/jsm/loaders/KTX2Loader.js +31 -12
  68. package/examples/jsm/loaders/LDrawLoader.js +8 -8
  69. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  70. package/examples/jsm/loaders/LUTCubeLoader.js +2 -2
  71. package/examples/jsm/loaders/LWOLoader.js +4 -0
  72. package/examples/jsm/loaders/LottieLoader.js +1 -1
  73. package/examples/jsm/loaders/MaterialXLoader.js +31 -9
  74. package/examples/jsm/loaders/NRRDLoader.js +3 -3
  75. package/examples/jsm/loaders/PCDLoader.js +7 -7
  76. package/examples/jsm/loaders/PLYLoader.js +218 -55
  77. package/examples/jsm/loaders/SVGLoader.js +547 -495
  78. package/examples/jsm/loaders/TTFLoader.js +1 -1
  79. package/examples/jsm/loaders/USDLoader.js +33 -9
  80. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  81. package/examples/jsm/loaders/usd/USDAParser.js +93 -20
  82. package/examples/jsm/loaders/usd/USDCParser.js +1 -1
  83. package/examples/jsm/loaders/usd/USDComposer.js +52 -19
  84. package/examples/jsm/misc/TileCreasedNormalsPlugin.js +270 -0
  85. package/examples/jsm/misc/Volume.js +2 -2
  86. package/examples/jsm/objects/GroundedSkybox.js +1 -1
  87. package/examples/jsm/objects/Reflector.js +2 -3
  88. package/examples/jsm/objects/Water2Mesh.js +1 -1
  89. package/examples/jsm/physics/AmmoPhysics.js +15 -8
  90. package/examples/jsm/physics/RapierPhysics.js +27 -2
  91. package/examples/jsm/shaders/VolumeShader.js +31 -44
  92. package/examples/jsm/transpiler/GLSLDecoder.js +6 -6
  93. package/examples/jsm/transpiler/Linker.js +1 -1
  94. package/examples/jsm/tsl/display/BloomNode.js +59 -19
  95. package/examples/jsm/tsl/display/DepthOfFieldNode.js +2 -2
  96. package/examples/jsm/tsl/display/FXAANode.js +11 -12
  97. package/examples/jsm/tsl/display/GTAONode.js +34 -13
  98. package/examples/jsm/tsl/display/GodraysNode.js +1 -1
  99. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +560 -0
  100. package/examples/jsm/tsl/display/PixelationPassNode.js +2 -2
  101. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +912 -0
  102. package/examples/jsm/tsl/display/SSAAPassNode.js +13 -25
  103. package/examples/jsm/tsl/display/SSGINode.js +89 -39
  104. package/examples/jsm/tsl/display/SSRNode.js +829 -132
  105. package/examples/jsm/tsl/display/SSSNode.js +2 -2
  106. package/examples/jsm/tsl/display/TemporalReprojectNode.js +1023 -0
  107. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +622 -0
  108. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +1 -1
  109. package/examples/jsm/tsl/math/curlNoise.js +107 -0
  110. package/examples/jsm/tsl/shadows/TileShadowNode.js +1 -1
  111. package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +3 -3
  112. package/examples/jsm/tsl/utils/GroundedSkybox.js +62 -0
  113. package/examples/jsm/tsl/utils/RNoise.js +51 -0
  114. package/examples/jsm/tsl/utils/SpecularHelpers.js +325 -0
  115. package/examples/jsm/utils/BufferGeometryUtils.js +126 -59
  116. package/examples/jsm/utils/GeometryCompressionUtils.js +1 -1
  117. package/examples/jsm/utils/SceneOptimizer.js +1 -1
  118. package/examples/jsm/webxr/ARButton.js +1 -1
  119. package/examples/jsm/webxr/WebGLXRFallback.js +89 -0
  120. package/examples/jsm/webxr/XRControllerModelFactory.js +2 -2
  121. package/package.json +7 -7
  122. package/src/Three.TSL.js +10 -3
  123. package/src/Three.WebGPU.js +4 -0
  124. package/src/animation/AnimationAction.js +15 -11
  125. package/src/animation/AnimationClip.js +0 -139
  126. package/src/animation/KeyframeTrack.js +2 -2
  127. package/src/animation/PropertyBinding.js +2 -2
  128. package/src/cameras/Camera.js +2 -2
  129. package/src/cameras/StereoCamera.js +5 -2
  130. package/src/constants.js +1 -1
  131. package/src/core/BufferGeometry.js +29 -7
  132. package/src/core/Object3D.js +17 -7
  133. package/src/core/Raycaster.js +1 -1
  134. package/src/core/RenderTarget.js +15 -2
  135. package/src/extras/PMREMGenerator.js +6 -4
  136. package/src/extras/TextureUtils.js +1 -1
  137. package/src/extras/core/ShapePath.js +149 -160
  138. package/src/geometries/SphereGeometry.js +8 -3
  139. package/src/helpers/DirectionalLightHelper.js +2 -0
  140. package/src/helpers/HemisphereLightHelper.js +2 -0
  141. package/src/helpers/PointLightHelper.js +2 -0
  142. package/src/helpers/SpotLightHelper.js +1 -1
  143. package/src/loaders/DataTextureLoader.js +69 -38
  144. package/src/loaders/LoadingManager.js +5 -0
  145. package/src/loaders/MaterialLoader.js +36 -266
  146. package/src/loaders/ObjectLoader.js +3 -1
  147. package/src/materials/LineBasicMaterial.js +4 -0
  148. package/src/materials/Material.js +196 -1
  149. package/src/materials/MeshBasicMaterial.js +24 -0
  150. package/src/materials/MeshDepthMaterial.js +10 -0
  151. package/src/materials/MeshDistanceMaterial.js +10 -0
  152. package/src/materials/MeshLambertMaterial.js +40 -1
  153. package/src/materials/MeshMatcapMaterial.js +25 -1
  154. package/src/materials/MeshNormalMaterial.js +9 -1
  155. package/src/materials/MeshPhongMaterial.js +40 -1
  156. package/src/materials/MeshPhysicalMaterial.js +38 -0
  157. package/src/materials/MeshStandardMaterial.js +42 -1
  158. package/src/materials/MeshToonMaterial.js +34 -1
  159. package/src/materials/PointsMaterial.js +7 -0
  160. package/src/materials/ShaderMaterial.js +86 -0
  161. package/src/materials/SpriteMaterial.js +7 -0
  162. package/src/materials/nodes/Line2NodeMaterial.js +378 -322
  163. package/src/materials/nodes/MeshBasicNodeMaterial.js +2 -2
  164. package/src/materials/nodes/MeshNormalNodeMaterial.js +2 -2
  165. package/src/materials/nodes/MeshPhongNodeMaterial.js +0 -9
  166. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +0 -30
  167. package/src/materials/nodes/MeshSSSNodeMaterial.js +0 -13
  168. package/src/materials/nodes/MeshStandardNodeMaterial.js +0 -11
  169. package/src/materials/nodes/NodeMaterial.js +115 -71
  170. package/src/materials/nodes/SpriteNodeMaterial.js +0 -10
  171. package/src/materials/nodes/manager/NodeMaterialObserver.js +49 -20
  172. package/src/math/Box3.js +5 -0
  173. package/src/math/FrustumArray.js +103 -133
  174. package/src/math/Interpolant.js +1 -1
  175. package/src/math/MathUtils.js +2 -2
  176. package/src/math/Matrix3.js +11 -0
  177. package/src/math/Matrix4.js +28 -3
  178. package/src/math/Vector2.js +2 -2
  179. package/src/math/Vector3.js +2 -2
  180. package/src/math/Vector4.js +2 -2
  181. package/src/math/interpolants/BezierInterpolant.js +4 -6
  182. package/src/nodes/Nodes.js +2 -5
  183. package/src/nodes/TSL.js +8 -6
  184. package/src/nodes/accessors/Arrays.js +4 -4
  185. package/src/nodes/accessors/Batch.js +108 -0
  186. package/src/nodes/accessors/Bitangent.js +2 -2
  187. package/src/nodes/accessors/BufferAttributeNode.js +13 -2
  188. package/src/nodes/accessors/Camera.js +7 -7
  189. package/src/nodes/accessors/ClippingNode.js +1 -1
  190. package/src/nodes/accessors/Instance.js +264 -0
  191. package/src/nodes/accessors/MaterialNode.js +18 -2
  192. package/src/nodes/accessors/MaterialProperties.js +4 -3
  193. package/src/nodes/accessors/{MorphNode.js → Morph.js} +99 -112
  194. package/src/nodes/accessors/Normal.js +13 -13
  195. package/src/nodes/accessors/Position.js +5 -1
  196. package/src/nodes/accessors/ReferenceNode.js +1 -0
  197. package/src/nodes/accessors/ReflectVector.js +3 -3
  198. package/src/nodes/accessors/SceneProperties.js +1 -1
  199. package/src/nodes/accessors/Skinning.js +263 -0
  200. package/src/nodes/accessors/StorageBufferNode.js +2 -2
  201. package/src/nodes/accessors/StorageTexture3DNode.js +100 -0
  202. package/src/nodes/accessors/StorageTextureNode.js +39 -7
  203. package/src/nodes/accessors/Tangent.js +4 -4
  204. package/src/nodes/accessors/TextureNode.js +60 -5
  205. package/src/nodes/code/FunctionNode.js +2 -16
  206. package/src/nodes/core/MRTNode.js +7 -2
  207. package/src/nodes/core/Node.js +39 -2
  208. package/src/nodes/core/NodeBuilder.js +201 -41
  209. package/src/nodes/core/NodeUtils.js +13 -13
  210. package/src/nodes/core/OutputStructNode.js +1 -1
  211. package/src/nodes/core/OverrideContextNode.js +153 -0
  212. package/src/nodes/core/PropertyNode.js +51 -5
  213. package/src/nodes/core/StackNode.js +56 -34
  214. package/src/nodes/core/StructNode.js +4 -6
  215. package/src/nodes/core/StructTypeNode.js +6 -6
  216. package/src/nodes/core/VarNode.js +8 -0
  217. package/src/nodes/core/VaryingNode.js +12 -2
  218. package/src/nodes/display/BlendModes.js +1 -41
  219. package/src/nodes/display/BumpMapNode.js +6 -1
  220. package/src/nodes/display/ColorAdjustment.js +10 -9
  221. package/src/nodes/display/FrontFacingNode.js +38 -9
  222. package/src/nodes/display/NormalMapNode.js +2 -2
  223. package/src/nodes/display/PassNode.js +35 -43
  224. package/src/nodes/display/PremultiplyAlphaFunctions.js +39 -0
  225. package/src/nodes/display/RenderOutputNode.js +12 -3
  226. package/src/nodes/functions/VolumetricLightingModel.js +40 -7
  227. package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
  228. package/src/nodes/lighting/EnvironmentNode.js +2 -2
  229. package/src/nodes/lighting/IESSpotLightNode.js +40 -2
  230. package/src/nodes/lighting/LightingContextNode.js +10 -2
  231. package/src/nodes/lighting/LightsNode.js +90 -37
  232. package/src/nodes/lighting/PointShadowNode.js +6 -1
  233. package/src/nodes/lighting/ShadowFilterNode.js +21 -52
  234. package/src/nodes/lighting/ShadowNode.js +34 -14
  235. package/src/nodes/materialx/lib/mx_noise.js +2 -2
  236. package/src/nodes/math/ConditionalNode.js +3 -3
  237. package/src/nodes/math/MathNode.js +39 -11
  238. package/src/nodes/math/OperatorNode.js +23 -23
  239. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  240. package/src/nodes/pmrem/PMREMNode.js +33 -2
  241. package/src/nodes/tsl/TSLCore.js +63 -18
  242. package/src/nodes/utils/EquirectUV.js +30 -5
  243. package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
  244. package/src/nodes/utils/Packing.js +35 -4
  245. package/src/nodes/utils/RTTNode.js +40 -24
  246. package/src/nodes/utils/ReflectorNode.js +1 -0
  247. package/src/nodes/utils/StorageArrayElementNode.js +1 -1
  248. package/src/objects/BatchedMesh.js +22 -14
  249. package/src/objects/InstancedMesh.js +0 -11
  250. package/src/objects/Skeleton.js +0 -9
  251. package/src/renderers/WebGLRenderer.js +19 -15
  252. package/src/renderers/common/Backend.js +49 -5
  253. package/src/renderers/common/Bindings.js +114 -45
  254. package/src/renderers/common/Buffer.js +9 -0
  255. package/src/renderers/common/ClippingContext.js +10 -2
  256. package/src/renderers/common/Info.js +63 -22
  257. package/src/renderers/common/Lighting.js +53 -5
  258. package/src/renderers/common/RenderList.js +41 -4
  259. package/src/renderers/common/RenderObject.js +73 -13
  260. package/src/renderers/common/Renderer.js +281 -108
  261. package/src/renderers/common/Sampler.js +16 -48
  262. package/src/renderers/common/Textures.js +32 -5
  263. package/src/renderers/common/TimestampQueryPool.js +1 -1
  264. package/src/renderers/common/UniformsGroup.js +31 -9
  265. package/src/renderers/common/XRManager.js +340 -22
  266. package/src/renderers/common/extras/PMREMGenerator.js +15 -38
  267. package/src/renderers/common/nodes/NodeBuilderState.js +9 -1
  268. package/src/renderers/common/nodes/NodeLibrary.js +4 -4
  269. package/src/renderers/common/nodes/NodeManager.js +63 -14
  270. package/src/renderers/common/nodes/NodeUniformBuffer.js +13 -0
  271. package/src/renderers/shaders/ShaderChunk/common.glsl.js +13 -4
  272. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +0 -6
  273. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  274. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  275. package/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js +1 -1
  276. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  277. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +1 -1
  278. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -2
  279. package/src/renderers/shaders/ShaderChunk/normal_vertex.glsl.js +6 -0
  280. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +1 -1
  281. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  282. package/src/renderers/shaders/ShaderLib/distance.glsl.js +1 -1
  283. package/src/renderers/webgl/WebGLOutput.js +2 -1
  284. package/src/renderers/webgl/WebGLProgram.js +5 -4
  285. package/src/renderers/webgl/WebGLPrograms.js +12 -5
  286. package/src/renderers/webgl/WebGLRenderLists.js +9 -1
  287. package/src/renderers/webgl/WebGLShaderCache.js +5 -11
  288. package/src/renderers/webgl/WebGLTextures.js +20 -7
  289. package/src/renderers/webgl/WebGLUniformsGroups.js +66 -38
  290. package/src/renderers/webgl-fallback/WebGLBackend.js +84 -25
  291. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +138 -8
  292. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +1 -1
  293. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -22
  294. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +4 -2
  295. package/src/renderers/webgpu/WebGPUBackend.js +480 -169
  296. package/src/renderers/webgpu/descriptors/GPUBindGroupDescriptor.js +48 -0
  297. package/src/renderers/webgpu/descriptors/GPUBufferDescriptor.js +57 -0
  298. package/src/renderers/webgpu/descriptors/GPUCommandEncoderDescriptor.js +30 -0
  299. package/src/renderers/webgpu/descriptors/GPUComputePassDescriptor.js +38 -0
  300. package/src/renderers/webgpu/descriptors/GPUComputePipelineDescriptor.js +48 -0
  301. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageDestInfo.js +47 -0
  302. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageSourceInfo.js +50 -0
  303. package/src/renderers/webgpu/descriptors/GPUExtent3D.js +51 -0
  304. package/src/renderers/webgpu/descriptors/GPUPipelineLayoutDescriptor.js +39 -0
  305. package/src/renderers/webgpu/descriptors/GPUQuerySetDescriptor.js +47 -0
  306. package/src/renderers/webgpu/descriptors/GPURenderBundleEncoderDescriptor.js +74 -0
  307. package/src/renderers/webgpu/descriptors/GPURenderPassColorAttachment.js +72 -0
  308. package/src/renderers/webgpu/descriptors/GPURenderPassDepthStencilAttachment.js +99 -0
  309. package/src/renderers/webgpu/descriptors/GPURenderPassDescriptor.js +72 -0
  310. package/src/renderers/webgpu/descriptors/GPURenderPassTimestampWrites.js +49 -0
  311. package/src/renderers/webgpu/descriptors/GPURenderPipelineDescriptor.js +130 -0
  312. package/src/renderers/webgpu/descriptors/GPUSamplerDescriptor.js +119 -0
  313. package/src/renderers/webgpu/descriptors/GPUShaderModuleDescriptor.js +46 -0
  314. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferInfo.js +57 -0
  315. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferLayout.js +48 -0
  316. package/src/renderers/webgpu/descriptors/GPUTexelCopyTextureInfo.js +61 -0
  317. package/src/renderers/webgpu/descriptors/GPUTextureDescriptor.js +99 -0
  318. package/src/renderers/webgpu/descriptors/GPUTextureViewDescriptor.js +108 -0
  319. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -1
  320. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +164 -7
  321. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +1 -1
  322. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +98 -38
  323. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -68
  324. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +164 -69
  325. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +158 -95
  326. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +297 -141
  327. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +33 -18
  328. package/src/renderers/webgpu/utils/WebGPUUtils.js +38 -3
  329. package/src/textures/DepthTexture.js +1 -1
  330. package/src/textures/ExternalTexture.js +0 -3
  331. package/examples/fonts/LICENSE +0 -13
  332. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  333. package/examples/fonts/MPLUSRounded1c/OFL.txt +0 -91
  334. package/examples/fonts/README.md +0 -11
  335. package/examples/fonts/droid/NOTICE +0 -190
  336. package/examples/fonts/droid/README.txt +0 -18
  337. package/examples/fonts/droid/droid_sans_bold.typeface.json +0 -1
  338. package/examples/fonts/droid/droid_sans_mono_regular.typeface.json +0 -1
  339. package/examples/fonts/droid/droid_sans_regular.typeface.json +0 -1
  340. package/examples/fonts/droid/droid_serif_bold.typeface.json +0 -1
  341. package/examples/fonts/droid/droid_serif_regular.typeface.json +0 -1
  342. package/examples/fonts/gentilis_bold.typeface.json +0 -1
  343. package/examples/fonts/gentilis_regular.typeface.json +0 -1
  344. package/examples/fonts/helvetiker_bold.typeface.json +0 -1
  345. package/examples/fonts/helvetiker_regular.typeface.json +0 -1
  346. package/examples/fonts/optimer_bold.typeface.json +0 -1
  347. package/examples/fonts/optimer_regular.typeface.json +0 -1
  348. package/examples/fonts/ttf/README.md +0 -9
  349. package/examples/fonts/ttf/kenpixel.ttf +0 -0
  350. package/examples/jsm/inspector/extensions/extensions.json +0 -6
  351. package/examples/jsm/libs/ammo.wasm.js +0 -822
  352. package/examples/jsm/libs/ammo.wasm.wasm +0 -0
  353. package/examples/jsm/libs/draco/draco_encoder.js +0 -33
  354. package/examples/jsm/libs/draco/gltf/draco_encoder.js +0 -33
  355. package/examples/jsm/libs/lottie_canvas.module.js +0 -14849
  356. package/examples/jsm/libs/opentype.module.js +0 -14506
  357. package/examples/jsm/libs/rhino3dm/rhino3dm.js +0 -21
  358. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +0 -16
  359. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  360. package/examples/jsm/lighting/TiledLighting.js +0 -42
  361. package/examples/jsm/tsl/display/AnamorphicNode.js +0 -293
  362. package/examples/jsm/tsl/lighting/TiledLightsNode.js +0 -442
  363. package/src/nodes/accessors/BatchNode.js +0 -163
  364. package/src/nodes/accessors/InstanceNode.js +0 -349
  365. package/src/nodes/accessors/InstancedMeshNode.js +0 -50
  366. package/src/nodes/accessors/SkinningNode.js +0 -328
@@ -0,0 +1,504 @@
1
+ import {
2
+ BufferGeometry,
3
+ Float32BufferAttribute,
4
+ Group,
5
+ Mesh
6
+ } from 'three';
7
+
8
+ import { MeshStandardNodeMaterial } from 'three/webgpu';
9
+ import { cameraPosition, color, float, Fn, If, mix, mx_noise_float, normalView, normalWorld, positionView, positionWorld, saturation, smoothstep, uniform } from 'three/tsl';
10
+
11
+ import { ImprovedNoise } from '../math/ImprovedNoise.js';
12
+
13
+ /**
14
+ * Bakes a procedural mountain range into a single {@link THREE.BufferGeometry} and
15
+ * returns a `THREE.Group` ready to add to a scene.
16
+ *
17
+ * The heightfield is a derivative-damped fractal sum ( Quilez's fake erosion ): each
18
+ * octave is suppressed where the running slope is already steep, concentrating detail
19
+ * into weathered ridgelines, and a low-frequency domain warp makes those ridges
20
+ * meander. A few passes of thermal ( talus ) erosion then relax any slope past the
21
+ * angle of repose, settling the fractal's needle-spikes into real crests.
22
+ *
23
+ * The grid is triangulated with alternating quad diagonals ( a diamond pattern ), so a
24
+ * coarse mesh holds its silhouette without a one-way grain. The surface shades itself
25
+ * from altitude and slope in TSL — grass, forest, rock, scree and snow, with detail
26
+ * normals and aerial perspective — so no material or textures are needed.
27
+ *
28
+ * The baked height grid is exposed through {@link TerrainGenerator#sampleHeight} so a
29
+ * scattered forest ( or anything else ) can sit exactly on the surface.
30
+ *
31
+ * ```js
32
+ * const terrain = new TerrainGenerator( { seed: 1 } );
33
+ * scene.add( terrain.build() );
34
+ * ```
35
+ */
36
+ class TerrainGenerator {
37
+
38
+ constructor( parameters = {} ) {
39
+
40
+ this.parameters = Object.assign( {}, TerrainGenerator.defaults, parameters );
41
+
42
+ // baked altitude range, fed to the shader so the colour bands track the real
43
+ // valley floor and peaks
44
+ this.minHeight = uniform( 0 );
45
+ this.maxHeight = uniform( 1 );
46
+
47
+ this.material = terrainMaterial( this.minHeight, this.maxHeight );
48
+ this.geometry = null;
49
+ this.group = null;
50
+
51
+ }
52
+
53
+ build() {
54
+
55
+ this.dispose();
56
+
57
+ const p = this.parameters;
58
+ const N = p.segments + 1;
59
+ const half = p.size / 2;
60
+
61
+ // world coordinate of each grid line, shared by the bake and layout below
62
+ const coord = new Array( N );
63
+ for ( let i = 0; i < N; i ++ ) coord[ i ] = i / p.segments * p.size - half;
64
+
65
+ // bake the height grid; kept around so the surface can be sampled ( bilinearly )
66
+ // afterwards — e.g. to sit a scattered forest on it
67
+ const height = heightField( p );
68
+ const heights = new Float32Array( N * N );
69
+
70
+ for ( let iz = 0; iz < N; iz ++ ) {
71
+
72
+ for ( let ix = 0; ix < N; ix ++ ) {
73
+
74
+ heights[ iz * N + ix ] = height( coord[ ix ], coord[ iz ] );
75
+
76
+ }
77
+
78
+ }
79
+
80
+ // relax slopes past the angle of repose, shedding the fractal's needle-spikes
81
+ if ( p.talusPasses > 0 ) thermalErode( heights, N, p.size / p.segments, p.talus, p.talusPasses );
82
+
83
+ // lay the grid out flat in the XZ plane ( Y-up ) and find the height range
84
+ const positions = new Float32Array( N * N * 3 );
85
+ let min = Infinity, max = - Infinity;
86
+
87
+ for ( let iz = 0; iz < N; iz ++ ) {
88
+
89
+ for ( let ix = 0; ix < N; ix ++ ) {
90
+
91
+ const o = iz * N + ix;
92
+ const y = heights[ o ];
93
+
94
+ positions[ o * 3 ] = coord[ ix ];
95
+ positions[ o * 3 + 1 ] = y;
96
+ positions[ o * 3 + 2 ] = coord[ iz ];
97
+
98
+ if ( y < min ) min = y;
99
+ if ( y > max ) max = y;
100
+
101
+ }
102
+
103
+ }
104
+
105
+ // flip the quad diagonal on every other quad, so the mesh reads as diamonds
106
+ // rather than a one-way grain
107
+ const indices = [];
108
+
109
+ for ( let iz = 0; iz < p.segments; iz ++ ) {
110
+
111
+ for ( let ix = 0; ix < p.segments; ix ++ ) {
112
+
113
+ const a = iz * N + ix, b = a + 1, c = a + N, d = c + 1;
114
+
115
+ if ( ( ix + iz ) % 2 === 0 ) indices.push( a, c, b, b, c, d );
116
+ else indices.push( a, c, d, a, d, b );
117
+
118
+ }
119
+
120
+ }
121
+
122
+ const geometry = new BufferGeometry();
123
+ geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
124
+ geometry.setIndex( indices );
125
+ geometry.computeVertexNormals();
126
+
127
+ this.heights = heights;
128
+ this.gridSize = N;
129
+ this.minY = min;
130
+ this.maxY = max;
131
+ this.minHeight.value = min;
132
+ this.maxHeight.value = max;
133
+
134
+ const mesh = new Mesh( geometry, this.material );
135
+ mesh.castShadow = mesh.receiveShadow = true;
136
+
137
+ const group = new Group();
138
+ group.name = 'Terrain';
139
+ group.add( mesh );
140
+
141
+ this.geometry = geometry;
142
+ this.group = group;
143
+
144
+ return group;
145
+
146
+ }
147
+
148
+ // world-space height at ( x, z ), bilinearly interpolated from the baked grid
149
+ sampleHeight( x, z ) {
150
+
151
+ const p = this.parameters;
152
+ const N = this.gridSize;
153
+ const half = p.size / 2;
154
+
155
+ const fx = Math.max( 0, Math.min( p.segments, ( x + half ) / p.size * p.segments ) );
156
+ const fz = Math.max( 0, Math.min( p.segments, ( z + half ) / p.size * p.segments ) );
157
+
158
+ const ix = Math.min( N - 2, Math.floor( fx ) );
159
+ const iz = Math.min( N - 2, Math.floor( fz ) );
160
+ const tx = fx - ix;
161
+ const tz = fz - iz;
162
+
163
+ const h = this.heights;
164
+ const h00 = h[ iz * N + ix ];
165
+ const h10 = h[ iz * N + ix + 1 ];
166
+ const h01 = h[ ( iz + 1 ) * N + ix ];
167
+ const h11 = h[ ( iz + 1 ) * N + ix + 1 ];
168
+
169
+ return ( h00 * ( 1 - tx ) + h10 * tx ) * ( 1 - tz ) + ( h01 * ( 1 - tx ) + h11 * tx ) * tz;
170
+
171
+ }
172
+
173
+ // surface flatness at ( x, z ): the normal's y component ( 1 on the flat, → 0 on a
174
+ // cliff ). allocation-free, for cheaply testing many candidate forest positions.
175
+ sampleSlope( x, z ) {
176
+
177
+ const e = this.parameters.size / this.parameters.segments;
178
+ const hx = this.sampleHeight( x + e, z ) - this.sampleHeight( x - e, z );
179
+ const hz = this.sampleHeight( x, z + e ) - this.sampleHeight( x, z - e );
180
+
181
+ return 2 * e / Math.sqrt( hx * hx + 4 * e * e + hz * hz );
182
+
183
+ }
184
+
185
+ dispose() {
186
+
187
+ if ( this.geometry ) this.geometry.dispose();
188
+ this.geometry = null;
189
+ this.group = null;
190
+
191
+ }
192
+
193
+ }
194
+
195
+ TerrainGenerator.defaults = {
196
+ seed: 1,
197
+ size: 200, // world units across the square patch
198
+ segments: 192, // grid quads per side; vertices = ( segments + 1 )²
199
+ heightScale: 65, // peak-to-valley exaggeration, in world units
200
+ frequency: 0.01, // base noise frequency ( the footprint of a mountain )
201
+ octaves: 5,
202
+ lacunarity: 1.97, // per-octave frequency step; off 2 so octaves don't grid-lock
203
+ gain: 0.5, // per-octave amplitude step ( persistence )
204
+ erosion: 0.7, // derivative damping: higher flattens valleys and sharpens ridges
205
+ warp: 0.35, // domain-warp strength ( noise units ): bends ridges and valleys
206
+ valleyBias: 1.2, // power curve over the height, to flatten the mist floor
207
+ seaLevel: 0.15, // 0..1, subtracted before scaling so the valley floor sinks below y = 0
208
+ talus: 1, // thermal-erosion angle of repose ( rise / run ): lower settles flatter
209
+ talusPasses: 12 // thermal-erosion iterations ( 0 = off )
210
+ };
211
+
212
+ // deterministic PRNG ( mulberry32 ), so a seed always bakes the same terrain
213
+ function createRandom( seed ) {
214
+
215
+ let s = ( seed >>> 0 ) || 1;
216
+
217
+ return function () {
218
+
219
+ s = ( s + 0x6D2B79F5 ) | 0;
220
+ let t = Math.imul( s ^ ( s >>> 15 ), 1 | s );
221
+ t = ( t + Math.imul( t ^ ( t >>> 7 ), 61 | t ) ) ^ t;
222
+ return ( ( t ^ ( t >>> 14 ) ) >>> 0 ) / 4294967296;
223
+
224
+ };
225
+
226
+ }
227
+
228
+ // builds the height( worldX, worldZ ) function for one seed
229
+ function heightField( p ) {
230
+
231
+ const perlin = new ImprovedNoise();
232
+ const random = createRandom( p.seed );
233
+
234
+ // ImprovedNoise's permutation is fixed, so a seed can only shift the sample window:
235
+ // a translation and a per-octave z-slice, drawn from the PRNG to decorrelate seeds
236
+ const offsetX = random() * 256;
237
+ const offsetZ = random() * 256;
238
+ const slice = random() * 256;
239
+
240
+ const { frequency, octaves, lacunarity, gain, erosion, warp, valleyBias, seaLevel, heightScale } = p;
241
+
242
+ // low-frequency fractal sum that warps the sample position
243
+ function warpField( x, z, zr ) {
244
+
245
+ let freq = 1, amp = 1, sum = 0, norm = 0;
246
+
247
+ for ( let i = 0; i < 2; i ++ ) {
248
+
249
+ sum += amp * perlin.noise( x * freq + offsetX, z * freq + offsetZ, zr + i * 1.7 );
250
+ norm += amp; freq *= lacunarity; amp *= gain;
251
+
252
+ }
253
+
254
+ return sum / norm;
255
+
256
+ }
257
+
258
+ // derivative-damped fractal sum: each octave is divided down where the running
259
+ // gradient is already steep, keeping ridges crisp and valleys smooth. the domain
260
+ // rotates between octaves to break the noise's axis-aligned grid.
261
+ function eroded( x, z ) {
262
+
263
+ let sum = 0, amp = 1, dX = 0, dZ = 0, px = x, pz = z, freq = 1;
264
+ const e = 0.004; // finite-difference step, in noise units
265
+
266
+ for ( let i = 0; i < octaves; i ++ ) {
267
+
268
+ const zr = slice + i * 1.7;
269
+ const bx = px * freq + offsetX, bz = pz * freq + offsetZ;
270
+ const n = perlin.noise( bx, bz, zr );
271
+ const nx = perlin.noise( bx + e, bz, zr );
272
+ const nz = perlin.noise( bx, bz + e, zr );
273
+
274
+ // this octave's world-space gradient ( chain rule: × freq )
275
+ dX += ( nx - n ) / e * freq;
276
+ dZ += ( nz - n ) / e * freq;
277
+
278
+ sum += amp * n / ( 1 + erosion * ( dX * dX + dZ * dZ ) );
279
+
280
+ // rotate the domain ~37° ( the matrix [ 0.8 -0.6 ; 0.6 0.8 ] )
281
+ const rx = 0.8 * px - 0.6 * pz;
282
+ pz = 0.6 * px + 0.8 * pz;
283
+ px = rx;
284
+
285
+ freq *= lacunarity; amp *= gain;
286
+
287
+ }
288
+
289
+ return sum * 0.5 + 0.5;
290
+
291
+ }
292
+
293
+ return function ( worldX, worldZ ) {
294
+
295
+ const x = worldX * frequency, z = worldZ * frequency;
296
+
297
+ // warp the sample so ridges and valleys meander instead of running straight
298
+ const wx = x + warp * warpField( x + 1.3, z + 7.2, slice + 40 );
299
+ const wz = z + warp * warpField( x + 5.2, z + 1.3, slice + 70 );
300
+
301
+ // power curve that settles the low ground into a flat mist bed
302
+ const h = Math.pow( Math.min( eroded( wx, wz ) * 1.1, 1 ), valleyBias );
303
+
304
+ return ( h - seaLevel ) * heightScale;
305
+
306
+ };
307
+
308
+ }
309
+
310
+ // thermal ( talus ) erosion on the baked height grid: a cell overhanging a neighbour
311
+ // by more than the talus drop sheds the excess downhill, so over a few passes slopes
312
+ // relax to the angle of repose. spikes — steep on every side — bleed off fastest;
313
+ // broad one-sided faces keep their shape. material is conserved through a delta buffer,
314
+ // so the result is independent of cell order.
315
+ function thermalErode( h, N, cellSize, talus, passes ) {
316
+
317
+ const drop = talus * cellSize; // max height step a slope can hold between two cells
318
+ const carry = 0.5; // fraction of the steepest overhang moved per pass ( <= 0.5 = stable )
319
+ const delta = new Float32Array( N * N );
320
+ const ex = [ 0, 0, 0, 0 ];
321
+ const off = [ - 1, 1, - N, N ];
322
+
323
+ for ( let p = 0; p < passes; p ++ ) {
324
+
325
+ delta.fill( 0 );
326
+
327
+ for ( let z = 0; z < N; z ++ ) {
328
+
329
+ for ( let x = 0; x < N; x ++ ) {
330
+
331
+ const i = z * N + x;
332
+ const hi = h[ i ];
333
+
334
+ // overhang past the talus drop toward each of the 4 neighbours
335
+ ex[ 0 ] = x > 0 ? hi - h[ i - 1 ] - drop : 0;
336
+ ex[ 1 ] = x < N - 1 ? hi - h[ i + 1 ] - drop : 0;
337
+ ex[ 2 ] = z > 0 ? hi - h[ i - N ] - drop : 0;
338
+ ex[ 3 ] = z < N - 1 ? hi - h[ i + N ] - drop : 0;
339
+
340
+ let sum = 0, peak = 0;
341
+
342
+ for ( let k = 0; k < 4; k ++ ) {
343
+
344
+ const d = ex[ k ];
345
+
346
+ if ( d <= 0 ) {
347
+
348
+ ex[ k ] = 0;
349
+ continue;
350
+
351
+ }
352
+
353
+ sum += d;
354
+ if ( d > peak ) peak = d;
355
+
356
+ }
357
+
358
+ if ( sum <= 0 ) continue;
359
+
360
+ // move a slice of the steepest overhang, split across the downhill
361
+ // neighbours in proportion to how far each sits below the talus line
362
+ const move = carry * peak;
363
+ delta[ i ] -= move;
364
+
365
+ for ( let k = 0; k < 4; k ++ ) {
366
+
367
+ if ( ex[ k ] > 0 ) delta[ i + off[ k ] ] += move * ex[ k ] / sum;
368
+
369
+ }
370
+
371
+ }
372
+
373
+ }
374
+
375
+ for ( let k = 0; k < N * N; k ++ ) h[ k ] += delta[ k ];
376
+
377
+ }
378
+
379
+ }
380
+
381
+ // --- shading -------------------------------------------------------------
382
+
383
+ // perturbs the normal by a world-space height field using Mikkelsen's surface-gradient
384
+ // method. the built-in bumpMap reads height by offsetting the UV — a no-op for a
385
+ // world-keyed height — so the height's screen-space derivatives are fed in directly.
386
+ // returns a view-space normal.
387
+ function bumpNormal( height ) {
388
+
389
+ const dpdx = positionView.dFdx();
390
+ const dpdy = positionView.dFdy();
391
+ const r1 = dpdy.cross( normalView );
392
+ const r2 = normalView.cross( dpdx );
393
+ const det = dpdx.dot( r1 );
394
+ const grad = det.sign().mul( height.dFdx().mul( r1 ).add( height.dFdy().mul( r2 ) ) );
395
+
396
+ return det.abs().mul( normalView ).sub( grad ).normalize();
397
+
398
+ }
399
+
400
+ // altitude- and slope-based shading, all in TSL ( no textures ). only the colour,
401
+ // roughness and detail normal are authored here; the lighting ( sun, sky fill, the
402
+ // snow's warm/cool cast ) comes from the scene's lights and environment.
403
+ function terrainMaterial( minHeight, maxHeight ) {
404
+
405
+ const material = new MeshStandardNodeMaterial();
406
+ material.metalness = 0;
407
+
408
+ const distance = positionWorld.distance( cameraPosition );
409
+
410
+ // the two drivers: normalised altitude ( valley 0 → peak 1 ) and surface flatness
411
+ const altitude = positionWorld.y.sub( minHeight ).div( maxHeight.sub( minHeight ) ).clamp();
412
+ const flatness = normalWorld.y.clamp(); // 1 on level ground, 0 on a vertical cliff
413
+ const steep = flatness.oneMinus();
414
+
415
+ // three reused noise scales: fine band-edge jitter, grain ( ~5u patches ) and macro
416
+ const detail = mx_noise_float( positionWorld.xz.mul( 0.05 ) );
417
+ const grain = mx_noise_float( positionWorld.xz.mul( 0.18 ) );
418
+ const macro = mx_noise_float( positionWorld.xz.mul( 0.012 ) );
419
+
420
+ const grass = color( 0x6e7253 ); // dry sage-olive meadow ( not video-game green )
421
+ const dryGrass = color( 0x8a8550 );
422
+ const forest = color( 0x39402f ); // dark forested mid-slope band, under the trees
423
+ const rock = color( 0x736a5f ); // warm grey-brown rock
424
+ const scree = color( 0x837a6f ); // brighter broken rock below the cliffs
425
+ const lichen = color( 0x6c7355 ); // muted green-grey, patched onto lower rock
426
+ const snow = color( 0xe9ecf0 ); // fresh snow; warm-sun / cool-sky cast is from the lighting
427
+ const snowDeep = color( 0xccd6e2 ); // cooler wind-packed snow, drifted into patches
428
+
429
+ // two band frequencies of lighter / darker stone, wobbled by noise, so cliff faces
430
+ // read as layered bedding instead of flat grey
431
+ const bandA = positionWorld.y.mul( 0.5 ).add( detail.mul( 3 ) ).add( macro.mul( 4 ) ).sin();
432
+ const bandB = positionWorld.y.mul( 1.4 ).add( grain.mul( 2 ) ).sin();
433
+ const strata = bandA.mul( 0.6 ).add( bandB.mul( 0.4 ) ).mul( 0.5 ).add( 0.5 );
434
+
435
+ // lichen creeps onto the lower, gentler rock; cliffs and high ground stay bare grey
436
+ const lichenMask = smoothstep( 0.45, 0.72, grain ).mul( smoothstep( 0.62, 0.32, steep ) ).mul( smoothstep( 0.66, 0.34, altitude ) );
437
+ const rockShade = mix( rock, lichen, lichenMask.mul( 0.45 ) ).mul( strata.mul( 0.36 ).add( 0.8 ) );
438
+
439
+ // meadow, drifting to dry grass in macro-noise patches over a mid band
440
+ let surface = mix( grass, dryGrass, smoothstep( 0.15, 0.75, macro ).mul( smoothstep( 0.22, 0.5, altitude ) ) );
441
+
442
+ // dark forested band on the gentle mid-slopes ( where the instanced trees live )
443
+ surface = mix( surface, forest, smoothstep( 0.16, 0.34, altitude ).mul( smoothstep( 0.5, 0.72, flatness ) ).mul( 0.75 ) );
444
+
445
+ // rock by altitude, and on every steep face regardless of height
446
+ surface = mix( surface, rockShade, smoothstep( 0.46, 0.64, altitude.add( detail.mul( 0.06 ) ) ) );
447
+ surface = mix( surface, rockShade, smoothstep( 0.34, 0.62, steep ) );
448
+
449
+ // scree on the medium-steep ground below the cliffs, broken up by noise
450
+ const screeMask = smoothstep( 0.42, 0.7, steep ).mul( smoothstep( 0.35, 0.7, flatness ) ).mul( detail.mul( 0.5 ).add( 0.5 ) );
451
+ surface = mix( surface, scree, screeMask.mul( 0.5 ) );
452
+
453
+ // snow on high, flat ground; the grain noise breaks the line so rock pokes through
454
+ // near the snowline instead of stopping on a clean contour
455
+ const snowMask = smoothstep( 0.56, 0.78, altitude.add( detail.mul( 0.08 ) ).add( grain.mul( 0.05 ) ) ).mul( smoothstep( 0.3, 0.6, flatness ) );
456
+ const snowColor = mix( snow, snowDeep, smoothstep( 0.2, 0.7, grain ).mul( 0.6 ) ); // patchy, not a flat sheet
457
+ surface = mix( surface, snowColor, snowMask );
458
+
459
+ // dark, damp ground pooling in the low flat creases ( cheap moisture proxy )
460
+ const cavity = smoothstep( 0.24, 0.06, altitude ).mul( flatness );
461
+ surface = surface.mul( cavity.mul( 0.32 ).oneMinus() );
462
+
463
+ // macro drift then a fine grain mottle, so no band is a flat colour
464
+ surface = surface.mul( macro.mul( 0.5 ).add( 0.5 ).mul( 0.3 ).add( 0.84 ) );
465
+ surface = surface.mul( grain.mul( 0.5 ).add( 0.5 ).mul( 0.12 ).add( 0.94 ) );
466
+
467
+ // aerial perspective: desaturate and lift distant ground toward a cool haze, so
468
+ // depth reads and the range recedes into the mist
469
+ const aerial = smoothstep( 180, 820, distance );
470
+ surface = saturation( surface, aerial.oneMinus().mul( 0.5 ).add( 0.5 ) );
471
+ surface = mix( surface, color( 0xcfc8ba ), aerial.mul( 0.62 ) ); // far ridges dissolve into the sky
472
+
473
+ material.colorNode = surface;
474
+ material.roughnessNode = mix( float( 0.95 ), float( 0.72 ), snowMask );
475
+
476
+ // detail normals: three octaves of world-space relief, faded out with distance so
477
+ // they can't alias into fireflies in the haze. gating the noise behind the fade ( a
478
+ // real branch ) lets the far majority of this fragment-bound terrain skip the taps.
479
+ const detailFade = smoothstep( 420, 60, distance );
480
+ const reliefStrength = mix( float( 0.25 ), float( 0.55 ), steep ); // more on rock, less on grass
481
+ const relief = Fn( () => {
482
+
483
+ const r = float( 0 ).toVar();
484
+
485
+ If( detailFade.greaterThan( 0.01 ), () => {
486
+
487
+ r.assign( mx_noise_float( positionWorld.xz.mul( 0.6 ) )
488
+ .add( mx_noise_float( positionWorld.xz.mul( 1.7 ) ).mul( 0.5 ) )
489
+ .add( mx_noise_float( positionWorld.xz.mul( 4.0 ) ).mul( 0.25 ) )
490
+ .mul( reliefStrength ).mul( detailFade ).mul( 0.25 ) );
491
+
492
+ } );
493
+
494
+ return r;
495
+
496
+ } )();
497
+
498
+ material.normalNode = bumpNormal( relief );
499
+
500
+ return material;
501
+
502
+ }
503
+
504
+ export { TerrainGenerator };