@zephyr3d/scene 0.9.26 → 0.10.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 (506) hide show
  1. package/README.md +60 -27
  2. package/dist/animation/animation_bank.js +634 -0
  3. package/dist/animation/animation_bank.js.map +1 -0
  4. package/dist/animation/animation_bank_gpu.js +256 -0
  5. package/dist/animation/animation_bank_gpu.js.map +1 -0
  6. package/dist/animation/animationset.js +146 -30
  7. package/dist/animation/animationset.js.map +1 -1
  8. package/dist/animation/cloth/gpu_cloth_component.js +406 -0
  9. package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
  10. package/dist/animation/cloth/gpu_cloth_system.js +332 -202
  11. package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
  12. package/dist/animation/gpu_animation_driver.js +289 -0
  13. package/dist/animation/gpu_animation_driver.js.map +1 -0
  14. package/dist/animation/joint_dynamics/collision.js +112 -1
  15. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  16. package/dist/animation/joint_dynamics/controller.js +6 -0
  17. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  18. package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
  19. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  20. package/dist/animation/joint_dynamics/solver.js +50 -12
  21. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  22. package/dist/animation/joint_dynamics/types.js.map +1 -1
  23. package/dist/animation/skeleton.js +300 -56
  24. package/dist/animation/skeleton.js.map +1 -1
  25. package/dist/animation/skin_palette_atlas.js +252 -0
  26. package/dist/animation/skin_palette_atlas.js.map +1 -0
  27. package/dist/animation/spring/multi_chain_spring_system.js +298 -38
  28. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  29. package/dist/animation/spring/spring_chain.js +2 -0
  30. package/dist/animation/spring/spring_chain.js.map +1 -1
  31. package/dist/animation/spring/spring_collider.js +159 -21
  32. package/dist/animation/spring/spring_collider.js.map +1 -1
  33. package/dist/animation/spring/spring_particle.js +1 -0
  34. package/dist/animation/spring/spring_particle.js.map +1 -1
  35. package/dist/animation/spring/spring_solver.js +173 -0
  36. package/dist/animation/spring/spring_solver.js.map +1 -0
  37. package/dist/animation/spring/spring_system.js +249 -24
  38. package/dist/animation/spring/spring_system.js.map +1 -1
  39. package/dist/animation/spring_modifier.js +32 -1
  40. package/dist/animation/spring_modifier.js.map +1 -1
  41. package/dist/app/app.js +26 -0
  42. package/dist/app/app.js.map +1 -1
  43. package/dist/app/engine.js +86 -15
  44. package/dist/app/engine.js.map +1 -1
  45. package/dist/app/gamepad.js +191 -0
  46. package/dist/app/gamepad.js.map +1 -0
  47. package/dist/app/inputactions.js +271 -0
  48. package/dist/app/inputactions.js.map +1 -0
  49. package/dist/app/inputmgr.js +331 -22
  50. package/dist/app/inputmgr.js.map +1 -1
  51. package/dist/app/loading.js +138 -0
  52. package/dist/app/loading.js.map +1 -0
  53. package/dist/app/pipelinecache.js +209 -0
  54. package/dist/app/pipelinecache.js.map +1 -0
  55. package/dist/app/runtimescript.js +25 -0
  56. package/dist/app/runtimescript.js.map +1 -1
  57. package/dist/app/scriptingsystem.js +54 -0
  58. package/dist/app/scriptingsystem.js.map +1 -1
  59. package/dist/app/scriptregistry.js +7 -2
  60. package/dist/app/scriptregistry.js.map +1 -1
  61. package/dist/asset/asset_manifest.js +59 -0
  62. package/dist/asset/asset_manifest.js.map +1 -0
  63. package/dist/asset/asset_preload.js +258 -0
  64. package/dist/asset/asset_preload.js.map +1 -0
  65. package/dist/asset/assetmanager.js +117 -65
  66. package/dist/asset/assetmanager.js.map +1 -1
  67. package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
  68. package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  69. package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  70. package/dist/asset/loaders/ktx2/basis_location.js +17 -0
  71. package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
  72. package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
  73. package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
  74. package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
  75. package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
  76. package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
  77. package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
  78. package/dist/asset/mesh_lod_builder.js +104 -0
  79. package/dist/asset/mesh_lod_builder.js.map +1 -0
  80. package/dist/asset/mesh_settings.js +111 -0
  81. package/dist/asset/mesh_settings.js.map +1 -0
  82. package/dist/asset/meshopt_decoder.js +18 -0
  83. package/dist/asset/meshopt_decoder.js.map +1 -0
  84. package/dist/asset/meshopt_simplifier.js +26 -0
  85. package/dist/asset/meshopt_simplifier.js.map +1 -0
  86. package/dist/asset/model.js +177 -3
  87. package/dist/asset/model.js.map +1 -1
  88. package/dist/asset/texture_settings.js +231 -0
  89. package/dist/asset/texture_settings.js.map +1 -0
  90. package/dist/asset/zmsh_binary.js +131 -0
  91. package/dist/asset/zmsh_binary.js.map +1 -0
  92. package/dist/asset/zsdf_binary.js +111 -0
  93. package/dist/asset/zsdf_binary.js.map +1 -0
  94. package/dist/blitter/bilateralblur.js +1 -2
  95. package/dist/blitter/bilateralblur.js.map +1 -1
  96. package/dist/blitter/gaussianblur.js +1 -6
  97. package/dist/blitter/gaussianblur.js.map +1 -1
  98. package/dist/camera/base.js +31 -10
  99. package/dist/camera/base.js.map +1 -1
  100. package/dist/camera/camera.js +178 -200
  101. package/dist/camera/camera.js.map +1 -1
  102. package/dist/camera/follow.js +342 -0
  103. package/dist/camera/follow.js.map +1 -0
  104. package/dist/camera/fps.js +9 -7
  105. package/dist/camera/fps.js.map +1 -1
  106. package/dist/camera/orbit.js +46 -19
  107. package/dist/camera/orbit.js.map +1 -1
  108. package/dist/index.d.ts +30475 -19865
  109. package/dist/index.js +67 -12
  110. package/dist/index.js.map +1 -1
  111. package/dist/material/blinn.js +3 -0
  112. package/dist/material/blinn.js.map +1 -1
  113. package/dist/material/eye.js +1 -1
  114. package/dist/material/eye.js.map +1 -1
  115. package/dist/material/hair.js +2 -3
  116. package/dist/material/hair.js.map +1 -1
  117. package/dist/material/hairstrand.js +235 -235
  118. package/dist/material/hairstrand.js.map +1 -1
  119. package/dist/material/lambert.js +4 -1
  120. package/dist/material/lambert.js.map +1 -1
  121. package/dist/material/material.js +362 -300
  122. package/dist/material/material.js.map +1 -1
  123. package/dist/material/meshmaterial.js +118 -45
  124. package/dist/material/meshmaterial.js.map +1 -1
  125. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  126. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  127. package/dist/material/mixins/lightmodel/lambert.js +1 -1
  128. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  129. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
  130. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  131. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
  132. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  133. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
  134. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  135. package/dist/material/mixins/lit.js +223 -83
  136. package/dist/material/mixins/lit.js.map +1 -1
  137. package/dist/material/mixins/pbr/common.js +31 -206
  138. package/dist/material/mixins/pbr/common.js.map +1 -1
  139. package/dist/material/mtoon.js +1 -1
  140. package/dist/material/mtoon.js.map +1 -1
  141. package/dist/material/pbrmr.js +3 -0
  142. package/dist/material/pbrmr.js.map +1 -1
  143. package/dist/material/pbrsg.js +3 -0
  144. package/dist/material/pbrsg.js.map +1 -1
  145. package/dist/material/sdf_debug.js +78 -0
  146. package/dist/material/sdf_debug.js.map +1 -0
  147. package/dist/material/shader/helper.js +733 -190
  148. package/dist/material/shader/helper.js.map +1 -1
  149. package/dist/material/shader/terrain_blend.js +204 -43
  150. package/dist/material/shader/terrain_blend.js.map +1 -1
  151. package/dist/material/skin.js +331 -297
  152. package/dist/material/skin.js.map +1 -1
  153. package/dist/material/skinprofile.js +1058 -0
  154. package/dist/material/skinprofile.js.map +1 -0
  155. package/dist/material/sss.js +353 -0
  156. package/dist/material/sss.js.map +1 -0
  157. package/dist/material/sss_kernel.js +265 -0
  158. package/dist/material/sss_kernel.js.map +1 -0
  159. package/dist/material/sssprofile.js +879 -0
  160. package/dist/material/sssprofile.js.map +1 -0
  161. package/dist/material/subsurfaceprofile.js +4 -8
  162. package/dist/material/subsurfaceprofile.js.map +1 -1
  163. package/dist/material/terrain-cm.js +464 -188
  164. package/dist/material/terrain-cm.js.map +1 -1
  165. package/dist/material/unlit.js +3 -0
  166. package/dist/material/unlit.js.map +1 -1
  167. package/dist/material/water.js +2009 -201
  168. package/dist/material/water.js.map +1 -1
  169. package/dist/node_modules/meshoptimizer/LICENSE +21 -0
  170. package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
  171. package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
  172. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
  173. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
  174. package/dist/physics/character.js +226 -0
  175. package/dist/physics/character.js.map +1 -0
  176. package/dist/physics/collider.js +209 -0
  177. package/dist/physics/collider.js.map +1 -0
  178. package/dist/physics/events.js +79 -0
  179. package/dist/physics/events.js.map +1 -0
  180. package/dist/physics/joint.js +272 -0
  181. package/dist/physics/joint.js.map +1 -0
  182. package/dist/physics/node_physics.js +234 -0
  183. package/dist/physics/node_physics.js.map +1 -0
  184. package/dist/physics/part.js +91 -0
  185. package/dist/physics/part.js.map +1 -0
  186. package/dist/physics/rigid_body.js +379 -0
  187. package/dist/physics/rigid_body.js.map +1 -0
  188. package/dist/physics/vehicle.js +335 -0
  189. package/dist/physics/vehicle.js.map +1 -0
  190. package/dist/physics/world.js +25 -0
  191. package/dist/physics/world.js.map +1 -0
  192. package/dist/posteffect/bloom.js +49 -14
  193. package/dist/posteffect/bloom.js.map +1 -1
  194. package/dist/posteffect/motionblur.js +668 -63
  195. package/dist/posteffect/motionblur.js.map +1 -1
  196. package/dist/posteffect/posteffect.js +12 -1
  197. package/dist/posteffect/posteffect.js.map +1 -1
  198. package/dist/posteffect/postsss.js +572 -0
  199. package/dist/posteffect/postsss.js.map +1 -0
  200. package/dist/posteffect/sao.js +48 -50
  201. package/dist/posteffect/sao.js.map +1 -1
  202. package/dist/posteffect/skinsss.js +605 -355
  203. package/dist/posteffect/skinsss.js.map +1 -1
  204. package/dist/posteffect/ssgi.js +91 -162
  205. package/dist/posteffect/ssgi.js.map +1 -1
  206. package/dist/posteffect/ssr.js +3 -11
  207. package/dist/posteffect/ssr.js.map +1 -1
  208. package/dist/posteffect/sss.js +34 -15
  209. package/dist/posteffect/sss.js.map +1 -1
  210. package/dist/posteffect/taa.js +1 -0
  211. package/dist/posteffect/taa.js.map +1 -1
  212. package/dist/render/abuffer_oit.js +40 -39
  213. package/dist/render/abuffer_oit.js.map +1 -1
  214. package/dist/render/clipmap.js +328 -62
  215. package/dist/render/clipmap.js.map +1 -1
  216. package/dist/render/cluster_light.js +958 -224
  217. package/dist/render/cluster_light.js.map +1 -1
  218. package/dist/render/cull_visitor.js +26 -5
  219. package/dist/render/cull_visitor.js.map +1 -1
  220. package/dist/render/debug_views.js +37 -0
  221. package/dist/render/debug_views.js.map +1 -0
  222. package/dist/render/depthpass.js +5 -1
  223. package/dist/render/depthpass.js.map +1 -1
  224. package/dist/render/drawable_mixin.js +53 -6
  225. package/dist/render/drawable_mixin.js.map +1 -1
  226. package/dist/render/dualdepthpeeling_oit.js +53 -53
  227. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  228. package/dist/render/envlight.js +196 -113
  229. package/dist/render/envlight.js.map +1 -1
  230. package/dist/render/fbm_wavegenerator.js +8 -13
  231. package/dist/render/fbm_wavegenerator.js.map +1 -1
  232. package/dist/render/fft_wavegenerator.js +268 -136
  233. package/dist/render/fft_wavegenerator.js.map +1 -1
  234. package/dist/render/gerstner_wavegenerator.js +113 -28
  235. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  236. package/dist/render/gi/probe_volume.js +1334 -0
  237. package/dist/render/gi/probe_volume.js.map +1 -0
  238. package/dist/render/gi/scene_gi.js +282 -0
  239. package/dist/render/gi/scene_gi.js.map +1 -0
  240. package/dist/render/gi/voxel_atlas.js +198 -0
  241. package/dist/render/gi/voxel_atlas.js.map +1 -0
  242. package/dist/render/gi/voxel_lighting.js +652 -0
  243. package/dist/render/gi/voxel_lighting.js.map +1 -0
  244. package/dist/render/gi/voxel_scene.js +642 -0
  245. package/dist/render/gi/voxel_scene.js.map +1 -0
  246. package/dist/render/gi/voxelize_pass.js +223 -0
  247. package/dist/render/gi/voxelize_pass.js.map +1 -0
  248. package/dist/render/globalbindgroup_allocator.js +3 -2
  249. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  250. package/dist/render/gpu_picking.js +9 -36
  251. package/dist/render/gpu_picking.js.map +1 -1
  252. package/dist/render/hzb.js +80 -22
  253. package/dist/render/hzb.js.map +1 -1
  254. package/dist/render/instance_culling.js +499 -0
  255. package/dist/render/instance_culling.js.map +1 -0
  256. package/dist/render/lightpass.js +23 -9
  257. package/dist/render/lightpass.js.map +1 -1
  258. package/dist/render/lod.js +46 -0
  259. package/dist/render/lod.js.map +1 -0
  260. package/dist/render/oit.js +11 -11
  261. package/dist/render/oit.js.map +1 -1
  262. package/dist/render/primitive.js +301 -9
  263. package/dist/render/primitive.js.map +1 -1
  264. package/dist/render/primitive_readback.js +209 -0
  265. package/dist/render/primitive_readback.js.map +1 -0
  266. package/dist/render/render_queue.js +198 -11
  267. package/dist/render/render_queue.js.map +1 -1
  268. package/dist/render/renderer.js +14 -7
  269. package/dist/render/renderer.js.map +1 -1
  270. package/dist/render/rendergraph/blackboard.js +15 -1
  271. package/dist/render/rendergraph/blackboard.js.map +1 -1
  272. package/dist/render/rendergraph/executor.js +136 -0
  273. package/dist/render/rendergraph/executor.js.map +1 -1
  274. package/dist/render/rendergraph/forward_plus_builder.js +585 -59
  275. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  276. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  277. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  278. package/dist/render/rendergraph/history_resources.js +8 -1
  279. package/dist/render/rendergraph/history_resources.js.map +1 -1
  280. package/dist/render/rendergraph/scene_render_context.js +31 -2
  281. package/dist/render/rendergraph/scene_render_context.js.map +1 -1
  282. package/dist/render/rendergraph/types.js.map +1 -1
  283. package/dist/render/renderpass.js +28 -5
  284. package/dist/render/renderpass.js.map +1 -1
  285. package/dist/render/sdf/box_allocator.js +98 -0
  286. package/dist/render/sdf/box_allocator.js.map +1 -0
  287. package/dist/render/sdf/global_sdf.js +865 -0
  288. package/dist/render/sdf/global_sdf.js.map +1 -0
  289. package/dist/render/sdf/scene_sdf.js +562 -0
  290. package/dist/render/sdf/scene_sdf.js.map +1 -0
  291. package/dist/render/sdf/sdf_atlas.js +227 -0
  292. package/dist/render/sdf/sdf_atlas.js.map +1 -0
  293. package/dist/render/sdf/sdf_programs.js +42 -0
  294. package/dist/render/sdf/sdf_programs.js.map +1 -0
  295. package/dist/render/sdf/sdf_view.js +199 -0
  296. package/dist/render/sdf/sdf_view.js.map +1 -0
  297. package/dist/render/sdf/waterline.js +610 -0
  298. package/dist/render/sdf/waterline.js.map +1 -0
  299. package/dist/render/shadow_mask_pass.js +142 -25
  300. package/dist/render/shadow_mask_pass.js.map +1 -1
  301. package/dist/render/shore_wave_generator.js +1193 -0
  302. package/dist/render/shore_wave_generator.js.map +1 -0
  303. package/dist/render/sky.js +516 -86
  304. package/dist/render/sky.js.map +1 -1
  305. package/dist/render/transmission_thickness_pass.js +477 -0
  306. package/dist/render/transmission_thickness_pass.js.map +1 -0
  307. package/dist/render/underwater.js +524 -0
  308. package/dist/render/underwater.js.map +1 -0
  309. package/dist/render/virtualtexture/virtual_texture.js +1214 -0
  310. package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
  311. package/dist/render/volumetric_cloud/cloud_common.js +472 -0
  312. package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
  313. package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
  314. package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
  315. package/dist/render/volumetric_cloud/debug_view.js +131 -0
  316. package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
  317. package/dist/render/volumetric_cloud/resources.js +380 -0
  318. package/dist/render/volumetric_cloud/resources.js.map +1 -0
  319. package/dist/render/volumetric_cloud/sky_cache.js +380 -0
  320. package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
  321. package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
  322. package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
  323. package/dist/render/water_caustics.js +1195 -0
  324. package/dist/render/water_caustics.js.map +1 -0
  325. package/dist/render/water_foam.js +627 -0
  326. package/dist/render/water_foam.js.map +1 -0
  327. package/dist/render/water_interaction.js +1795 -0
  328. package/dist/render/water_interaction.js.map +1 -0
  329. package/dist/render/weightedblended_oit.js +36 -36
  330. package/dist/render/weightedblended_oit.js.map +1 -1
  331. package/dist/scene/basesprite.js +9 -4
  332. package/dist/scene/basesprite.js.map +1 -1
  333. package/dist/scene/batchgroup.js +108 -12
  334. package/dist/scene/batchgroup.js.map +1 -1
  335. package/dist/scene/environment.js +28 -7
  336. package/dist/scene/environment.js.map +1 -1
  337. package/dist/scene/foliage.js +1020 -0
  338. package/dist/scene/foliage.js.map +1 -0
  339. package/dist/scene/foliage_buckets.js +147 -0
  340. package/dist/scene/foliage_buckets.js.map +1 -0
  341. package/dist/scene/foliage_mask.js +358 -0
  342. package/dist/scene/foliage_mask.js.map +1 -0
  343. package/dist/scene/hair.js +15 -4
  344. package/dist/scene/hair.js.map +1 -1
  345. package/dist/scene/light.js +179 -13
  346. package/dist/scene/light.js.map +1 -1
  347. package/dist/scene/mesh.js +327 -45
  348. package/dist/scene/mesh.js.map +1 -1
  349. package/dist/scene/meshdrawable.js +6 -0
  350. package/dist/scene/meshdrawable.js.map +1 -1
  351. package/dist/scene/msdftext.js +9 -3
  352. package/dist/scene/msdftext.js.map +1 -1
  353. package/dist/scene/msdftextsprite.js +9 -3
  354. package/dist/scene/msdftextsprite.js.map +1 -1
  355. package/dist/scene/particlesys.js +8 -2
  356. package/dist/scene/particlesys.js.map +1 -1
  357. package/dist/scene/physics_settings.js +157 -0
  358. package/dist/scene/physics_settings.js.map +1 -0
  359. package/dist/scene/scene.js +190 -44
  360. package/dist/scene/scene.js.map +1 -1
  361. package/dist/scene/scene_node.js +147 -6
  362. package/dist/scene/scene_node.js.map +1 -1
  363. package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
  364. package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
  365. package/dist/scene/terrain-cm/grass.js +881 -42
  366. package/dist/scene/terrain-cm/grass.js.map +1 -1
  367. package/dist/scene/terrain-cm/grass_gpu.js +929 -0
  368. package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
  369. package/dist/scene/terrain-cm/grassmaterial.js +180 -9
  370. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  371. package/dist/scene/terrain-cm/terrain-cm.js +465 -36
  372. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  373. package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
  374. package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
  375. package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
  376. package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
  377. package/dist/scene/update_queue.js +54 -0
  378. package/dist/scene/update_queue.js.map +1 -0
  379. package/dist/scene/water.js +997 -96
  380. package/dist/scene/water.js.map +1 -1
  381. package/dist/scene/water_surface_sampler.js +324 -0
  382. package/dist/scene/water_surface_sampler.js.map +1 -0
  383. package/dist/scene/wind.js +317 -0
  384. package/dist/scene/wind.js.map +1 -0
  385. package/dist/shaders/atmosphere.js +388 -166
  386. package/dist/shaders/atmosphere.js.map +1 -1
  387. package/dist/shaders/fog.js +100 -32
  388. package/dist/shaders/fog.js.map +1 -1
  389. package/dist/shaders/gi.js +365 -0
  390. package/dist/shaders/gi.js.map +1 -0
  391. package/dist/shaders/ltc_rect.js +202 -0
  392. package/dist/shaders/ltc_rect.js.map +1 -0
  393. package/dist/shaders/misc.js +1 -10
  394. package/dist/shaders/misc.js.map +1 -1
  395. package/dist/shaders/noise.js +5 -1
  396. package/dist/shaders/noise.js.map +1 -1
  397. package/dist/shaders/probes.js +309 -0
  398. package/dist/shaders/probes.js.map +1 -0
  399. package/dist/shaders/sdf.js +537 -0
  400. package/dist/shaders/sdf.js.map +1 -0
  401. package/dist/shaders/shadow.js +104 -70
  402. package/dist/shaders/shadow.js.map +1 -1
  403. package/dist/shaders/skin_brdf.js +243 -0
  404. package/dist/shaders/skin_brdf.js.map +1 -0
  405. package/dist/shaders/ssr.js +6 -159
  406. package/dist/shaders/ssr.js.map +1 -1
  407. package/dist/shaders/temporal.js +38 -27
  408. package/dist/shaders/temporal.js.map +1 -1
  409. package/dist/shaders/water.js +40 -87
  410. package/dist/shaders/water.js.map +1 -1
  411. package/dist/shaders/water_medium.js +42 -0
  412. package/dist/shaders/water_medium.js.map +1 -0
  413. package/dist/shadow/dom.js +110 -19
  414. package/dist/shadow/dom.js.map +1 -1
  415. package/dist/shadow/esm.js +3 -3
  416. package/dist/shadow/esm.js.map +1 -1
  417. package/dist/shadow/pcf_opt.js +15 -48
  418. package/dist/shadow/pcf_opt.js.map +1 -1
  419. package/dist/shadow/pcf_pd.js +15 -53
  420. package/dist/shadow/pcf_pd.js.map +1 -1
  421. package/dist/shadow/pcss.js +34 -9
  422. package/dist/shadow/pcss.js.map +1 -1
  423. package/dist/shadow/shadow_impl.js +3 -8
  424. package/dist/shadow/shadow_impl.js.map +1 -1
  425. package/dist/shadow/shadow_region.js +87 -49
  426. package/dist/shadow/shadow_region.js.map +1 -1
  427. package/dist/shadow/shadowmapper.js +93 -53
  428. package/dist/shadow/shadowmapper.js.map +1 -1
  429. package/dist/shadow/ssm.js +18 -72
  430. package/dist/shadow/ssm.js.map +1 -1
  431. package/dist/shadow/vsm.js +3 -3
  432. package/dist/shadow/vsm.js.map +1 -1
  433. package/dist/shapes/shape.js +44 -1
  434. package/dist/shapes/shape.js.map +1 -1
  435. package/dist/utility/buoyancy.js +287 -0
  436. package/dist/utility/buoyancy.js.map +1 -0
  437. package/dist/utility/physical.js +10 -1
  438. package/dist/utility/physical.js.map +1 -1
  439. package/dist/utility/pmrem.js +17 -43
  440. package/dist/utility/pmrem.js.map +1 -1
  441. package/dist/utility/sdf/bake.js +435 -0
  442. package/dist/utility/sdf/bake.js.map +1 -0
  443. package/dist/utility/sdf/bvh.js +576 -0
  444. package/dist/utility/sdf/bvh.js.map +1 -0
  445. package/dist/utility/serialization/manager.js +36 -6
  446. package/dist/utility/serialization/manager.js.map +1 -1
  447. package/dist/utility/serialization/scene/animation.js +77 -7
  448. package/dist/utility/serialization/scene/animation.js.map +1 -1
  449. package/dist/utility/serialization/scene/batch.js +11 -4
  450. package/dist/utility/serialization/scene/batch.js.map +1 -1
  451. package/dist/utility/serialization/scene/camera.js +140 -279
  452. package/dist/utility/serialization/scene/camera.js.map +1 -1
  453. package/dist/utility/serialization/scene/cloth.js +25 -0
  454. package/dist/utility/serialization/scene/cloth.js.map +1 -0
  455. package/dist/utility/serialization/scene/common.js +14 -6
  456. package/dist/utility/serialization/scene/common.js.map +1 -1
  457. package/dist/utility/serialization/scene/foliage.js +821 -0
  458. package/dist/utility/serialization/scene/foliage.js.map +1 -0
  459. package/dist/utility/serialization/scene/hair.js +11 -4
  460. package/dist/utility/serialization/scene/hair.js.map +1 -1
  461. package/dist/utility/serialization/scene/light.js +115 -7
  462. package/dist/utility/serialization/scene/light.js.map +1 -1
  463. package/dist/utility/serialization/scene/material.js +388 -220
  464. package/dist/utility/serialization/scene/material.js.map +1 -1
  465. package/dist/utility/serialization/scene/mesh.js +69 -4
  466. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  467. package/dist/utility/serialization/scene/node.js +140 -5
  468. package/dist/utility/serialization/scene/node.js.map +1 -1
  469. package/dist/utility/serialization/scene/node_physics.js +1318 -0
  470. package/dist/utility/serialization/scene/node_physics.js.map +1 -0
  471. package/dist/utility/serialization/scene/particle.js +11 -4
  472. package/dist/utility/serialization/scene/particle.js.map +1 -1
  473. package/dist/utility/serialization/scene/physics.js +120 -0
  474. package/dist/utility/serialization/scene/physics.js.map +1 -0
  475. package/dist/utility/serialization/scene/primitive.js +124 -10
  476. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  477. package/dist/utility/serialization/scene/scene.js +1687 -51
  478. package/dist/utility/serialization/scene/scene.js.map +1 -1
  479. package/dist/utility/serialization/scene/sprite.js +11 -4
  480. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  481. package/dist/utility/serialization/scene/terrain.js +163 -33
  482. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  483. package/dist/utility/serialization/scene/text.js +11 -4
  484. package/dist/utility/serialization/scene/text.js.map +1 -1
  485. package/dist/utility/serialization/scene/water.js +2473 -114
  486. package/dist/utility/serialization/scene/water.js.map +1 -1
  487. package/dist/utility/serialization/types.js.map +1 -1
  488. package/dist/utility/shprojector.js +97 -109
  489. package/dist/utility/shprojector.js.map +1 -1
  490. package/dist/utility/textures/foam.js +170 -0
  491. package/dist/utility/textures/foam.js.map +1 -0
  492. package/dist/utility/textures/ggxlut.js +17 -43
  493. package/dist/utility/textures/ggxlut.js.map +1 -1
  494. package/dist/utility/textures/ltcdata.js +4 -4
  495. package/dist/utility/textures/ltcdata.js.map +1 -1
  496. package/dist/utility/textures/ltclut.js +16 -6
  497. package/dist/utility/textures/ltclut.js.map +1 -1
  498. package/dist/utility/unsupported.js +24 -0
  499. package/dist/utility/unsupported.js.map +1 -0
  500. package/dist/values.js +13 -1
  501. package/dist/values.js.map +1 -1
  502. package/package.json +25 -12
  503. package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
  504. package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  505. package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  506. package/src/asset/meshoptimizer/LICENSE +21 -0
