@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,227 @@
1
+ import { getDevice } from '../../app/api.js';
2
+ import { VolumeBoxAllocator } from './box_allocator.js';
3
+
4
+ /** Allocation granularity of the atlas in voxels, per axis. */ const SDF_ATLAS_BLOCK = 8;
5
+ /**
6
+ * A 3D `r16f` texture shared by the resident mesh distance fields, each in a block-aligned region
7
+ * from a guillotine allocator. When an allocation no longer fits, everything is repacked on trial
8
+ * and committed only if all fit; uploads are deferred to {@link MeshSDFAtlas.flush} under a byte
9
+ * budget. Works on WebGL2 and WebGPU.
10
+ *
11
+ * @public
12
+ */ class MeshSDFAtlas {
13
+ size;
14
+ _texture;
15
+ _allocator;
16
+ _entries;
17
+ _usedVoxels;
18
+ _version;
19
+ constructor(size = [
20
+ 256,
21
+ 256,
22
+ 256
23
+ ]){
24
+ this.size = size.map((v)=>Math.max(SDF_ATLAS_BLOCK, Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK));
25
+ this._texture = null;
26
+ this._allocator = new VolumeBoxAllocator(this.size);
27
+ this._entries = new Map();
28
+ this._usedVoxels = 0;
29
+ this._version = 0;
30
+ }
31
+ /** The atlas texture, created on first use. */ get texture() {
32
+ if (!this._texture) {
33
+ const [w, h, d] = this.size;
34
+ this._texture = getDevice().createTexture3D('r16f', w, h, d, {
35
+ mipmapping: false
36
+ });
37
+ this._texture.name = '@MeshSDFAtlas';
38
+ // Earlier uploads had no texture; redo them
39
+ for (const entry of this._entries.values()){
40
+ entry.uploaded = false;
41
+ }
42
+ }
43
+ return this._texture;
44
+ }
45
+ /** Fields resident in the atlas. */ get count() {
46
+ return this._entries.size;
47
+ }
48
+ /** Share of the atlas allocated to fields, 0 to 1. */ get occupancy() {
49
+ return this._usedVoxels / (this.size[0] * this.size[1] * this.size[2]);
50
+ }
51
+ /** Bumped whenever a slot moves or is removed, so users of slot offsets can refresh them. */ get version() {
52
+ return this._version;
53
+ }
54
+ /** Fields waiting to be uploaded. */ get pendingUploads() {
55
+ let n = 0;
56
+ for (const entry of this._entries.values()){
57
+ n += entry.uploaded ? 0 : 1;
58
+ }
59
+ return n;
60
+ }
61
+ /** The slot of a resident field, or null. */ getSlot(key) {
62
+ return this._entries.get(key)?.slot ?? null;
63
+ }
64
+ /** True when the field is resident and its voxels are on the GPU. */ isReady(key) {
65
+ return !!this._entries.get(key)?.uploaded;
66
+ }
67
+ /**
68
+ * Allocates a region for a field and queues its upload.
69
+ * @param key - Identity of the field, used to look it up and free it.
70
+ * @param resolution - Voxels per axis.
71
+ * @param voxels - Half floats, x fastest; kept by reference.
72
+ * @returns The slot, or null when the atlas is full.
73
+ */ add(key, resolution, voxels) {
74
+ const existing = this._entries.get(key);
75
+ if (existing) {
76
+ return existing.slot;
77
+ }
78
+ const need = this.blockAligned(resolution);
79
+ if (need[0] > this.size[0] || need[1] > this.size[1] || need[2] > this.size[2]) {
80
+ return null;
81
+ }
82
+ const box = this._allocator.allocate(need) ?? this.repack(need);
83
+ if (!box) {
84
+ return null;
85
+ }
86
+ const entry = {
87
+ key,
88
+ slot: {
89
+ offset: [
90
+ box.x,
91
+ box.y,
92
+ box.z
93
+ ],
94
+ resolution: [
95
+ ...resolution
96
+ ]
97
+ },
98
+ box,
99
+ voxels,
100
+ uploaded: false
101
+ };
102
+ this._entries.set(key, entry);
103
+ this._usedVoxels += box.w * box.h * box.d;
104
+ return entry.slot;
105
+ }
106
+ /**
107
+ * True when a field of this resolution would fit alongside only the fields of `keep`, packed
108
+ * from scratch. Changes nothing; tells a caller whether evicting is worth it.
109
+ */ fits(resolution, keep) {
110
+ const sizes = [
111
+ this.blockAligned(resolution)
112
+ ];
113
+ for (const key of keep){
114
+ const box = this._entries.get(key)?.box;
115
+ if (box) {
116
+ sizes.push([
117
+ box.w,
118
+ box.h,
119
+ box.d
120
+ ]);
121
+ }
122
+ }
123
+ sizes.sort((a, b)=>b[0] * b[1] * b[2] - a[0] * a[1] * a[2]);
124
+ const allocator = new VolumeBoxAllocator(this.size);
125
+ return sizes.every((size)=>!!allocator.allocate(size));
126
+ }
127
+ /** Frees the region of a field. */ remove(key) {
128
+ const entry = this._entries.get(key);
129
+ if (entry) {
130
+ this._entries.delete(key);
131
+ this._allocator.free(entry.box);
132
+ this._usedVoxels -= entry.box.w * entry.box.h * entry.box.d;
133
+ this._version++;
134
+ }
135
+ }
136
+ /**
137
+ * Uploads queued fields, nearest-first in the order they were added, until
138
+ * the byte budget is spent. At least one field is uploaded per call.
139
+ * @returns Keys of the fields that became ready.
140
+ */ flush(byteBudget = 4 * 1024 * 1024) {
141
+ const ready = [];
142
+ let spent = 0;
143
+ for (const entry of this._entries.values()){
144
+ if (entry.uploaded) {
145
+ continue;
146
+ }
147
+ const bytes = entry.voxels.byteLength;
148
+ if (ready.length > 0 && spent + bytes > byteBudget) {
149
+ break;
150
+ }
151
+ const [x, y, z] = entry.slot.offset;
152
+ const [w, h, d] = entry.slot.resolution;
153
+ this.texture.update(entry.voxels, x, y, z, w, h, d);
154
+ entry.uploaded = true;
155
+ spent += bytes;
156
+ ready.push(entry.key);
157
+ }
158
+ return ready;
159
+ }
160
+ dispose() {
161
+ this._texture?.dispose();
162
+ this._texture = null;
163
+ this._entries.clear();
164
+ this._allocator.reset();
165
+ this._usedVoxels = 0;
166
+ this._version++;
167
+ }
168
+ /** @internal */ blockAligned(resolution) {
169
+ return resolution.map((v)=>Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK);
170
+ }
171
+ /**
172
+ * Repacks the resident fields plus a new region from scratch, largest first, on a trial
173
+ * allocator; commits only when everything fits, re-uploading only fields that moved.
174
+ * @returns The box of the new region, or null with the atlas unchanged.
175
+ * @internal
176
+ */ repack(need) {
177
+ const items = [
178
+ {
179
+ entry: null,
180
+ size: need
181
+ },
182
+ ...[
183
+ ...this._entries.values()
184
+ ].map((entry)=>({
185
+ entry,
186
+ size: [
187
+ entry.box.w,
188
+ entry.box.h,
189
+ entry.box.d
190
+ ]
191
+ }))
192
+ ].sort((a, b)=>b.size[0] * b.size[1] * b.size[2] - a.size[0] * a.size[1] * a.size[2]);
193
+ const allocator = new VolumeBoxAllocator(this.size);
194
+ const boxes = [];
195
+ for (const item of items){
196
+ const box = allocator.allocate(item.size);
197
+ if (!box) {
198
+ return null;
199
+ }
200
+ boxes.push(box);
201
+ }
202
+ this._allocator = allocator;
203
+ this._version++;
204
+ let result = null;
205
+ for(let i = 0; i < items.length; i++){
206
+ const entry = items[i].entry;
207
+ const box = boxes[i];
208
+ if (!entry) {
209
+ result = box;
210
+ continue;
211
+ }
212
+ if (entry.box.x !== box.x || entry.box.y !== box.y || entry.box.z !== box.z) {
213
+ entry.slot.offset = [
214
+ box.x,
215
+ box.y,
216
+ box.z
217
+ ];
218
+ entry.uploaded = false;
219
+ }
220
+ entry.box = box;
221
+ }
222
+ return result;
223
+ }
224
+ }
225
+
226
+ export { MeshSDFAtlas, SDF_ATLAS_BLOCK };
227
+ //# sourceMappingURL=sdf_atlas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdf_atlas.js","sources":["../../../src/render/sdf/sdf_atlas.ts"],"sourcesContent":["import type { Texture3D } from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { getDevice } from '../../app/api';\r\nimport { VolumeBoxAllocator } from './box_allocator';\r\nimport type { VolumeBox } from './box_allocator';\r\n\r\n/** Allocation granularity of the atlas in voxels, per axis. */\r\nexport const SDF_ATLAS_BLOCK = 8;\r\n\r\n/**\r\n * A region of the atlas holding one mesh field.\r\n * @public\r\n */\r\nexport interface MeshSDFAtlasSlot {\r\n /** Voxel offset of the region in the atlas. */\r\n offset: [number, number, number];\r\n /** Voxels of the field, at most the region size. */\r\n resolution: [number, number, number];\r\n}\r\n\r\ninterface Entry {\r\n key: object;\r\n slot: MeshSDFAtlasSlot;\r\n box: VolumeBox;\r\n voxels: Uint16Array<ArrayBuffer>;\r\n uploaded: boolean;\r\n}\r\n\r\n/**\r\n * A 3D `r16f` texture shared by the resident mesh distance fields, each in a block-aligned region\r\n * from a guillotine allocator. When an allocation no longer fits, everything is repacked on trial\r\n * and committed only if all fit; uploads are deferred to {@link MeshSDFAtlas.flush} under a byte\r\n * budget. Works on WebGL2 and WebGPU.\r\n *\r\n * @public\r\n */\r\nexport class MeshSDFAtlas {\r\n readonly size: [number, number, number];\r\n private _texture: Nullable<Texture3D>;\r\n private _allocator: VolumeBoxAllocator;\r\n private readonly _entries: Map<object, Entry>;\r\n private _usedVoxels: number;\r\n private _version: number;\r\n constructor(size: [number, number, number] = [256, 256, 256]) {\r\n this.size = size.map((v) =>\r\n Math.max(SDF_ATLAS_BLOCK, Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK)\r\n ) as [number, number, number];\r\n this._texture = null;\r\n this._allocator = new VolumeBoxAllocator(this.size);\r\n this._entries = new Map();\r\n this._usedVoxels = 0;\r\n this._version = 0;\r\n }\r\n /** The atlas texture, created on first use. */\r\n get texture() {\r\n if (!this._texture) {\r\n const [w, h, d] = this.size;\r\n this._texture = getDevice().createTexture3D('r16f', w, h, d, { mipmapping: false })!;\r\n this._texture.name = '@MeshSDFAtlas';\r\n // Earlier uploads had no texture; redo them\r\n for (const entry of this._entries.values()) {\r\n entry.uploaded = false;\r\n }\r\n }\r\n return this._texture;\r\n }\r\n /** Fields resident in the atlas. */\r\n get count() {\r\n return this._entries.size;\r\n }\r\n /** Share of the atlas allocated to fields, 0 to 1. */\r\n get occupancy() {\r\n return this._usedVoxels / (this.size[0] * this.size[1] * this.size[2]);\r\n }\r\n /** Bumped whenever a slot moves or is removed, so users of slot offsets can refresh them. */\r\n get version() {\r\n return this._version;\r\n }\r\n /** Fields waiting to be uploaded. */\r\n get pendingUploads() {\r\n let n = 0;\r\n for (const entry of this._entries.values()) {\r\n n += entry.uploaded ? 0 : 1;\r\n }\r\n return n;\r\n }\r\n /** The slot of a resident field, or null. */\r\n getSlot(key: object) {\r\n return this._entries.get(key)?.slot ?? null;\r\n }\r\n /** True when the field is resident and its voxels are on the GPU. */\r\n isReady(key: object) {\r\n return !!this._entries.get(key)?.uploaded;\r\n }\r\n /**\r\n * Allocates a region for a field and queues its upload.\r\n * @param key - Identity of the field, used to look it up and free it.\r\n * @param resolution - Voxels per axis.\r\n * @param voxels - Half floats, x fastest; kept by reference.\r\n * @returns The slot, or null when the atlas is full.\r\n */\r\n add(\r\n key: object,\r\n resolution: [number, number, number],\r\n voxels: Uint16Array<ArrayBuffer>\r\n ): Nullable<MeshSDFAtlasSlot> {\r\n const existing = this._entries.get(key);\r\n if (existing) {\r\n return existing.slot;\r\n }\r\n const need = this.blockAligned(resolution);\r\n if (need[0] > this.size[0] || need[1] > this.size[1] || need[2] > this.size[2]) {\r\n return null;\r\n }\r\n const box = this._allocator.allocate(need) ?? this.repack(need);\r\n if (!box) {\r\n return null;\r\n }\r\n const entry: Entry = {\r\n key,\r\n slot: { offset: [box.x, box.y, box.z], resolution: [...resolution] },\r\n box,\r\n voxels,\r\n uploaded: false\r\n };\r\n this._entries.set(key, entry);\r\n this._usedVoxels += box.w * box.h * box.d;\r\n return entry.slot;\r\n }\r\n /**\r\n * True when a field of this resolution would fit alongside only the fields of `keep`, packed\r\n * from scratch. Changes nothing; tells a caller whether evicting is worth it.\r\n */\r\n fits(resolution: [number, number, number], keep: Iterable<object>) {\r\n const sizes: [number, number, number][] = [this.blockAligned(resolution)];\r\n for (const key of keep) {\r\n const box = this._entries.get(key)?.box;\r\n if (box) {\r\n sizes.push([box.w, box.h, box.d]);\r\n }\r\n }\r\n sizes.sort((a, b) => b[0] * b[1] * b[2] - a[0] * a[1] * a[2]);\r\n const allocator = new VolumeBoxAllocator(this.size);\r\n return sizes.every((size) => !!allocator.allocate(size));\r\n }\r\n /** Frees the region of a field. */\r\n remove(key: object) {\r\n const entry = this._entries.get(key);\r\n if (entry) {\r\n this._entries.delete(key);\r\n this._allocator.free(entry.box);\r\n this._usedVoxels -= entry.box.w * entry.box.h * entry.box.d;\r\n this._version++;\r\n }\r\n }\r\n /**\r\n * Uploads queued fields, nearest-first in the order they were added, until\r\n * the byte budget is spent. At least one field is uploaded per call.\r\n * @returns Keys of the fields that became ready.\r\n */\r\n flush(byteBudget = 4 * 1024 * 1024) {\r\n const ready: object[] = [];\r\n let spent = 0;\r\n for (const entry of this._entries.values()) {\r\n if (entry.uploaded) {\r\n continue;\r\n }\r\n const bytes = entry.voxels.byteLength;\r\n if (ready.length > 0 && spent + bytes > byteBudget) {\r\n break;\r\n }\r\n const [x, y, z] = entry.slot.offset;\r\n const [w, h, d] = entry.slot.resolution;\r\n this.texture.update(entry.voxels, x, y, z, w, h, d);\r\n entry.uploaded = true;\r\n spent += bytes;\r\n ready.push(entry.key);\r\n }\r\n return ready;\r\n }\r\n dispose() {\r\n this._texture?.dispose();\r\n this._texture = null;\r\n this._entries.clear();\r\n this._allocator.reset();\r\n this._usedVoxels = 0;\r\n this._version++;\r\n }\r\n /** @internal */\r\n private blockAligned(resolution: [number, number, number]) {\r\n return resolution.map((v) => Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK) as [\r\n number,\r\n number,\r\n number\r\n ];\r\n }\r\n /**\r\n * Repacks the resident fields plus a new region from scratch, largest first, on a trial\r\n * allocator; commits only when everything fits, re-uploading only fields that moved.\r\n * @returns The box of the new region, or null with the atlas unchanged.\r\n * @internal\r\n */\r\n private repack(need: [number, number, number]): Nullable<VolumeBox> {\r\n const items: { entry: Nullable<Entry>; size: [number, number, number] }[] = [\r\n { entry: null, size: need },\r\n ...[...this._entries.values()].map((entry) => ({\r\n entry,\r\n size: [entry.box.w, entry.box.h, entry.box.d] as [number, number, number]\r\n }))\r\n ].sort((a, b) => b.size[0] * b.size[1] * b.size[2] - a.size[0] * a.size[1] * a.size[2]);\r\n const allocator = new VolumeBoxAllocator(this.size);\r\n const boxes: VolumeBox[] = [];\r\n for (const item of items) {\r\n const box = allocator.allocate(item.size);\r\n if (!box) {\r\n return null;\r\n }\r\n boxes.push(box);\r\n }\r\n this._allocator = allocator;\r\n this._version++;\r\n let result: Nullable<VolumeBox> = null;\r\n for (let i = 0; i < items.length; i++) {\r\n const entry = items[i].entry;\r\n const box = boxes[i];\r\n if (!entry) {\r\n result = box;\r\n continue;\r\n }\r\n if (entry.box.x !== box.x || entry.box.y !== box.y || entry.box.z !== box.z) {\r\n entry.slot.offset = [box.x, box.y, box.z];\r\n entry.uploaded = false;\r\n }\r\n entry.box = box;\r\n }\r\n return result;\r\n }\r\n}\r\n"],"names":["SDF_ATLAS_BLOCK","MeshSDFAtlas","size","_texture","_allocator","_entries","_usedVoxels","_version","map","v","Math","max","ceil","VolumeBoxAllocator","Map","texture","w","h","d","getDevice","createTexture3D","mipmapping","name","entry","values","uploaded","count","occupancy","version","pendingUploads","n","getSlot","key","get","slot","isReady","add","resolution","voxels","existing","need","blockAligned","box","allocate","repack","offset","x","y","z","set","fits","keep","sizes","push","sort","a","b","allocator","every","remove","delete","free","flush","byteBudget","ready","spent","bytes","byteLength","length","update","dispose","clear","reset","items","boxes","item","result","i"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { getDevice } from '../../app/api.js';
2
+
3
+ /** Programs of the SDF system by label, with the error that stopped one, if any. */ const programs = new Map();
4
+ const buildErrors = new Map();
5
+ /**
6
+ * Builds a program of the SDF system and records the outcome under its label. Throws on a shader
7
+ * builder error (which the device reports only as a null program) so the message is kept.
8
+ *
9
+ * @internal
10
+ */ function buildSDFProgram(options) {
11
+ const device = getDevice();
12
+ const label = options.label ?? 'SDF';
13
+ const program = 'compute' in options ? device.buildComputeProgram(options) : device.buildRenderProgram(options);
14
+ programs.set(label, program);
15
+ if (!program) {
16
+ const err = device.programBuilder.lastError || 'unknown shader builder error';
17
+ buildErrors.set(label, err);
18
+ throw new Error(`${label}: ${err}`);
19
+ }
20
+ buildErrors.delete(label);
21
+ return program;
22
+ }
23
+ /**
24
+ * Errors of the SDF system's programs by label: shader builder errors and
25
+ * WGSL compile errors. Empty when everything built.
26
+ * @public
27
+ */ function getSDFProgramErrors() {
28
+ const out = {};
29
+ for (const [label, err] of buildErrors){
30
+ out[label] = err;
31
+ }
32
+ for (const [label, program] of programs){
33
+ const err = program?.getCompileError();
34
+ if (err) {
35
+ out[label] = err;
36
+ }
37
+ }
38
+ return out;
39
+ }
40
+
41
+ export { buildSDFProgram, getSDFProgramErrors };
42
+ //# sourceMappingURL=sdf_programs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdf_programs.js","sources":["../../../src/render/sdf/sdf_programs.ts"],"sourcesContent":["import type { GPUProgram, PBComputeOptions, PBRenderOptions } from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { getDevice } from '../../app/api';\r\n\r\n/** Programs of the SDF system by label, with the error that stopped one, if any. */\r\nconst programs = new Map<string, Nullable<GPUProgram>>();\r\nconst buildErrors = new Map<string, string>();\r\n\r\n/**\r\n * Builds a program of the SDF system and records the outcome under its label. Throws on a shader\r\n * builder error (which the device reports only as a null program) so the message is kept.\r\n *\r\n * @internal\r\n */\r\nexport function buildSDFProgram(options: PBComputeOptions | PBRenderOptions): GPUProgram {\r\n const device = getDevice();\r\n const label = options.label ?? 'SDF';\r\n const program =\r\n 'compute' in options\r\n ? device.buildComputeProgram(options as PBComputeOptions)\r\n : device.buildRenderProgram(options as PBRenderOptions);\r\n programs.set(label, program);\r\n if (!program) {\r\n const err = device.programBuilder.lastError || 'unknown shader builder error';\r\n buildErrors.set(label, err);\r\n throw new Error(`${label}: ${err}`);\r\n }\r\n buildErrors.delete(label);\r\n return program;\r\n}\r\n\r\n/**\r\n * Errors of the SDF system's programs by label: shader builder errors and\r\n * WGSL compile errors. Empty when everything built.\r\n * @public\r\n */\r\nexport function getSDFProgramErrors(): Record<string, string> {\r\n const out: Record<string, string> = {};\r\n for (const [label, err] of buildErrors) {\r\n out[label] = err;\r\n }\r\n for (const [label, program] of programs) {\r\n const err = program?.getCompileError();\r\n if (err) {\r\n out[label] = err;\r\n }\r\n }\r\n return out;\r\n}\r\n"],"names":["programs","Map","buildErrors","buildSDFProgram","options","device","getDevice","label","program","buildComputeProgram","buildRenderProgram","set","err","programBuilder","lastError","Error","delete","getSDFProgramErrors","out","getCompileError"],"mappings":";;AAIA,qFACA,MAAMA,QAAAA,GAAW,IAAIC,GAAAA,EAAAA;AACrB,MAAMC,cAAc,IAAID,GAAAA,EAAAA;AAExB;;;;;IAMO,SAASE,eAAAA,CAAgBC,OAA2C,EAAA;AACzE,IAAA,MAAMC,MAASC,GAAAA,SAAAA,EAAAA;IACf,MAAMC,KAAAA,GAAQH,OAAQG,CAAAA,KAAK,IAAI,KAAA;IAC/B,MAAMC,OAAAA,GACJ,aAAaJ,OACTC,GAAAA,MAAAA,CAAOI,mBAAmB,CAACL,OAAAA,CAAAA,GAC3BC,MAAOK,CAAAA,kBAAkB,CAACN,OAAAA,CAAAA;IAChCJ,QAASW,CAAAA,GAAG,CAACJ,KAAOC,EAAAA,OAAAA,CAAAA;AACpB,IAAA,IAAI,CAACA,OAAS,EAAA;AACZ,QAAA,MAAMI,GAAMP,GAAAA,MAAAA,CAAOQ,cAAc,CAACC,SAAS,IAAI,8BAAA;QAC/CZ,WAAYS,CAAAA,GAAG,CAACJ,KAAOK,EAAAA,GAAAA,CAAAA;AACvB,QAAA,MAAM,IAAIG,KAAM,CAAA,CAAA,EAAGR,KAAM,CAAA,EAAE,EAAEK,GAAK,CAAA,CAAA,CAAA;AACpC;AACAV,IAAAA,WAAAA,CAAYc,MAAM,CAACT,KAAAA,CAAAA;IACnB,OAAOC,OAAAA;AACT;AAEA;;;;AAIC,IACM,SAASS,mBAAAA,GAAAA;AACd,IAAA,MAAMC,MAA8B,EAAC;AACrC,IAAA,KAAK,MAAM,CAACX,KAAOK,EAAAA,GAAAA,CAAI,IAAIV,WAAa,CAAA;QACtCgB,GAAG,CAACX,MAAM,GAAGK,GAAAA;AACf;AACA,IAAA,KAAK,MAAM,CAACL,KAAOC,EAAAA,OAAAA,CAAQ,IAAIR,QAAU,CAAA;AACvC,QAAA,MAAMY,MAAMJ,OAASW,EAAAA,eAAAA,EAAAA;AACrB,QAAA,IAAIP,GAAK,EAAA;YACPM,GAAG,CAACX,MAAM,GAAGK,GAAAA;AACf;AACF;IACA,OAAOM,GAAAA;AACT;;;;"}
@@ -0,0 +1,199 @@
1
+ import { Vector3, Vector4 } from '@zephyr3d/base';
2
+ import { getDevice } from '../../app/api.js';
3
+ import { drawFullscreenQuad } from '../fullscreenquad.js';
4
+ import { declareGlobalSDFUniforms, declareDynamicSDFUniforms, sampleSceneSDFHinted, sdfSurfaceExpand, sdfRefineHit, sampleSceneSDF, sampleGlobalSDF } from '../../shaders/sdf.js';
5
+ import { VOXEL_SCENE_ALBEDO, VOXEL_SCENE_EMISSIVE, VOXEL_SCENE_RADIANCE, VOXEL_SCENE_ANISO0, VOXEL_SCENE_ANISO1, declareVoxelSceneUniforms, voxelSceneTexel, loadVoxelSceneAlbedo, loadVoxelSceneEmissive, sampleVoxelSceneRadiance } from '../../shaders/gi.js';
6
+ import { buildSDFProgram } from './sdf_programs.js';
7
+ import { fetchSampler } from '../../utility/misc.js';
8
+ import { declareProbeUniforms, sampleProbeIrradiance } from '../../shaders/probes.js';
9
+ import { getActiveProbeVolume } from '../gi/probe_volume.js';
10
+
11
+ /** True for the modes that read the probe volume rather than the voxel scene. */ function readsProbes(mode) {
12
+ return mode === 'skyVisibility' || mode === 'irradiance';
13
+ }
14
+ /** Sphere tracing steps per pixel. */ const MAX_STEPS = 128;
15
+ const programs = new Map();
16
+ let renderStates = null;
17
+ function getProgram(levels, mode) {
18
+ const key = `${levels}:${mode}`;
19
+ let entry = programs.get(key);
20
+ if (!entry) {
21
+ const device = getDevice();
22
+ const program = buildSDFProgram({
23
+ label: `SceneSDFView:${mode}`,
24
+ vertex (pb) {
25
+ this.$inputs.pos = pb.vec2().attrib('position');
26
+ this.$outputs.uv = pb.vec2();
27
+ pb.main(function() {
28
+ this.$builtins.position = pb.vec4(this.$inputs.pos, 0, 1);
29
+ this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
30
+ });
31
+ },
32
+ fragment (pb) {
33
+ this.$outputs.color = pb.vec4();
34
+ this.invViewProj = pb.mat4().uniform(0);
35
+ // (camera position, trace distance)
36
+ this.cameraInfo = pb.vec4().uniform(0);
37
+ // (exposure of the radiance and irradiance views, 0, 0, 0)
38
+ this.viewInfo = pb.vec4().uniform(0);
39
+ declareGlobalSDFUniforms(this, 0, levels);
40
+ declareDynamicSDFUniforms(this, 0);
41
+ if (readsProbes(mode)) {
42
+ declareProbeUniforms(this, 0);
43
+ } else if (mode !== 'distance') {
44
+ declareVoxelSceneUniforms(this, 0);
45
+ }
46
+ pb.main(function() {
47
+ // A point on the pixel's ray; clip z 0.5 lies in front on either depth convention
48
+ this.$l.h = pb.mul(this.invViewProj, pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), 0.5, 1));
49
+ this.$l.dir = pb.normalize(pb.sub(pb.div(this.h.xyz, this.h.w), this.cameraInfo.xyz));
50
+ this.$l.t = pb.float(0);
51
+ this.$l.steps = pb.float(0);
52
+ this.$l.hit = false;
53
+ this.$l.prevD = pb.float(0);
54
+ this.$l.hitT = pb.float(0);
55
+ this.$for(pb.int('i'), 0, MAX_STEPS, function() {
56
+ this.$l.sp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));
57
+ this.$l.s = sampleSceneSDFHinted(this, this.sp, this.prevD, levels);
58
+ this.$l.d = this.s.x;
59
+ this.prevD = this.d;
60
+ this.steps = pb.add(this.steps, 1);
61
+ // Same hit test as GI rays (surfaces swollen by a voxel). Probe views read at the
62
+ // refined surface; voxel views read where the trace stopped, since the voxel nearest
63
+ // the surface often lies inside geometry and holds no light
64
+ this.$l.expand = sdfSurfaceExpand(this, this.sp, this.s, this.t, levels);
65
+ this.$if(pb.lessThan(this.d, this.expand), function() {
66
+ this.hitT = sdfRefineHit(this, this.cameraInfo.xyz, this.dir, this.t, this.d, this.s.y, pb.int(0), levels);
67
+ this.hit = true;
68
+ this.$break();
69
+ });
70
+ this.t = pb.add(this.t, pb.max(this.d, 0.02));
71
+ this.$if(pb.greaterThan(this.t, this.cameraInfo.w), function() {
72
+ this.$break();
73
+ });
74
+ });
75
+ // Brightness from step count, so grazing silhouettes glow
76
+ this.$l.k = pb.sqrt(pb.div(this.steps, MAX_STEPS));
77
+ this.$l.miss = pb.vec4(pb.mix(pb.vec3(0.12, 0.12, 0.55), pb.vec3(0.85), this.k), 1);
78
+ if (mode === 'distance') {
79
+ this.$outputs.color = this.$choice(this.hit, pb.vec4(pb.vec3(pb.mix(0.08, 1, this.k)), 1), this.miss);
80
+ } else if (readsProbes(mode)) {
81
+ this.$outputs.color = this.miss;
82
+ this.$if(this.hit, function() {
83
+ // On the field's own surface, where the depth buffer would put a fragment
84
+ this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.hitT));
85
+ this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);
86
+ this.$l.n = pb.normalize(pb.vec3(pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels))));
87
+ if (mode === 'skyVisibility') {
88
+ // Unshaded: white sees the whole sky, black none; magenta where no probe covers
89
+ this.$l.sv = sampleProbeIrradiance(this, this.hp, this.n, pb.sub(this.cameraInfo.xyz, this.hp), 'sky');
90
+ this.$outputs.color = this.$choice(pb.greaterThan(this.sv.a, 0), pb.vec4(this.sv.rgb, 1), pb.vec4(1, 0, 1, 1));
91
+ } else {
92
+ // Irradiance (E/pi) at the view's exposure, unshaded; magenta where no probe covers
93
+ this.$l.irr = sampleProbeIrradiance(this, this.hp, this.n, pb.sub(this.cameraInfo.xyz, this.hp));
94
+ this.$l.ev = pb.mul(this.irr.rgb, this.viewInfo.x);
95
+ this.$outputs.color = this.$choice(pb.greaterThan(this.irr.a, 0), pb.vec4(pb.div(this.ev, pb.add(this.ev, pb.vec3(1))), 1), pb.vec4(1, 0, 1, 1));
96
+ }
97
+ });
98
+ } else {
99
+ this.$outputs.color = this.miss;
100
+ this.$if(this.hit, function() {
101
+ this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));
102
+ this.$l.texel = voxelSceneTexel(this, this.hp, levels);
103
+ if (mode === 'albedo') {
104
+ // Lit by a head light from the field's gradient, so shape reads
105
+ this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);
106
+ this.$l.n = pb.normalize(pb.vec3(pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels))));
107
+ this.$l.a = loadVoxelSceneAlbedo(this, this.texel);
108
+ this.$l.shade = pb.add(0.25, pb.mul(0.75, pb.max(pb.dot(this.n, pb.neg(this.dir)), 0)));
109
+ // No material: magenta outside every current window, orange for a dynamic
110
+ // instance (not voxelized), else cyan/yellow/white by clipmap level 0/1/2+
111
+ this.$l.staticD = sampleGlobalSDF(this, this.hp, levels);
112
+ this.$l.dynamicHit = pb.greaterThan(this.staticD, pb.add(0.05, pb.mul(this.t, 0.004)));
113
+ this.$l.flag = this.$choice(pb.lessThan(this.texel.w, 0), pb.vec3(1, 0, 1), this.$choice(this.dynamicHit, pb.vec3(1, 0.5, 0), this.$choice(pb.equal(this.texel.w, 0), pb.vec3(0, 1, 1), this.$choice(pb.equal(this.texel.w, 1), pb.vec3(1, 1, 0), pb.vec3(1)))));
114
+ this.$outputs.color = this.$choice(pb.greaterThan(this.a.a, 0), pb.vec4(pb.mul(this.a.rgb, this.shade), 1), pb.vec4(pb.mul(this.flag, this.shade), 1));
115
+ } else if (mode === 'emissive') {
116
+ this.$l.em = loadVoxelSceneEmissive(this, this.texel);
117
+ this.$outputs.color = pb.vec4(pb.div(this.em, pb.add(this.em, pb.vec3(1))), 1);
118
+ } else {
119
+ // The radiance toward the side the view ray hit, as a probe ray reads it
120
+ this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);
121
+ this.$l.n = pb.normalize(pb.vec3(pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels))));
122
+ this.$l.rad = pb.mul(sampleVoxelSceneRadiance(this, this.hp, this.n, levels), this.viewInfo.x);
123
+ this.$outputs.color = pb.vec4(pb.div(this.rad, pb.add(this.rad, pb.vec3(1))), 1);
124
+ }
125
+ });
126
+ }
127
+ });
128
+ }
129
+ });
130
+ program.name = `@SceneSDFView_${mode}`;
131
+ entry = {
132
+ program,
133
+ bindGroup: device.createBindGroup(program.bindGroupLayouts[0])
134
+ };
135
+ programs.set(key, entry);
136
+ }
137
+ return entry;
138
+ }
139
+ /**
140
+ * Debug-draws the scene's signed distance field from a camera over the current framebuffer:
141
+ * each pixel sphere traces the field and is shaded by step count, or by the voxel scene /
142
+ * probe volume at the hit for other modes (falling back to `distance` when unavailable).
143
+ * `exposure` scales `radiance` and `irradiance`; magenta marks uncovered points. Call after the
144
+ * camera has rendered; does nothing without a field (disabled or WebGL2).
145
+ *
146
+ * @returns Whether it drew.
147
+ * @public
148
+ */ function renderSceneSDFView(scene, camera, mode = 'distance', exposure = 1) {
149
+ const sdf = scene.sdf.enabled ? scene.sdf.global : null;
150
+ if (!sdf) {
151
+ return false;
152
+ }
153
+ const probes = readsProbes(mode) && scene.gi.enabled ? getActiveProbeVolume(scene) : null;
154
+ const voxels = mode !== 'distance' && !readsProbes(mode) && scene.gi.enabled ? scene.gi.voxels : null;
155
+ if (readsProbes(mode) ? !probes : !voxels?.ready || mode === 'radiance' && !voxels.lit) {
156
+ mode = 'distance';
157
+ }
158
+ const device = getDevice();
159
+ const { program, bindGroup } = getProgram(sdf.levels, mode);
160
+ if (!renderStates) {
161
+ renderStates = device.createRenderStateSet();
162
+ renderStates.useDepthState().enableTest(false).enableWrite(false);
163
+ renderStates.useRasterizerState().setCullMode('none');
164
+ }
165
+ const pos = camera.getWorldPosition(new Vector3());
166
+ bindGroup.setValue('invViewProj', camera.invViewProjectionMatrix);
167
+ // As far as the coarsest level reaches from the camera
168
+ bindGroup.setValue('cameraInfo', new Vector4(pos.x, pos.y, pos.z, sdf.resolution * sdf.voxelSize(sdf.levels - 1)));
169
+ bindGroup.setValue('viewInfo', new Vector4(exposure, 0, 0, 0));
170
+ sdf.applyBindGroup(bindGroup);
171
+ if (probes && readsProbes(mode)) {
172
+ probes.applyBindGroup(bindGroup);
173
+ }
174
+ if (voxels && mode !== 'distance' && !readsProbes(mode)) {
175
+ bindGroup.setTexture(VOXEL_SCENE_ALBEDO, voxels.albedo, fetchSampler('clamp_nearest_nomip'));
176
+ bindGroup.setTexture(VOXEL_SCENE_EMISSIVE, voxels.emissive, fetchSampler('clamp_nearest_nomip'));
177
+ // The layout declares all three; before the first lighting pass stand-ins are bound
178
+ bindGroup.setTexture(VOXEL_SCENE_RADIANCE, voxels.lit ? voxels.radiance : voxels.emissive, fetchSampler('clamp_nearest_nomip'));
179
+ bindGroup.setTexture(VOXEL_SCENE_ANISO0, voxels.lit ? voxels.radianceAniso0 : voxels.albedo, fetchSampler('clamp_nearest_nomip'));
180
+ bindGroup.setTexture(VOXEL_SCENE_ANISO1, voxels.lit ? voxels.radianceAniso1 : voxels.albedo, fetchSampler('clamp_nearest_nomip'));
181
+ }
182
+ device.pushDeviceStates();
183
+ try {
184
+ const vp = camera.viewport;
185
+ if (vp) {
186
+ device.setViewport(vp);
187
+ device.setScissor(vp);
188
+ }
189
+ device.setProgram(program);
190
+ device.setBindGroup(0, bindGroup);
191
+ drawFullscreenQuad(renderStates);
192
+ } finally{
193
+ device.popDeviceStates();
194
+ }
195
+ return true;
196
+ }
197
+
198
+ export { renderSceneSDFView };
199
+ //# sourceMappingURL=sdf_view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdf_view.js","sources":["../../../src/render/sdf/sdf_view.ts"],"sourcesContent":["import type { BindGroup, GPUProgram, RenderStateSet } from '@zephyr3d/device';\r\nimport { Vector3, Vector4 } from '@zephyr3d/base';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { getDevice } from '../../app/api';\r\nimport type { Camera } from '../../camera/camera';\r\nimport type { Scene } from '../../scene/scene';\r\nimport { drawFullscreenQuad } from '../fullscreenquad';\r\nimport {\r\n declareDynamicSDFUniforms,\r\n declareGlobalSDFUniforms,\r\n sampleGlobalSDF,\r\n sampleSceneSDF,\r\n sampleSceneSDFHinted,\r\n sdfRefineHit,\r\n sdfSurfaceExpand\r\n} from '../../shaders/sdf';\r\nimport {\r\n declareVoxelSceneUniforms,\r\n loadVoxelSceneAlbedo,\r\n loadVoxelSceneEmissive,\r\n sampleVoxelSceneRadiance,\r\n VOXEL_SCENE_ALBEDO,\r\n VOXEL_SCENE_EMISSIVE,\r\n VOXEL_SCENE_RADIANCE,\r\n VOXEL_SCENE_ANISO0,\r\n VOXEL_SCENE_ANISO1,\r\n voxelSceneTexel\r\n} from '../../shaders/gi';\r\nimport { buildSDFProgram } from './sdf_programs';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { declareProbeUniforms, sampleProbeIrradiance } from '../../shaders/probes';\r\nimport { getActiveProbeVolume } from '../gi/probe_volume';\r\n\r\n/**\r\n * What {@link renderSceneSDFView} shows: step count, voxel scene albedo/emissive/radiance at the\r\n * hit, or probe sky visibility/irradiance there.\r\n * @public\r\n */\r\nexport type SceneSDFViewMode =\r\n | 'distance'\r\n | 'albedo'\r\n | 'emissive'\r\n | 'radiance'\r\n | 'skyVisibility'\r\n | 'irradiance';\r\n\r\n/** True for the modes that read the probe volume rather than the voxel scene. */\r\nfunction readsProbes(mode: SceneSDFViewMode) {\r\n return mode === 'skyVisibility' || mode === 'irradiance';\r\n}\r\n\r\n/** Sphere tracing steps per pixel. */\r\nconst MAX_STEPS = 128;\r\n\r\nconst programs = new Map<string, { program: GPUProgram; bindGroup: BindGroup }>();\r\nlet renderStates: Nullable<RenderStateSet> = null;\r\n\r\nfunction getProgram(levels: number, mode: SceneSDFViewMode) {\r\n const key = `${levels}:${mode}`;\r\n let entry = programs.get(key);\r\n if (!entry) {\r\n const device = getDevice();\r\n const program = buildSDFProgram({\r\n label: `SceneSDFView:${mode}`,\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$outputs.uv = pb.vec2();\r\n pb.main(function () {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, 0, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n this.invViewProj = pb.mat4().uniform(0);\r\n // (camera position, trace distance)\r\n this.cameraInfo = pb.vec4().uniform(0);\r\n // (exposure of the radiance and irradiance views, 0, 0, 0)\r\n this.viewInfo = pb.vec4().uniform(0);\r\n declareGlobalSDFUniforms(this, 0, levels);\r\n declareDynamicSDFUniforms(this, 0);\r\n if (readsProbes(mode)) {\r\n declareProbeUniforms(this, 0);\r\n } else if (mode !== 'distance') {\r\n declareVoxelSceneUniforms(this, 0);\r\n }\r\n pb.main(function () {\r\n // A point on the pixel's ray; clip z 0.5 lies in front on either depth convention\r\n this.$l.h = pb.mul(\r\n this.invViewProj,\r\n pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), 0.5, 1)\r\n );\r\n this.$l.dir = pb.normalize(pb.sub(pb.div(this.h.xyz, this.h.w), this.cameraInfo.xyz));\r\n this.$l.t = pb.float(0);\r\n this.$l.steps = pb.float(0);\r\n this.$l.hit = false;\r\n this.$l.prevD = pb.float(0);\r\n this.$l.hitT = pb.float(0);\r\n this.$for(pb.int('i'), 0, MAX_STEPS, function () {\r\n this.$l.sp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));\r\n this.$l.s = sampleSceneSDFHinted(this, this.sp, this.prevD, levels);\r\n this.$l.d = this.s.x;\r\n this.prevD = this.d;\r\n this.steps = pb.add(this.steps, 1);\r\n // Same hit test as GI rays (surfaces swollen by a voxel). Probe views read at the\r\n // refined surface; voxel views read where the trace stopped, since the voxel nearest\r\n // the surface often lies inside geometry and holds no light\r\n this.$l.expand = sdfSurfaceExpand(this, this.sp, this.s, this.t, levels);\r\n this.$if(pb.lessThan(this.d, this.expand), function () {\r\n this.hitT = sdfRefineHit(\r\n this,\r\n this.cameraInfo.xyz,\r\n this.dir,\r\n this.t,\r\n this.d,\r\n this.s.y,\r\n pb.int(0),\r\n levels\r\n );\r\n this.hit = true;\r\n this.$break();\r\n });\r\n this.t = pb.add(this.t, pb.max(this.d, 0.02));\r\n this.$if(pb.greaterThan(this.t, this.cameraInfo.w), function () {\r\n this.$break();\r\n });\r\n });\r\n // Brightness from step count, so grazing silhouettes glow\r\n this.$l.k = pb.sqrt(pb.div(this.steps, MAX_STEPS));\r\n this.$l.miss = pb.vec4(pb.mix(pb.vec3(0.12, 0.12, 0.55), pb.vec3(0.85), this.k), 1);\r\n if (mode === 'distance') {\r\n this.$outputs.color = this.$choice(\r\n this.hit,\r\n pb.vec4(pb.vec3(pb.mix(0.08, 1, this.k)), 1),\r\n this.miss\r\n );\r\n } else if (readsProbes(mode)) {\r\n this.$outputs.color = this.miss;\r\n this.$if(this.hit, function () {\r\n // On the field's own surface, where the depth buffer would put a fragment\r\n this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.hitT));\r\n this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);\r\n this.$l.n = pb.normalize(\r\n pb.vec3(\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels)\r\n )\r\n )\r\n );\r\n if (mode === 'skyVisibility') {\r\n // Unshaded: white sees the whole sky, black none; magenta where no probe covers\r\n this.$l.sv = sampleProbeIrradiance(\r\n this,\r\n this.hp,\r\n this.n,\r\n pb.sub(this.cameraInfo.xyz, this.hp),\r\n 'sky'\r\n );\r\n this.$outputs.color = this.$choice(\r\n pb.greaterThan(this.sv.a, 0),\r\n pb.vec4(this.sv.rgb, 1),\r\n pb.vec4(1, 0, 1, 1)\r\n );\r\n } else {\r\n // Irradiance (E/pi) at the view's exposure, unshaded; magenta where no probe covers\r\n this.$l.irr = sampleProbeIrradiance(\r\n this,\r\n this.hp,\r\n this.n,\r\n pb.sub(this.cameraInfo.xyz, this.hp)\r\n );\r\n this.$l.ev = pb.mul(this.irr.rgb, this.viewInfo.x);\r\n this.$outputs.color = this.$choice(\r\n pb.greaterThan(this.irr.a, 0),\r\n pb.vec4(pb.div(this.ev, pb.add(this.ev, pb.vec3(1))), 1),\r\n pb.vec4(1, 0, 1, 1)\r\n );\r\n }\r\n });\r\n } else {\r\n this.$outputs.color = this.miss;\r\n this.$if(this.hit, function () {\r\n this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));\r\n this.$l.texel = voxelSceneTexel(this, this.hp, levels);\r\n if (mode === 'albedo') {\r\n // Lit by a head light from the field's gradient, so shape reads\r\n this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);\r\n this.$l.n = pb.normalize(\r\n pb.vec3(\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels)\r\n )\r\n )\r\n );\r\n this.$l.a = loadVoxelSceneAlbedo(this, this.texel);\r\n this.$l.shade = pb.add(0.25, pb.mul(0.75, pb.max(pb.dot(this.n, pb.neg(this.dir)), 0)));\r\n // No material: magenta outside every current window, orange for a dynamic\r\n // instance (not voxelized), else cyan/yellow/white by clipmap level 0/1/2+\r\n this.$l.staticD = sampleGlobalSDF(this, this.hp, levels);\r\n this.$l.dynamicHit = pb.greaterThan(this.staticD, pb.add(0.05, pb.mul(this.t, 0.004)));\r\n this.$l.flag = this.$choice(\r\n pb.lessThan(this.texel.w, 0),\r\n pb.vec3(1, 0, 1),\r\n this.$choice(\r\n this.dynamicHit,\r\n pb.vec3(1, 0.5, 0),\r\n this.$choice(\r\n pb.equal(this.texel.w, 0),\r\n pb.vec3(0, 1, 1),\r\n this.$choice(pb.equal(this.texel.w, 1), pb.vec3(1, 1, 0), pb.vec3(1))\r\n )\r\n )\r\n );\r\n this.$outputs.color = this.$choice(\r\n pb.greaterThan(this.a.a, 0),\r\n pb.vec4(pb.mul(this.a.rgb, this.shade), 1),\r\n pb.vec4(pb.mul(this.flag, this.shade), 1)\r\n );\r\n } else if (mode === 'emissive') {\r\n this.$l.em = loadVoxelSceneEmissive(this, this.texel);\r\n this.$outputs.color = pb.vec4(pb.div(this.em, pb.add(this.em, pb.vec3(1))), 1);\r\n } else {\r\n // The radiance toward the side the view ray hit, as a probe ray reads it\r\n this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);\r\n this.$l.n = pb.normalize(\r\n pb.vec3(\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels)\r\n )\r\n )\r\n );\r\n this.$l.rad = pb.mul(\r\n sampleVoxelSceneRadiance(this, this.hp, this.n, levels),\r\n this.viewInfo.x\r\n );\r\n this.$outputs.color = pb.vec4(pb.div(this.rad, pb.add(this.rad, pb.vec3(1))), 1);\r\n }\r\n });\r\n }\r\n });\r\n }\r\n })!;\r\n program.name = `@SceneSDFView_${mode}`;\r\n entry = { program, bindGroup: device.createBindGroup(program.bindGroupLayouts[0]) };\r\n programs.set(key, entry);\r\n }\r\n return entry;\r\n}\r\n\r\n/**\r\n * Debug-draws the scene's signed distance field from a camera over the current framebuffer:\r\n * each pixel sphere traces the field and is shaded by step count, or by the voxel scene /\r\n * probe volume at the hit for other modes (falling back to `distance` when unavailable).\r\n * `exposure` scales `radiance` and `irradiance`; magenta marks uncovered points. Call after the\r\n * camera has rendered; does nothing without a field (disabled or WebGL2).\r\n *\r\n * @returns Whether it drew.\r\n * @public\r\n */\r\nexport function renderSceneSDFView(\r\n scene: Scene,\r\n camera: Camera,\r\n mode: SceneSDFViewMode = 'distance',\r\n exposure = 1\r\n) {\r\n const sdf = scene.sdf.enabled ? scene.sdf.global : null;\r\n if (!sdf) {\r\n return false;\r\n }\r\n const probes = readsProbes(mode) && scene.gi.enabled ? getActiveProbeVolume(scene) : null;\r\n const voxels = mode !== 'distance' && !readsProbes(mode) && scene.gi.enabled ? scene.gi.voxels : null;\r\n if (readsProbes(mode) ? !probes : !voxels?.ready || (mode === 'radiance' && !voxels.lit)) {\r\n mode = 'distance';\r\n }\r\n const device = getDevice();\r\n const { program, bindGroup } = getProgram(sdf.levels, mode);\r\n if (!renderStates) {\r\n renderStates = device.createRenderStateSet();\r\n renderStates.useDepthState().enableTest(false).enableWrite(false);\r\n renderStates.useRasterizerState().setCullMode('none');\r\n }\r\n const pos = camera.getWorldPosition(new Vector3());\r\n bindGroup.setValue('invViewProj', camera.invViewProjectionMatrix);\r\n // As far as the coarsest level reaches from the camera\r\n bindGroup.setValue(\r\n 'cameraInfo',\r\n new Vector4(pos.x, pos.y, pos.z, sdf.resolution * sdf.voxelSize(sdf.levels - 1))\r\n );\r\n bindGroup.setValue('viewInfo', new Vector4(exposure, 0, 0, 0));\r\n sdf.applyBindGroup(bindGroup);\r\n if (probes && readsProbes(mode)) {\r\n probes.applyBindGroup(bindGroup);\r\n }\r\n if (voxels && mode !== 'distance' && !readsProbes(mode)) {\r\n bindGroup.setTexture(VOXEL_SCENE_ALBEDO, voxels.albedo, fetchSampler('clamp_nearest_nomip'));\r\n bindGroup.setTexture(VOXEL_SCENE_EMISSIVE, voxels.emissive, fetchSampler('clamp_nearest_nomip'));\r\n // The layout declares all three; before the first lighting pass stand-ins are bound\r\n bindGroup.setTexture(\r\n VOXEL_SCENE_RADIANCE,\r\n voxels.lit ? voxels.radiance : voxels.emissive,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n bindGroup.setTexture(\r\n VOXEL_SCENE_ANISO0,\r\n voxels.lit ? voxels.radianceAniso0 : voxels.albedo,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n bindGroup.setTexture(\r\n VOXEL_SCENE_ANISO1,\r\n voxels.lit ? voxels.radianceAniso1 : voxels.albedo,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n }\r\n device.pushDeviceStates();\r\n try {\r\n const vp = camera.viewport;\r\n if (vp) {\r\n device.setViewport(vp as number[]);\r\n device.setScissor(vp as number[]);\r\n }\r\n device.setProgram(program);\r\n device.setBindGroup(0, bindGroup);\r\n drawFullscreenQuad(renderStates);\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n return true;\r\n}\r\n"],"names":["readsProbes","mode","MAX_STEPS","programs","Map","renderStates","getProgram","levels","key","entry","get","device","getDevice","program","buildSDFProgram","label","vertex","pb","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","add","mul","xy","fragment","color","invViewProj","mat4","uniform","cameraInfo","viewInfo","declareGlobalSDFUniforms","declareDynamicSDFUniforms","declareProbeUniforms","declareVoxelSceneUniforms","$l","h","sub","dir","normalize","div","xyz","w","t","float","steps","hit","prevD","hitT","$for","int","sp","s","sampleSceneSDFHinted","d","x","expand","sdfSurfaceExpand","$if","lessThan","sdfRefineHit","y","$break","max","greaterThan","k","sqrt","miss","mix","vec3","$choice","hp","e","n","sampleSceneSDF","sv","sampleProbeIrradiance","a","rgb","irr","ev","texel","voxelSceneTexel","loadVoxelSceneAlbedo","shade","dot","neg","staticD","sampleGlobalSDF","dynamicHit","flag","equal","em","loadVoxelSceneEmissive","rad","sampleVoxelSceneRadiance","name","bindGroup","createBindGroup","bindGroupLayouts","set","renderSceneSDFView","scene","camera","exposure","sdf","enabled","global","probes","gi","getActiveProbeVolume","voxels","ready","lit","createRenderStateSet","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode","getWorldPosition","Vector3","setValue","invViewProjectionMatrix","Vector4","z","resolution","voxelSize","applyBindGroup","setTexture","VOXEL_SCENE_ALBEDO","albedo","fetchSampler","VOXEL_SCENE_EMISSIVE","emissive","VOXEL_SCENE_RADIANCE","radiance","VOXEL_SCENE_ANISO0","radianceAniso0","VOXEL_SCENE_ANISO1","radianceAniso1","pushDeviceStates","vp","viewport","setViewport","setScissor","setProgram","setBindGroup","drawFullscreenQuad","popDeviceStates"],"mappings":"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"}