@@ -0,0 +1,610 @@
1
+ import { Vector4 } from '@zephyr3d/base';
2
+ import { getDevice } from '../../app/api.js';
3
+ import { fetchSampler } from '../../utility/misc.js';
4
+ import { declareGlobalSDFUniforms, declareDynamicSDFUniforms, sampleGlobalSDF } from '../../shaders/sdf.js';
5
+ import { buildSDFProgram } from './sdf_programs.js';
6
+
7
+ /** Seed coordinate meaning "no seed yet". */ const NO_SEED = -1e5;
8
+ const WORKGROUP = 8;
9
+ /** Gaussian smoothing of the shore coordinates, in cells: half width and sigma. */ const SMOOTH_RADIUS = 4;
10
+ const SMOOTH_SIGMA = 2;
11
+ /** Field value within which the bed model is used, and its coefficient bound. */ const SMOOTH_MODEL_REACH = 4;
12
+ const SMOOTH_MODEL_CLAMP = 1000;
13
+ /** Jump-flooded distance, in metres, over which the bed model hands over to it. */ const SMOOTH_BLEND_START = 1;
14
+ const SMOOTH_BLEND_END = 4;
15
+ /** Horizontal field gradient below which the bed counts as flat. */ const WATERLINE_MIN_SLOPE = 0.02;
16
+ /** Bound of the linear model coefficients, within half float range. */ const WATERLINE_MODEL_CLAMP = 10000;
17
+ /** Distance a terrain source reports off its height map: open water, well past the bed model's reach. */ const TERRAIN_OFF_MAP = 1e4;
18
+ /**
19
+ * The global scene field as a waterline source: static geometry and the
20
+ * terrain, without the dynamic instances.
21
+ * @internal
22
+ */ class SDFWaterlineSource {
23
+ label = 'SDF';
24
+ _global;
25
+ constructor(global){
26
+ this._global = global;
27
+ }
28
+ get version() {
29
+ return this._global.staticVersion;
30
+ }
31
+ declareUniforms(scope) {
32
+ declareGlobalSDFUniforms(scope, 0, this._global.levels);
33
+ // Unsampled, declared for GlobalSDF.applyBindGroup
34
+ declareDynamicSDFUniforms(scope, 0);
35
+ }
36
+ applyBindGroup(bindGroup) {
37
+ this._global.applyBindGroup(bindGroup);
38
+ }
39
+ sampleDistance(scope, pos) {
40
+ return sampleGlobalSDF(scope, pos, this._global.levels);
41
+ }
42
+ }
43
+ /**
44
+ * A terrain's height map as a waterline source: the distance above the
45
+ * surface over its slope, exact on a plane, as the global field composites
46
+ * the terrain. Only the terrain, so nothing standing on a beach bends its
47
+ * shoreline. Off the height map, or with no terrain, everything is water.
48
+ * @internal
49
+ */ class TerrainWaterlineSource {
50
+ label = 'Terrain';
51
+ _terrain;
52
+ _version;
53
+ _key;
54
+ _region;
55
+ /** (height scale, world y, 1 / width, 1 / height) */ _params;
56
+ _dummy;
57
+ constructor(){
58
+ this._terrain = null;
59
+ this._version = 0;
60
+ this._key = '';
61
+ this._region = new Vector4(0, 0, 0, 0);
62
+ this._params = new Vector4(0, 0, 1, 1);
63
+ this._dummy = null;
64
+ }
65
+ get terrain() {
66
+ return this._terrain;
67
+ }
68
+ get version() {
69
+ return this._version;
70
+ }
71
+ /** Sets the terrain and notices changes to it; call before the field updates. */ setTerrain(terrain) {
72
+ this._terrain = terrain;
73
+ const heightMap = terrain?.heightMap ?? null;
74
+ let key = '';
75
+ if (terrain && heightMap) {
76
+ const r = terrain.worldRegion;
77
+ this._region.setXYZW(r.x, r.y, r.z, r.w);
78
+ this._params.setXYZW(Math.abs(terrain.scale.y), terrain.worldMatrix.m13, 1 / heightMap.width, 1 / heightMap.height);
79
+ key = `${heightMap.uid}:${terrain.heightVersion}:${[
80
+ ...this._region,
81
+ ...this._params
82
+ ].join(',')}`;
83
+ } else {
84
+ this._region.setXYZW(0, 0, 0, 0);
85
+ }
86
+ if (key !== this._key) {
87
+ this._key = key;
88
+ this._version++;
89
+ }
90
+ }
91
+ declareUniforms(scope) {
92
+ const pb = scope.$builder;
93
+ scope.wlHeightMap = pb.tex2D().uniform(0);
94
+ // (min x, min z, max x, max z); empty for no terrain
95
+ scope.wlTerrainRegion = pb.vec4().uniform(0);
96
+ scope.wlTerrainParams = pb.vec4().uniform(0);
97
+ }
98
+ applyBindGroup(bindGroup) {
99
+ const heightMap = this._terrain?.heightMap ?? null;
100
+ bindGroup.setTexture('wlHeightMap', heightMap ?? this.getDummy(), fetchSampler('clamp_linear_nomip'));
101
+ bindGroup.setValue('wlTerrainRegion', this._region);
102
+ bindGroup.setValue('wlTerrainParams', this._params);
103
+ }
104
+ sampleDistance(scope, pos) {
105
+ const pb = scope.$builder;
106
+ pb.func('wlTerrainHeight', [
107
+ pb.vec2('xz')
108
+ ], function() {
109
+ this.$l.uv = pb.div(pb.sub(this.xz, this.wlTerrainRegion.xy), pb.sub(this.wlTerrainRegion.zw, this.wlTerrainRegion.xy));
110
+ this.$return(pb.add(pb.mul(pb.textureSampleLevel(this.wlHeightMap, this.uv, 0).r, this.wlTerrainParams.x), this.wlTerrainParams.y));
111
+ });
112
+ pb.func('wlTerrainDistance', [
113
+ pb.vec3('p')
114
+ ], function() {
115
+ this.$if(pb.or(pb.any(pb.lessThanEqual(this.wlTerrainRegion.zw, this.wlTerrainRegion.xy)), pb.or(pb.any(pb.lessThan(this.p.xz, this.wlTerrainRegion.xy)), pb.any(pb.greaterThan(this.p.xz, this.wlTerrainRegion.zw)))), function() {
116
+ this.$return(pb.float(TERRAIN_OFF_MAP));
117
+ });
118
+ this.$l.h = this.wlTerrainHeight(this.p.xz);
119
+ // Central differences one height map texel apart, in world units
120
+ this.$l.cell = pb.mul(pb.sub(this.wlTerrainRegion.zw, this.wlTerrainRegion.xy), this.wlTerrainParams.zw);
121
+ this.$l.hx = pb.sub(this.wlTerrainHeight(pb.add(this.p.xz, pb.vec2(this.cell.x, 0))), this.wlTerrainHeight(pb.sub(this.p.xz, pb.vec2(this.cell.x, 0))));
122
+ this.$l.hz = pb.sub(this.wlTerrainHeight(pb.add(this.p.xz, pb.vec2(0, this.cell.y))), this.wlTerrainHeight(pb.sub(this.p.xz, pb.vec2(0, this.cell.y))));
123
+ this.$l.grad = pb.div(pb.vec2(this.hx, this.hz), pb.mul(this.cell, 2));
124
+ this.$return(pb.div(pb.sub(this.p.y, this.h), pb.sqrt(pb.add(1, pb.dot(this.grad, this.grad)))));
125
+ });
126
+ return scope.wlTerrainDistance(pos);
127
+ }
128
+ dispose() {
129
+ this._dummy?.dispose();
130
+ this._dummy = null;
131
+ }
132
+ /** @internal */ getDummy() {
133
+ if (!this._dummy) {
134
+ this._dummy = getDevice().createTexture2D('r16f', 1, 1, {
135
+ mipmapping: false
136
+ });
137
+ }
138
+ return this._dummy;
139
+ }
140
+ }
141
+ /**
142
+ * Horizontal distance to the waterline around the camera: on square grids at
143
+ * the rest level of a body of water, the distance in world units from each
144
+ * cell to the nearest point where the ground pierces that level.
145
+ *
146
+ * Unlike the 3D distance to the nearest solid (the water depth over a gently
147
+ * shelving bed), this measures shoreline bands outwards from where the ground
148
+ * meets the water.
149
+ *
150
+ * Built on the GPU from a {@link WaterlineSource}: the global clipmap (static
151
+ * geometry and the terrain; dynamic instances, a boat or a car wading in, are
152
+ * not shores and would ring themselves with shore waves and foam) or the
153
+ * terrain alone. One or more levels, all centred on the camera, each twice the
154
+ * cell size of the one before. Per level:
155
+ *
156
+ * 1. Seed: a cell whose centre is inside the ground at the water level is its own nearest shore.
157
+ * 2. Jump flooding, log2(resolution) passes, carries the nearest seed across the grid.
158
+ * 3. Resolve, into an rgba16f texture:
159
+ * - x: distance to the nearest seed, the waterline at the rest level;
160
+ * - y, z: a linear model of the ground around the cell, A and B with the horizontal distance
161
+ * to the waterline at a height `level + dy` being `A + B * dy`;
162
+ * - w: the field value at the cell at the rest level, telling how far the linear model holds.
163
+ * 4. Smooth, into a layer of {@link WaterlineField.smoothTexture}.
164
+ *
165
+ * The linear model lets the waterline follow the waves (a surface raised by dy moves the edge
166
+ * dy / tan(a) inland on a slope of angle a). From the field value s and its gradient g at the rest
167
+ * level, the ground near the cell is the plane s + g.(p - p0) = 0, crossed at height dy
168
+ * (s + g.y * dy) / |g.xz| away horizontally: A = s / |g.xz|, B = g.y / |g.xz|. Exact for a planar
169
+ * bed; farther from the shore the jump-flooded distance is used.
170
+ *
171
+ * The jump-flooded distance is accurate to about half a cell. A level only sees
172
+ * the shores on its own grid, so near its edge the nearest one may lie off it.
173
+ * WebGPU only.
174
+ *
175
+ * @public
176
+ */ class WaterlineField {
177
+ levels;
178
+ resolution;
179
+ cellSize;
180
+ maxRebuilds;
181
+ _source;
182
+ _level;
183
+ _requested;
184
+ _seedA;
185
+ _seedB;
186
+ /** Seeds in the water, flooded for the distance inland from it; and the pass between. */ _wetA;
187
+ _wetB;
188
+ /** (field at the rest level, field half a cell above) per cell. */ _probe;
189
+ _result;
190
+ /** Smoothed shore coordinates, a layer per level, see {@link WaterlineField.smoothTexture}. */ _smooth;
191
+ _smoothTemp;
192
+ _smoothHProgram;
193
+ _smoothVProgram;
194
+ _seedProgram;
195
+ _jfaProgram;
196
+ _resolveProgram;
197
+ _bindGroups;
198
+ /** Per level: (origin x, origin z, cell size, resolution) as last built; 0 cells before it is. */ _regions;
199
+ /** Per level: source version, origin x, origin z and water level it was last built at. */ _builtAt;
200
+ constructor(source, options){
201
+ this._source = source;
202
+ this.levels = Math.max(1, Math.min(8, Math.floor(options?.levels ?? 1)));
203
+ this.resolution = Math.max(16, 2 ** Math.round(Math.log2(options?.resolution ?? 256)));
204
+ this.cellSize = Math.max(1e-3, options?.cellSize ?? 0.5);
205
+ this.maxRebuilds = Math.max(1, Math.floor(options?.maxRebuilds ?? this.levels));
206
+ this._level = null;
207
+ this._requested = false;
208
+ this._seedA = null;
209
+ this._seedB = null;
210
+ this._wetA = null;
211
+ this._wetB = null;
212
+ this._probe = null;
213
+ this._result = null;
214
+ this._smooth = null;
215
+ this._smoothTemp = null;
216
+ this._smoothHProgram = null;
217
+ this._smoothVProgram = null;
218
+ this._seedProgram = null;
219
+ this._jfaProgram = null;
220
+ this._resolveProgram = null;
221
+ this._bindGroups = [];
222
+ this._regions = Array.from({
223
+ length: this.levels
224
+ }, ()=>new Vector4(0, 0, 0, 0));
225
+ this._builtAt = Array.from({
226
+ length: this.levels
227
+ }, ()=>[
228
+ NaN,
229
+ NaN,
230
+ NaN,
231
+ NaN
232
+ ]);
233
+ }
234
+ /** Grids built so far, a level each, for diagnosis. */ get rebuilds() {
235
+ return this._rebuilds;
236
+ }
237
+ _rebuilds = 0;
238
+ /** What the field is built from. */ get source() {
239
+ return this._source;
240
+ }
241
+ /** World Y the field is built at, or null before anything asked for it. */ get level() {
242
+ return this._level;
243
+ }
244
+ /** True once the finest level has been built. */ get ready() {
245
+ return this._regions[0].w > 0;
246
+ }
247
+ /**
248
+ * Smooth shore coordinates per cell, an rgba16f array with a layer per
249
+ * level, for effects that build geometry on them (see ShoreWaveGenerator):
250
+ * (signed distance to the waterline, negative inland; B of the bed model;
251
+ * height of the bed over the rest level; 0). The first two are
252
+ * Gaussian-filtered over two cells; the bed height is the cell's own, so it
253
+ * matches the ground. Null before the finest level is built.
254
+ */ get smoothTexture() {
255
+ return this.ready ? this._smooth : null;
256
+ }
257
+ /**
258
+ * (rest-level distance, model A, model B, field at the rest level) per cell
259
+ * of the level built last, rgba16f: for a field of a single level, that level.
260
+ */ get texture() {
261
+ return this._result;
262
+ }
263
+ /** (origin x, origin z, cell size, resolution) of the finest level, for sampling. */ get region() {
264
+ return this._regions[0];
265
+ }
266
+ /** (origin x, origin z, cell size, resolution) per level; 0 cells for a level not built yet. */ get regions() {
267
+ return this._regions;
268
+ }
269
+ /**
270
+ * Asks for the field at a water level this frame. Without a request in a
271
+ * frame it is not rebuilt; with several, the last one wins.
272
+ */ request(level) {
273
+ this._level = level;
274
+ this._requested = true;
275
+ }
276
+ /** Rebuilds the levels around the camera that moved or went stale, when requested. */ update(cameraPos) {
277
+ if (!this._requested || this._level === null) {
278
+ return;
279
+ }
280
+ this._requested = false;
281
+ this.ensureResources();
282
+ const version = this._source.version;
283
+ let budget = this.maxRebuilds;
284
+ // Finest first: it is the one the camera moves out of soonest and the one
285
+ // seen up close; a coarser level waiting a frame keeps its old grid, which
286
+ // its region still describes
287
+ for(let i = 0; i < this.levels && budget > 0; i++){
288
+ const h = this.cellSize * 2 ** i;
289
+ const n = this.resolution;
290
+ // Snapped to cells, so the grid does not swim as the camera moves
291
+ const ox = (Math.floor(cameraPos.x / h) - n / 2) * h;
292
+ const oz = (Math.floor(cameraPos.z / h) - n / 2) * h;
293
+ const at = this._builtAt[i];
294
+ if (this._regions[i].w > 0 && at[0] === version && at[1] === ox && at[2] === oz && at[3] === this._level) {
295
+ continue;
296
+ }
297
+ at[0] = version;
298
+ at[1] = ox;
299
+ at[2] = oz;
300
+ at[3] = this._level;
301
+ this.buildLevel(i, ox, oz, h);
302
+ this._regions[i].setXYZW(ox, oz, h, n);
303
+ this._rebuilds++;
304
+ budget--;
305
+ }
306
+ }
307
+ dispose() {
308
+ this._seedA?.dispose();
309
+ this._seedB?.dispose();
310
+ this._wetA?.dispose();
311
+ this._wetB?.dispose();
312
+ this._probe?.dispose();
313
+ this._result?.dispose();
314
+ this._smooth?.dispose();
315
+ this._smoothTemp?.dispose();
316
+ this._seedA = this._seedB = this._wetA = this._wetB = null;
317
+ this._probe = this._result = this._smoothTemp = null;
318
+ this._smooth = null;
319
+ for (const bgs of this._bindGroups){
320
+ bgs.seed.dispose();
321
+ bgs.resolve.dispose();
322
+ for (const bg of [
323
+ ...bgs.jfa,
324
+ ...bgs.wetJfa,
325
+ ...bgs.smooth
326
+ ]){
327
+ bg.dispose();
328
+ }
329
+ }
330
+ this._bindGroups = [];
331
+ for (const r of this._regions){
332
+ r.setXYZW(0, 0, 0, 0);
333
+ }
334
+ }
335
+ /** Builds one level into its layer of the smoothed array. @internal */ buildLevel(index, ox, oz, h) {
336
+ const device = getDevice();
337
+ const n = this.resolution;
338
+ const groups = n / WORKGROUP;
339
+ const bgs = this._bindGroups[index];
340
+ // Seed
341
+ const seedBG = bgs.seed;
342
+ seedBG.setValue('grid', new Vector4(ox, oz, h, this._level));
343
+ seedBG.setTexture('seedOut', this._seedA);
344
+ seedBG.setTexture('wetOut', this._wetA);
345
+ seedBG.setTexture('probeOut', this._probe);
346
+ this._source.applyBindGroup(seedBG);
347
+ device.setProgram(this._seedProgram);
348
+ device.setBindGroup(0, seedBG);
349
+ device.compute(groups, groups, 1);
350
+ // Jump flooding, halving the step down to one cell, from the shore and from the water side
351
+ const flood = (a, b, bindGroups)=>{
352
+ let src = a;
353
+ let dst = b;
354
+ let pass = 0;
355
+ for(let step = n / 2; step >= 1; step >>= 1, pass++){
356
+ const bg = bindGroups[pass];
357
+ bg.setValue('step', new Vector4(step, n, 0, 0));
358
+ bg.setTexture('seedIn', src, fetchSampler('clamp_nearest_nomip'));
359
+ bg.setTexture('seedOut', dst);
360
+ device.setProgram(this._jfaProgram);
361
+ device.setBindGroup(0, bg);
362
+ device.compute(groups, groups, 1);
363
+ const t = src;
364
+ src = dst;
365
+ dst = t;
366
+ }
367
+ return src;
368
+ };
369
+ const seeds = flood(this._seedA, this._seedB, bgs.jfa);
370
+ const wet = flood(this._wetA, this._wetB, bgs.wetJfa);
371
+ // Resolve
372
+ const rbg = bgs.resolve;
373
+ rbg.setValue('grid', new Vector4(ox, oz, h, n));
374
+ rbg.setTexture('seedIn', seeds, fetchSampler('clamp_nearest_nomip'));
375
+ rbg.setTexture('probeIn', this._probe, fetchSampler('clamp_nearest_nomip'));
376
+ rbg.setTexture('result', this._result);
377
+ device.setProgram(this._resolveProgram);
378
+ device.setBindGroup(0, rbg);
379
+ device.compute(groups, groups, 1);
380
+ // Smooth, separably: the first pass also turns the result into the signed distance
381
+ for(let pass = 0; pass < 2; pass++){
382
+ const bg = bgs.smooth[pass];
383
+ bg.setValue('smoothPass', new Vector4(pass, n, h, index));
384
+ bg.setTexture('wetIn', wet, fetchSampler('clamp_nearest_nomip'));
385
+ bg.setTexture('src', pass === 0 ? this._result : this._smoothTemp, fetchSampler('clamp_nearest_nomip'));
386
+ bg.setTexture('dst', pass === 0 ? this._smoothTemp : this._smooth);
387
+ device.setProgram(pass === 0 ? this._smoothHProgram : this._smoothVProgram);
388
+ device.setBindGroup(0, bg);
389
+ device.compute(groups, groups, 1);
390
+ }
391
+ }
392
+ /** @internal */ ensureResources() {
393
+ if (this._seedProgram) {
394
+ return;
395
+ }
396
+ const device = getDevice();
397
+ const n = this.resolution;
398
+ const tex = (format)=>device.createTexture2D(format, n, n, {
399
+ mipmapping: false,
400
+ writable: true
401
+ });
402
+ this._seedA = tex('rg32f');
403
+ this._seedB = tex('rg32f');
404
+ this._wetA = tex('rg32f');
405
+ this._wetB = tex('rg32f');
406
+ this._probe = tex('rg32f');
407
+ this._result = tex('rgba16f');
408
+ this._result.name = `@Waterline${this._source.label}`;
409
+ this._smoothTemp = tex('rgba16f');
410
+ this._smooth = device.createTexture2DArray('rgba16f', n, n, this.levels, {
411
+ mipmapping: false,
412
+ writable: true
413
+ });
414
+ this._smooth.name = `@Waterline${this._source.label}Smooth`;
415
+ const source = this._source;
416
+ this._seedProgram = buildSDFProgram({
417
+ label: `WaterlineSeed${source.label}`,
418
+ workgroupSize: [
419
+ WORKGROUP,
420
+ WORKGROUP,
421
+ 1
422
+ ],
423
+ compute (pb) {
424
+ // (origin x, origin z, cell size, water level)
425
+ this.grid = pb.vec4().uniform(0);
426
+ this.seedOut = pb.texStorage2D.rg32float().storage(0);
427
+ this.wetOut = pb.texStorage2D.rg32float().storage(0);
428
+ this.probeOut = pb.texStorage2D.rg32float().storage(0);
429
+ source.declareUniforms(this);
430
+ pb.main(function() {
431
+ this.$l.id = this.$builtins.globalInvocationId.xy;
432
+ this.$l.xz = pb.add(this.grid.xy, pb.mul(pb.add(pb.vec2(this.id), pb.vec2(0.5)), this.grid.z));
433
+ this.$l.d = source.sampleDistance(this, pb.vec3(this.xz.x, this.grid.w, this.xz.y));
434
+ // Half a cell up, for the vertical slope of the field
435
+ this.$l.dUp = source.sampleDistance(this, pb.vec3(this.xz.x, pb.add(this.grid.w, pb.mul(this.grid.z, 0.5)), this.xz.y));
436
+ pb.textureStore(this.probeOut, this.id, pb.vec4(this.d, this.dUp, 0, 0));
437
+ pb.textureStore(this.seedOut, this.id, this.$choice(pb.lessThan(this.d, 0), pb.vec4(pb.vec2(this.id), 0, 0), pb.vec4(NO_SEED, NO_SEED, 0, 0)));
438
+ pb.textureStore(this.wetOut, this.id, this.$choice(pb.lessThan(this.d, 0), pb.vec4(NO_SEED, NO_SEED, 0, 0), pb.vec4(pb.vec2(this.id), 0, 0)));
439
+ });
440
+ }
441
+ });
442
+ this._jfaProgram = buildSDFProgram({
443
+ label: 'WaterlineJFA',
444
+ workgroupSize: [
445
+ WORKGROUP,
446
+ WORKGROUP,
447
+ 1
448
+ ],
449
+ compute (pb) {
450
+ // (step, resolution, 0, 0)
451
+ this.step = pb.vec4().uniform(0);
452
+ this.seedIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
453
+ this.seedOut = pb.texStorage2D.rg32float().storage(0);
454
+ pb.main(function() {
455
+ this.$l.id = pb.ivec2(this.$builtins.globalInvocationId.xy);
456
+ this.$l.n = pb.int(this.step.y);
457
+ this.$l.s = pb.int(this.step.x);
458
+ this.$l.p = pb.vec2(this.id);
459
+ this.$l.best = pb.textureLoad(this.seedIn, this.id, 0).xy;
460
+ this.$l.bestD = pb.dot(pb.sub(this.best, this.p), pb.sub(this.best, this.p));
461
+ for(let dy = -1; dy <= 1; dy++){
462
+ for(let dx = -1; dx <= 1; dx++){
463
+ if (dx === 0 && dy === 0) {
464
+ continue;
465
+ }
466
+ this.$l.q = pb.add(this.id, pb.mul(pb.ivec2(dx, dy), this.s));
467
+ this.$if(pb.and(pb.all(pb.greaterThanEqual(this.q, pb.ivec2(0))), pb.all(pb.lessThan(this.q, pb.ivec2(this.n)))), function() {
468
+ this.$l.c = pb.textureLoad(this.seedIn, this.q, 0).xy;
469
+ this.$l.cd = pb.dot(pb.sub(this.c, this.p), pb.sub(this.c, this.p));
470
+ this.$if(pb.lessThan(this.cd, this.bestD), function() {
471
+ this.best = this.c;
472
+ this.bestD = this.cd;
473
+ });
474
+ });
475
+ }
476
+ }
477
+ pb.textureStore(this.seedOut, pb.uvec2(this.id), pb.vec4(this.best, 0, 0));
478
+ });
479
+ }
480
+ });
481
+ this._resolveProgram = buildSDFProgram({
482
+ label: 'WaterlineResolve',
483
+ workgroupSize: [
484
+ WORKGROUP,
485
+ WORKGROUP,
486
+ 1
487
+ ],
488
+ compute (pb) {
489
+ // (origin x, origin z, cell size, resolution)
490
+ this.grid = pb.vec4().uniform(0);
491
+ this.seedIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
492
+ this.probeIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
493
+ this.result = pb.texStorage2D.rgba16float().storage(0);
494
+ pb.main(function() {
495
+ this.$l.id = this.$builtins.globalInvocationId.xy;
496
+ this.$l.p = pb.vec2(this.id);
497
+ this.$l.seed = pb.textureLoad(this.seedIn, pb.ivec2(this.id), 0).xy;
498
+ this.$l.v = pb.sub(this.p, this.seed);
499
+ this.$l.len = pb.length(this.v);
500
+ // A seed is a whole solid cell: the shore is half a cell nearer than its centre
501
+ this.$l.dist = pb.mul(pb.max(pb.sub(this.len, 0.5), 0), this.grid.z);
502
+ // No shore anywhere on the grid: as far as the grid reaches
503
+ this.dist = this.$choice(pb.lessThan(this.seed.x, NO_SEED * 0.5), pb.mul(this.grid.w, this.grid.z), this.dist);
504
+ // Gradient of the field at the rest level: horizontally from the neighbouring
505
+ // cells (one-sided at the grid edge), vertically from the probe above
506
+ this.$l.ip = pb.ivec2(this.id);
507
+ this.$l.last = pb.sub(pb.int(this.grid.w), 1);
508
+ this.$l.probe = pb.textureLoad(this.probeIn, this.ip, 0).xy;
509
+ this.$l.xl = pb.max(pb.sub(this.ip.x, 1), 0);
510
+ this.$l.xr = pb.min(pb.add(this.ip.x, 1), this.last);
511
+ this.$l.zl = pb.max(pb.sub(this.ip.y, 1), 0);
512
+ this.$l.zr = pb.min(pb.add(this.ip.y, 1), this.last);
513
+ this.$l.gx = pb.div(pb.sub(pb.textureLoad(this.probeIn, pb.ivec2(this.xr, this.ip.y), 0).x, pb.textureLoad(this.probeIn, pb.ivec2(this.xl, this.ip.y), 0).x), pb.mul(pb.float(pb.sub(this.xr, this.xl)), this.grid.z));
514
+ this.$l.gz = pb.div(pb.sub(pb.textureLoad(this.probeIn, pb.ivec2(this.ip.x, this.zr), 0).x, pb.textureLoad(this.probeIn, pb.ivec2(this.ip.x, this.zl), 0).x), pb.mul(pb.float(pb.sub(this.zr, this.zl)), this.grid.z));
515
+ this.$l.gy = pb.div(pb.sub(this.probe.y, this.probe.x), pb.mul(this.grid.z, 0.5));
516
+ // A flat bed never meets the water: the model then says far away
517
+ this.$l.gh = pb.max(pb.length(pb.vec2(this.gx, this.gz)), WATERLINE_MIN_SLOPE);
518
+ this.$l.a = pb.clamp(pb.div(this.probe.x, this.gh), -1e4, WATERLINE_MODEL_CLAMP);
519
+ this.$l.b = pb.clamp(pb.div(this.gy, this.gh), -1e4, WATERLINE_MODEL_CLAMP);
520
+ pb.textureStore(this.result, this.id, pb.vec4(this.dist, this.a, this.b, this.probe.x));
521
+ });
522
+ }
523
+ });
524
+ this._smoothHProgram = buildSmoothProgram(false);
525
+ this._smoothVProgram = buildSmoothProgram(true);
526
+ const passes = Math.log2(n);
527
+ for(let i = 0; i < this.levels; i++){
528
+ this._bindGroups.push({
529
+ seed: device.createBindGroup(this._seedProgram.bindGroupLayouts[0]),
530
+ jfa: Array.from({
531
+ length: passes
532
+ }, ()=>device.createBindGroup(this._jfaProgram.bindGroupLayouts[0])),
533
+ wetJfa: Array.from({
534
+ length: passes
535
+ }, ()=>device.createBindGroup(this._jfaProgram.bindGroupLayouts[0])),
536
+ resolve: device.createBindGroup(this._resolveProgram.bindGroupLayouts[0]),
537
+ smooth: [
538
+ device.createBindGroup(this._smoothHProgram.bindGroupLayouts[0]),
539
+ device.createBindGroup(this._smoothVProgram.bindGroupLayouts[0])
540
+ ]
541
+ });
542
+ }
543
+ }
544
+ }
545
+ /**
546
+ * One pass of the separable smoothing: horizontal from the resolved field
547
+ * into a scratch texture, or vertical from it into a level's layer.
548
+ */ function buildSmoothProgram(toArray) {
549
+ return buildSDFProgram({
550
+ label: toArray ? 'WaterlineSmoothV' : 'WaterlineSmoothH',
551
+ workgroupSize: [
552
+ WORKGROUP,
553
+ WORKGROUP,
554
+ 1
555
+ ],
556
+ compute (pb) {
557
+ // (pass: 0 horizontal from the resolved field, 1 vertical; resolution; cell size; layer)
558
+ this.smoothPass = pb.vec4().uniform(0);
559
+ this.src = pb.tex2D().sampleType('unfilterable-float').uniform(0);
560
+ // Nearest cell in the water, for the distance inland
561
+ this.wetIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
562
+ this.dst = toArray ? pb.texStorage2DArray.rgba16float().storage(0) : pb.texStorage2D.rgba16float().storage(0);
563
+ // Signed distance and B of a resolved texel: the bed model near the
564
+ // shore, the jump-flooded distance farther out, blended over a couple
565
+ // of metres. Inland, away from the model, the negated jump-flooded
566
+ // distance from the water side (the resolved distance is 0 on land).
567
+ pb.func('wlSigned', [
568
+ pb.vec4('t'),
569
+ pb.ivec2('q')
570
+ ], function() {
571
+ this.$l.model = pb.and(pb.lessThan(pb.abs(this.t.w), SMOOTH_MODEL_REACH), pb.lessThan(pb.abs(this.t.y), SMOOTH_MODEL_CLAMP));
572
+ this.$l.wet = pb.textureLoad(this.wetIn, this.q, 0).xy;
573
+ this.$l.inland = this.$choice(pb.lessThan(this.wet.x, NO_SEED * 0.5), pb.mul(this.smoothPass.y, this.smoothPass.z), pb.mul(pb.max(pb.sub(pb.length(pb.sub(pb.vec2(this.q), this.wet)), 0.5), 0), this.smoothPass.z));
574
+ this.$l.far = this.$choice(pb.lessThan(this.t.w, 0), pb.neg(this.inland), this.t.x);
575
+ this.$l.w = this.$choice(this.model, pb.smoothStep(SMOOTH_BLEND_START, SMOOTH_BLEND_END, pb.abs(this.far)), 1);
576
+ this.$return(pb.vec2(pb.mix(this.t.y, this.far, this.w), this.$choice(this.model, this.t.z, 0)));
577
+ });
578
+ pb.main(function() {
579
+ this.$l.id = pb.ivec2(this.$builtins.globalInvocationId.xy);
580
+ this.$l.last = pb.sub(pb.int(this.smoothPass.y), 1);
581
+ this.$l.axis = toArray ? pb.ivec2(0, 1) : pb.ivec2(1, 0);
582
+ this.$l.acc = pb.vec2(0);
583
+ this.$l.wsum = pb.float(0);
584
+ for(let k = -4; k <= SMOOTH_RADIUS; k++){
585
+ const w = Math.exp(-(k * k) / (2 * SMOOTH_SIGMA * SMOOTH_SIGMA));
586
+ this.$l.q = pb.clamp(pb.add(this.id, pb.mul(this.axis, k)), pb.ivec2(0), pb.ivec2(this.last));
587
+ this.$l.t = pb.textureLoad(this.src, this.q, 0);
588
+ this.$l.v = toArray ? this.t.xy : this.wlSigned(this.t, this.q);
589
+ this.acc = pb.add(this.acc, pb.mul(this.v, w));
590
+ this.wsum = pb.add(this.wsum, w);
591
+ }
592
+ // Keep the bed unfiltered; the second pass carries its height through.
593
+ this.$l.own = pb.textureLoad(this.src, this.id, 0);
594
+ if (toArray) {
595
+ pb.textureArrayStore(this.dst, pb.uvec2(this.id), pb.int(this.smoothPass.w), pb.vec4(pb.div(this.acc, this.wsum), this.own.z, 0));
596
+ } else {
597
+ this.$l.bed = pb.neg(this.own.w);
598
+ this.$if(pb.and(pb.lessThan(pb.abs(this.own.w), SMOOTH_MODEL_REACH), pb.and(pb.lessThan(pb.abs(this.own.y), SMOOTH_MODEL_CLAMP), pb.and(pb.greaterThan(this.own.z, 1e-3), pb.lessThan(this.own.z, WATERLINE_MODEL_CLAMP)))), function() {
599
+ // A + B * dy = 0 gives vertical bed height; -SDF is a normal distance.
600
+ this.bed = pb.div(pb.neg(this.own.y), this.own.z);
601
+ });
602
+ pb.textureStore(this.dst, pb.uvec2(this.id), pb.vec4(pb.div(this.acc, this.wsum), this.bed, 0));
603
+ }
604
+ });
605
+ }
606
+ });
607
+ }
608
+
609
+ export { SDFWaterlineSource, TerrainWaterlineSource, WaterlineField };
610
+ //# sourceMappingURL=waterline.js.map