@zephyr3d/scene 0.9.27 → 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 (502) 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 +54 -0
  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 +279 -55
  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 +171 -1
  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 +104 -178
  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 +25436 -15990
  109. package/dist/index.js +65 -11
  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/lambert.js +4 -1
  118. package/dist/material/lambert.js.map +1 -1
  119. package/dist/material/material.js +66 -4
  120. package/dist/material/material.js.map +1 -1
  121. package/dist/material/meshmaterial.js +118 -45
  122. package/dist/material/meshmaterial.js.map +1 -1
  123. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  124. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  125. package/dist/material/mixins/lightmodel/lambert.js +1 -1
  126. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  127. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
  128. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  129. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
  130. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  131. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
  132. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  133. package/dist/material/mixins/lit.js +191 -83
  134. package/dist/material/mixins/lit.js.map +1 -1
  135. package/dist/material/mixins/pbr/common.js +31 -206
  136. package/dist/material/mixins/pbr/common.js.map +1 -1
  137. package/dist/material/mtoon.js +1 -1
  138. package/dist/material/mtoon.js.map +1 -1
  139. package/dist/material/pbrmr.js +3 -0
  140. package/dist/material/pbrmr.js.map +1 -1
  141. package/dist/material/pbrsg.js +3 -0
  142. package/dist/material/pbrsg.js.map +1 -1
  143. package/dist/material/sdf_debug.js +78 -0
  144. package/dist/material/sdf_debug.js.map +1 -0
  145. package/dist/material/shader/helper.js +333 -191
  146. package/dist/material/shader/helper.js.map +1 -1
  147. package/dist/material/shader/terrain_blend.js +204 -43
  148. package/dist/material/shader/terrain_blend.js.map +1 -1
  149. package/dist/material/skin.js +331 -297
  150. package/dist/material/skin.js.map +1 -1
  151. package/dist/material/skinprofile.js +1058 -0
  152. package/dist/material/skinprofile.js.map +1 -0
  153. package/dist/material/sss.js +353 -0
  154. package/dist/material/sss.js.map +1 -0
  155. package/dist/material/sss_kernel.js +265 -0
  156. package/dist/material/sss_kernel.js.map +1 -0
  157. package/dist/material/sssprofile.js +879 -0
  158. package/dist/material/sssprofile.js.map +1 -0
  159. package/dist/material/subsurfaceprofile.js +4 -8
  160. package/dist/material/subsurfaceprofile.js.map +1 -1
  161. package/dist/material/terrain-cm.js +464 -188
  162. package/dist/material/terrain-cm.js.map +1 -1
  163. package/dist/material/unlit.js +3 -0
  164. package/dist/material/unlit.js.map +1 -1
  165. package/dist/material/water.js +1261 -1438
  166. package/dist/material/water.js.map +1 -1
  167. package/dist/node_modules/meshoptimizer/LICENSE +21 -0
  168. package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
  169. package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
  170. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
  171. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
  172. package/dist/physics/character.js +226 -0
  173. package/dist/physics/character.js.map +1 -0
  174. package/dist/physics/collider.js +209 -0
  175. package/dist/physics/collider.js.map +1 -0
  176. package/dist/physics/events.js +79 -0
  177. package/dist/physics/events.js.map +1 -0
  178. package/dist/physics/joint.js +272 -0
  179. package/dist/physics/joint.js.map +1 -0
  180. package/dist/physics/node_physics.js +234 -0
  181. package/dist/physics/node_physics.js.map +1 -0
  182. package/dist/physics/part.js +91 -0
  183. package/dist/physics/part.js.map +1 -0
  184. package/dist/physics/rigid_body.js +379 -0
  185. package/dist/physics/rigid_body.js.map +1 -0
  186. package/dist/physics/vehicle.js +335 -0
  187. package/dist/physics/vehicle.js.map +1 -0
  188. package/dist/physics/world.js +25 -0
  189. package/dist/physics/world.js.map +1 -0
  190. package/dist/posteffect/bloom.js +49 -14
  191. package/dist/posteffect/bloom.js.map +1 -1
  192. package/dist/posteffect/motionblur.js +106 -106
  193. package/dist/posteffect/motionblur.js.map +1 -1
  194. package/dist/posteffect/postsss.js +572 -0
  195. package/dist/posteffect/postsss.js.map +1 -0
  196. package/dist/posteffect/sao.js +2 -6
  197. package/dist/posteffect/sao.js.map +1 -1
  198. package/dist/posteffect/skinsss.js +605 -355
  199. package/dist/posteffect/skinsss.js.map +1 -1
  200. package/dist/posteffect/ssgi.js +91 -162
  201. package/dist/posteffect/ssgi.js.map +1 -1
  202. package/dist/posteffect/ssr.js +3 -11
  203. package/dist/posteffect/ssr.js.map +1 -1
  204. package/dist/posteffect/sss.js +4 -13
  205. package/dist/posteffect/sss.js.map +1 -1
  206. package/dist/posteffect/taa.js +1 -0
  207. package/dist/posteffect/taa.js.map +1 -1
  208. package/dist/render/abuffer_oit.js +3 -2
  209. package/dist/render/abuffer_oit.js.map +1 -1
  210. package/dist/render/clipmap.js +179 -64
  211. package/dist/render/clipmap.js.map +1 -1
  212. package/dist/render/cluster_light.js +958 -224
  213. package/dist/render/cluster_light.js.map +1 -1
  214. package/dist/render/cull_visitor.js +25 -5
  215. package/dist/render/cull_visitor.js.map +1 -1
  216. package/dist/render/debug_views.js +37 -0
  217. package/dist/render/debug_views.js.map +1 -0
  218. package/dist/render/depthpass.js +5 -1
  219. package/dist/render/depthpass.js.map +1 -1
  220. package/dist/render/drawable_mixin.js +53 -6
  221. package/dist/render/drawable_mixin.js.map +1 -1
  222. package/dist/render/dualdepthpeeling_oit.js +5 -5
  223. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  224. package/dist/render/envlight.js +196 -113
  225. package/dist/render/envlight.js.map +1 -1
  226. package/dist/render/fbm_wavegenerator.js +5 -10
  227. package/dist/render/fbm_wavegenerator.js.map +1 -1
  228. package/dist/render/fft_wavegenerator.js +247 -157
  229. package/dist/render/fft_wavegenerator.js.map +1 -1
  230. package/dist/render/gerstner_wavegenerator.js +16 -38
  231. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  232. package/dist/render/gi/probe_volume.js +1334 -0
  233. package/dist/render/gi/probe_volume.js.map +1 -0
  234. package/dist/render/gi/scene_gi.js +282 -0
  235. package/dist/render/gi/scene_gi.js.map +1 -0
  236. package/dist/render/gi/voxel_atlas.js +198 -0
  237. package/dist/render/gi/voxel_atlas.js.map +1 -0
  238. package/dist/render/gi/voxel_lighting.js +652 -0
  239. package/dist/render/gi/voxel_lighting.js.map +1 -0
  240. package/dist/render/gi/voxel_scene.js +642 -0
  241. package/dist/render/gi/voxel_scene.js.map +1 -0
  242. package/dist/render/gi/voxelize_pass.js +223 -0
  243. package/dist/render/gi/voxelize_pass.js.map +1 -0
  244. package/dist/render/globalbindgroup_allocator.js +3 -2
  245. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  246. package/dist/render/gpu_picking.js +9 -36
  247. package/dist/render/gpu_picking.js.map +1 -1
  248. package/dist/render/instance_culling.js +499 -0
  249. package/dist/render/instance_culling.js.map +1 -0
  250. package/dist/render/lightpass.js +19 -8
  251. package/dist/render/lightpass.js.map +1 -1
  252. package/dist/render/lod.js +46 -0
  253. package/dist/render/lod.js.map +1 -0
  254. package/dist/render/primitive.js +301 -9
  255. package/dist/render/primitive.js.map +1 -1
  256. package/dist/render/primitive_readback.js +209 -0
  257. package/dist/render/primitive_readback.js.map +1 -0
  258. package/dist/render/render_queue.js +162 -11
  259. package/dist/render/render_queue.js.map +1 -1
  260. package/dist/render/renderer.js +10 -7
  261. package/dist/render/renderer.js.map +1 -1
  262. package/dist/render/rendergraph/blackboard.js +14 -1
  263. package/dist/render/rendergraph/blackboard.js.map +1 -1
  264. package/dist/render/rendergraph/executor.js +136 -0
  265. package/dist/render/rendergraph/executor.js.map +1 -1
  266. package/dist/render/rendergraph/forward_plus_builder.js +272 -55
  267. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  268. package/dist/render/rendergraph/frame_graph_context.js +41 -0
  269. package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
  270. package/dist/render/rendergraph/scene_render_context.js +31 -2
  271. package/dist/render/rendergraph/scene_render_context.js.map +1 -1
  272. package/dist/render/rendergraph/types.js.map +1 -1
  273. package/dist/render/renderpass.js +28 -5
  274. package/dist/render/renderpass.js.map +1 -1
  275. package/dist/render/sdf/box_allocator.js +98 -0
  276. package/dist/render/sdf/box_allocator.js.map +1 -0
  277. package/dist/render/sdf/global_sdf.js +865 -0
  278. package/dist/render/sdf/global_sdf.js.map +1 -0
  279. package/dist/render/sdf/scene_sdf.js +562 -0
  280. package/dist/render/sdf/scene_sdf.js.map +1 -0
  281. package/dist/render/sdf/sdf_atlas.js +227 -0
  282. package/dist/render/sdf/sdf_atlas.js.map +1 -0
  283. package/dist/render/sdf/sdf_programs.js +42 -0
  284. package/dist/render/sdf/sdf_programs.js.map +1 -0
  285. package/dist/render/sdf/sdf_view.js +199 -0
  286. package/dist/render/sdf/sdf_view.js.map +1 -0
  287. package/dist/render/sdf/waterline.js +610 -0
  288. package/dist/render/sdf/waterline.js.map +1 -0
  289. package/dist/render/shadow_mask_pass.js +142 -25
  290. package/dist/render/shadow_mask_pass.js.map +1 -1
  291. package/dist/render/shore_wave_generator.js +1193 -0
  292. package/dist/render/shore_wave_generator.js.map +1 -0
  293. package/dist/render/sky.js +516 -86
  294. package/dist/render/sky.js.map +1 -1
  295. package/dist/render/transmission_thickness_pass.js +477 -0
  296. package/dist/render/transmission_thickness_pass.js.map +1 -0
  297. package/dist/render/underwater.js +58 -158
  298. package/dist/render/underwater.js.map +1 -1
  299. package/dist/render/virtualtexture/virtual_texture.js +1214 -0
  300. package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
  301. package/dist/render/volumetric_cloud/cloud_common.js +472 -0
  302. package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
  303. package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
  304. package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
  305. package/dist/render/volumetric_cloud/debug_view.js +131 -0
  306. package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
  307. package/dist/render/volumetric_cloud/resources.js +380 -0
  308. package/dist/render/volumetric_cloud/resources.js.map +1 -0
  309. package/dist/render/volumetric_cloud/sky_cache.js +380 -0
  310. package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
  311. package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
  312. package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
  313. package/dist/render/water_caustics.js +134 -319
  314. package/dist/render/water_caustics.js.map +1 -1
  315. package/dist/render/water_foam.js +627 -0
  316. package/dist/render/water_foam.js.map +1 -0
  317. package/dist/render/water_interaction.js +1795 -0
  318. package/dist/render/water_interaction.js.map +1 -0
  319. package/dist/render/weightedblended_oit.js +3 -3
  320. package/dist/render/weightedblended_oit.js.map +1 -1
  321. package/dist/scene/basesprite.js +9 -4
  322. package/dist/scene/basesprite.js.map +1 -1
  323. package/dist/scene/batchgroup.js +108 -12
  324. package/dist/scene/batchgroup.js.map +1 -1
  325. package/dist/scene/environment.js +28 -7
  326. package/dist/scene/environment.js.map +1 -1
  327. package/dist/scene/foliage.js +1020 -0
  328. package/dist/scene/foliage.js.map +1 -0
  329. package/dist/scene/foliage_buckets.js +147 -0
  330. package/dist/scene/foliage_buckets.js.map +1 -0
  331. package/dist/scene/foliage_mask.js +358 -0
  332. package/dist/scene/foliage_mask.js.map +1 -0
  333. package/dist/scene/hair.js +15 -4
  334. package/dist/scene/hair.js.map +1 -1
  335. package/dist/scene/light.js +179 -13
  336. package/dist/scene/light.js.map +1 -1
  337. package/dist/scene/mesh.js +327 -45
  338. package/dist/scene/mesh.js.map +1 -1
  339. package/dist/scene/meshdrawable.js +6 -0
  340. package/dist/scene/meshdrawable.js.map +1 -1
  341. package/dist/scene/msdftext.js +9 -3
  342. package/dist/scene/msdftext.js.map +1 -1
  343. package/dist/scene/msdftextsprite.js +9 -3
  344. package/dist/scene/msdftextsprite.js.map +1 -1
  345. package/dist/scene/particlesys.js +8 -2
  346. package/dist/scene/particlesys.js.map +1 -1
  347. package/dist/scene/physics_settings.js +157 -0
  348. package/dist/scene/physics_settings.js.map +1 -0
  349. package/dist/scene/scene.js +190 -44
  350. package/dist/scene/scene.js.map +1 -1
  351. package/dist/scene/scene_node.js +147 -6
  352. package/dist/scene/scene_node.js.map +1 -1
  353. package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
  354. package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
  355. package/dist/scene/terrain-cm/grass.js +881 -42
  356. package/dist/scene/terrain-cm/grass.js.map +1 -1
  357. package/dist/scene/terrain-cm/grass_gpu.js +929 -0
  358. package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
  359. package/dist/scene/terrain-cm/grassmaterial.js +180 -9
  360. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  361. package/dist/scene/terrain-cm/terrain-cm.js +465 -36
  362. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  363. package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
  364. package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
  365. package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
  366. package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
  367. package/dist/scene/update_queue.js +54 -0
  368. package/dist/scene/update_queue.js.map +1 -0
  369. package/dist/scene/water.js +633 -268
  370. package/dist/scene/water.js.map +1 -1
  371. package/dist/scene/water_surface_sampler.js +324 -0
  372. package/dist/scene/water_surface_sampler.js.map +1 -0
  373. package/dist/scene/wind.js +317 -0
  374. package/dist/scene/wind.js.map +1 -0
  375. package/dist/shaders/atmosphere.js +388 -166
  376. package/dist/shaders/atmosphere.js.map +1 -1
  377. package/dist/shaders/fog.js +100 -32
  378. package/dist/shaders/fog.js.map +1 -1
  379. package/dist/shaders/gi.js +365 -0
  380. package/dist/shaders/gi.js.map +1 -0
  381. package/dist/shaders/ltc_rect.js +202 -0
  382. package/dist/shaders/ltc_rect.js.map +1 -0
  383. package/dist/shaders/misc.js +1 -10
  384. package/dist/shaders/misc.js.map +1 -1
  385. package/dist/shaders/noise.js +5 -1
  386. package/dist/shaders/noise.js.map +1 -1
  387. package/dist/shaders/probes.js +309 -0
  388. package/dist/shaders/probes.js.map +1 -0
  389. package/dist/shaders/sdf.js +537 -0
  390. package/dist/shaders/sdf.js.map +1 -0
  391. package/dist/shaders/shadow.js +104 -70
  392. package/dist/shaders/shadow.js.map +1 -1
  393. package/dist/shaders/skin_brdf.js +243 -0
  394. package/dist/shaders/skin_brdf.js.map +1 -0
  395. package/dist/shaders/ssgi.js +63 -0
  396. package/dist/shaders/ssgi.js.map +1 -0
  397. package/dist/shaders/ssgi_reprojection.js +118 -0
  398. package/dist/shaders/ssgi_reprojection.js.map +1 -0
  399. package/dist/shaders/ssr.js +6 -159
  400. package/dist/shaders/ssr.js.map +1 -1
  401. package/dist/shaders/temporal.js +38 -27
  402. package/dist/shaders/temporal.js.map +1 -1
  403. package/dist/shaders/water.js +32 -82
  404. package/dist/shaders/water.js.map +1 -1
  405. package/dist/shaders/water_medium.js +7 -21
  406. package/dist/shaders/water_medium.js.map +1 -1
  407. package/dist/shadow/dom.js +110 -19
  408. package/dist/shadow/dom.js.map +1 -1
  409. package/dist/shadow/esm.js +3 -3
  410. package/dist/shadow/esm.js.map +1 -1
  411. package/dist/shadow/pcf_opt.js +15 -48
  412. package/dist/shadow/pcf_opt.js.map +1 -1
  413. package/dist/shadow/pcf_pd.js +15 -53
  414. package/dist/shadow/pcf_pd.js.map +1 -1
  415. package/dist/shadow/pcss.js +34 -9
  416. package/dist/shadow/pcss.js.map +1 -1
  417. package/dist/shadow/shadow_impl.js +3 -8
  418. package/dist/shadow/shadow_impl.js.map +1 -1
  419. package/dist/shadow/shadow_region.js +40 -2
  420. package/dist/shadow/shadow_region.js.map +1 -1
  421. package/dist/shadow/shadowmapper.js +93 -53
  422. package/dist/shadow/shadowmapper.js.map +1 -1
  423. package/dist/shadow/ssm.js +18 -72
  424. package/dist/shadow/ssm.js.map +1 -1
  425. package/dist/shadow/vsm.js +3 -3
  426. package/dist/shadow/vsm.js.map +1 -1
  427. package/dist/shapes/shape.js +44 -1
  428. package/dist/shapes/shape.js.map +1 -1
  429. package/dist/utility/buoyancy.js +287 -0
  430. package/dist/utility/buoyancy.js.map +1 -0
  431. package/dist/utility/physical.js +10 -1
  432. package/dist/utility/physical.js.map +1 -1
  433. package/dist/utility/pmrem.js +17 -43
  434. package/dist/utility/pmrem.js.map +1 -1
  435. package/dist/utility/sdf/bake.js +435 -0
  436. package/dist/utility/sdf/bake.js.map +1 -0
  437. package/dist/utility/sdf/bvh.js +576 -0
  438. package/dist/utility/sdf/bvh.js.map +1 -0
  439. package/dist/utility/serialization/manager.js +34 -6
  440. package/dist/utility/serialization/manager.js.map +1 -1
  441. package/dist/utility/serialization/scene/animation.js +46 -5
  442. package/dist/utility/serialization/scene/animation.js.map +1 -1
  443. package/dist/utility/serialization/scene/batch.js +11 -4
  444. package/dist/utility/serialization/scene/batch.js.map +1 -1
  445. package/dist/utility/serialization/scene/camera.js +87 -254
  446. package/dist/utility/serialization/scene/camera.js.map +1 -1
  447. package/dist/utility/serialization/scene/cloth.js +25 -0
  448. package/dist/utility/serialization/scene/cloth.js.map +1 -0
  449. package/dist/utility/serialization/scene/common.js +14 -6
  450. package/dist/utility/serialization/scene/common.js.map +1 -1
  451. package/dist/utility/serialization/scene/foliage.js +821 -0
  452. package/dist/utility/serialization/scene/foliage.js.map +1 -0
  453. package/dist/utility/serialization/scene/hair.js +11 -4
  454. package/dist/utility/serialization/scene/hair.js.map +1 -1
  455. package/dist/utility/serialization/scene/light.js +115 -7
  456. package/dist/utility/serialization/scene/light.js.map +1 -1
  457. package/dist/utility/serialization/scene/material.js +388 -220
  458. package/dist/utility/serialization/scene/material.js.map +1 -1
  459. package/dist/utility/serialization/scene/mesh.js +69 -4
  460. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  461. package/dist/utility/serialization/scene/node.js +140 -5
  462. package/dist/utility/serialization/scene/node.js.map +1 -1
  463. package/dist/utility/serialization/scene/node_physics.js +1318 -0
  464. package/dist/utility/serialization/scene/node_physics.js.map +1 -0
  465. package/dist/utility/serialization/scene/particle.js +11 -4
  466. package/dist/utility/serialization/scene/particle.js.map +1 -1
  467. package/dist/utility/serialization/scene/physics.js +120 -0
  468. package/dist/utility/serialization/scene/physics.js.map +1 -0
  469. package/dist/utility/serialization/scene/primitive.js +124 -10
  470. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  471. package/dist/utility/serialization/scene/scene.js +1687 -51
  472. package/dist/utility/serialization/scene/scene.js.map +1 -1
  473. package/dist/utility/serialization/scene/sprite.js +11 -4
  474. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  475. package/dist/utility/serialization/scene/terrain.js +163 -33
  476. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  477. package/dist/utility/serialization/scene/text.js +11 -4
  478. package/dist/utility/serialization/scene/text.js.map +1 -1
  479. package/dist/utility/serialization/scene/water.js +1543 -264
  480. package/dist/utility/serialization/scene/water.js.map +1 -1
  481. package/dist/utility/serialization/types.js.map +1 -1
  482. package/dist/utility/shprojector.js +10 -22
  483. package/dist/utility/shprojector.js.map +1 -1
  484. package/dist/utility/textures/foam.js +170 -0
  485. package/dist/utility/textures/foam.js.map +1 -0
  486. package/dist/utility/textures/ggxlut.js +17 -43
  487. package/dist/utility/textures/ggxlut.js.map +1 -1
  488. package/dist/utility/textures/ltcdata.js +4 -4
  489. package/dist/utility/textures/ltcdata.js.map +1 -1
  490. package/dist/utility/textures/ltclut.js +16 -6
  491. package/dist/utility/textures/ltclut.js.map +1 -1
  492. package/dist/utility/unsupported.js +24 -0
  493. package/dist/utility/unsupported.js.map +1 -0
  494. package/dist/values.js +13 -1
  495. package/dist/values.js.map +1 -1
  496. package/package.json +25 -12
  497. package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
  498. package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  499. package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  500. package/src/asset/meshoptimizer/LICENSE +21 -0
  501. package/dist/animation/joint_dynamics/convex_collider.js +0 -320
  502. package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
@@ -1,56 +1,34 @@
1
1
  import { Matrix4x4, DRef, Vector3, Vector2, Vector4, REVERSE_Z, Disposable } from '@zephyr3d/base';
2
2
  import { getSamplerOptions, fetchSampler } from '../utility/misc.js';
3
3
  import { getDevice } from '../app/api.js';
4
- import { decodeNormalizedFloatFromRGBA } from '../shaders/misc.js';
4
+ import { getProbeVolumeForDraw } from './gi/probe_volume.js';
5
+ import { declareProbeUniforms, sampleProbeIrradiance } from '../shaders/probes.js';
5
6
 
6
7
  /**
7
- * Depth-proportional term of the SSGI history rejection tolerance.
8
- *
9
- * The surface history stores `linearDepth * cameraFar` in an `rgba16f` alpha
10
- * channel, so its quantization error grows with depth: fp16 carries ~11 bits of
11
- * mantissa, giving a relative error near 4.9e-4 (~0.49 world units at a depth of
12
- * 1000). A purely absolute tolerance is therefore unusable in the distance -- at
13
- * `ssgiDepthReject`'s 0.5 default, storage quantization alone consumes the whole
14
- * budget and the test degenerates into dithered noise. This factor keeps roughly
15
- * 4x headroom over that error while staying far below the depth step of a real
16
- * disocclusion.
8
+ * Depth-proportional term of the SSGI history rejection tolerance. fp16 storage of
9
+ * `linearDepth * cameraFar` has ~4.9e-4 relative error; this keeps ~4x headroom
10
+ * while staying far below a real disocclusion's depth step.
17
11
  *
18
12
  * @internal
19
13
  */ const SSGI_DEPTH_TOLERANCE_RELATIVE = 2e-3;
20
14
  /**
21
- * Multiple of the scaled tolerance at which history is dropped outright.
22
- *
23
- * Inside this gate the depth term contributes a smooth `exp(-d/tol)` weight
24
- * rather than a boolean, so confidence decays continuously instead of flipping.
25
- * At 3x the weight is already down to ~0.05, making the cutoff visually
26
- * continuous -- which is what keeps a rejection boundary from reading as a
27
- * staircase after nearest-neighbour sampling quantizes it to texel steps.
15
+ * Multiple of the scaled tolerance at which history is dropped outright. Inside it
16
+ * the depth term is a smooth `exp(-d/tol)` weight (~0.05 at 3x), so the cutoff
17
+ * does not staircase.
28
18
  *
29
19
  * @internal
30
20
  */ const SSGI_DEPTH_GATE_SCALE = 3;
31
21
  /**
32
22
  * Clamp distance, in texels, at which history repair reaches its widest radius.
33
- *
34
- * The clamp distance says how far the reprojection had to travel to get back on
35
- * screen, which is a direct measure of how unrelated to this pixel the surviving
36
- * history is. It scales the repair radius rather than gating repair off: the
37
- * lighting pass only ever sees the previous frame, so a pixel rotating in from
38
- * off screen has no fresh data anywhere and both alternatives to spreading the
39
- * taps look worse than the blur does.
23
+ * Clamp travel measures how unrelated the surviving history is, so it scales the
24
+ * repair radius rather than gating repair off.
40
25
  *
41
26
  * @internal
42
27
  */ const SSGI_REPAIR_WIDE_CLAMP_TEXELS = 8;
43
28
  /**
44
- * Repair tap radius in texels, from an interior hole to a camera-edge one.
45
- *
46
- * The radius is what trades structure against smoothness. At one texel the taps
47
- * of neighbouring pixels barely overlap, so detail survives -- correct for a hole
48
- * in the middle of the screen, where the reprojection landed near its true
49
- * position. Wide taps instead overlap heavily between neighbours, which turns the
50
- * one strip of history that survives at a screen edge into a smooth low-frequency
51
- * estimate of the surface's irradiance rather than a per-column copy of single
52
- * texels, and copying single texels is what draws streaks along the direction of
53
- * travel.
29
+ * Repair tap radius in texels, from an interior hole to a camera-edge one. Narrow
30
+ * taps keep detail; wide taps average the surviving edge strip into a smooth
31
+ * estimate instead of copying single texels into streaks.
54
32
  *
55
33
  * @internal
56
34
  */ const SSGI_REPAIR_MIN_RADIUS_TEXELS = 1;
@@ -59,6 +37,77 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
59
37
  * Base class for any kind of environment light
60
38
  * @public
61
39
  */ class EnvironmentLighting extends Disposable {
40
+ /**
41
+ * Declares the scene's probe volume where the draw reads it (see
42
+ * {@link getProbeVolumeForDraw}); call from `initShaderBindings` in the fragment stage.
43
+ * @internal
44
+ */ initProbeBindings(pb, ctx) {
45
+ if (pb.shaderKind === 'fragment' && getProbeVolumeForDraw(ctx)) {
46
+ declareProbeUniforms(pb.getGlobalScope(), 0);
47
+ }
48
+ }
49
+ /** Binds what {@link EnvironmentLighting.initProbeBindings} declared. @internal */ updateProbeBindGroup(bg, ctx) {
50
+ getProbeVolumeForDraw(ctx)?.applyBindGroup(bg);
51
+ }
52
+ /**
53
+ * Specular occlusion from the probe volume's sky visibility. 1 where probes
54
+ * do not cover the fragment or without a `worldPos` varying.
55
+ * @internal
56
+ */ getSkySpecularOcclusion(scope, normal, NoV, roughness, ctx) {
57
+ const pb = scope.$builder;
58
+ if (!getProbeVolumeForDraw(ctx)) {
59
+ return pb.float(1);
60
+ }
61
+ const global = pb.getGlobalScope();
62
+ const worldPos = global.$inputs.worldPos;
63
+ if (!worldPos) {
64
+ return pb.float(1);
65
+ }
66
+ const funcName = 'Z_envSkySpecularOcclusion';
67
+ pb.func(funcName, [
68
+ pb.vec3('n'),
69
+ pb.vec3('p'),
70
+ pb.float('NoV'),
71
+ pb.float('roughness')
72
+ ], function() {
73
+ this.$l.sky = sampleProbeIrradiance(this, this.p, this.n, pb.sub(this.camera.position.xyz, this.p), 'sky');
74
+ this.$l.vis = pb.mix(pb.float(1), this.sky.r, this.sky.a);
75
+ this.$l.r2 = pb.mul(this.roughness, this.roughness);
76
+ this.$return(pb.clamp(pb.add(pb.sub(pb.pow(pb.add(this.NoV, this.vis), this.r2), 1), this.vis), 0, 1));
77
+ });
78
+ return global[funcName](normal, worldPos, NoV, roughness);
79
+ }
80
+ /**
81
+ * Turns raw sky irradiance into material shading irradiance: scaled by the environment
82
+ * strength, then replaced by probe GI where covered (probes are not scaled again).
83
+ * Needs the `worldPos` varying; returns the raw irradiance without a draw context.
84
+ * @internal
85
+ */ applyProbes(scope, normal, ctx, irradiance) {
86
+ const pb = scope.$builder;
87
+ if (!ctx) {
88
+ return irradiance;
89
+ }
90
+ // The light uniforms of the material's light pass; see ShaderHelper.getEnvLightStrength
91
+ const sky = pb.mul(irradiance, scope.light.envLightStrength);
92
+ if (!getProbeVolumeForDraw(ctx)) {
93
+ return sky;
94
+ }
95
+ const global = pb.getGlobalScope();
96
+ const worldPos = global.$inputs.worldPos;
97
+ if (!worldPos) {
98
+ return sky;
99
+ }
100
+ const funcName = 'Z_envIrradianceWithProbes';
101
+ pb.func(funcName, [
102
+ pb.vec3('n'),
103
+ pb.vec3('p'),
104
+ pb.vec3('env')
105
+ ], function() {
106
+ this.$l.probe = sampleProbeIrradiance(this, this.p, this.n, pb.sub(this.camera.position.xyz, this.p));
107
+ this.$return(pb.mix(this.env, this.probe.rgb, this.probe.a));
108
+ });
109
+ return global[funcName](normal, worldPos, sky);
110
+ }
62
111
  }
63
112
  /**
64
113
  * IBL with SH based environment lighting
@@ -76,9 +125,7 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
76
125
  /** @internal */ static UNIFORM_NAME_SSGI_TARGET_SIZE = 'zSSGITargetSize';
77
126
  /** @internal */ static UNIFORM_NAME_SSGI_REPROJECTION = 'zSSGIReprojection';
78
127
  /**
79
- * Transforms a current-frame view-space position into previous-frame clip
80
- * space, so the reprojected depth can be compared against the surface history
81
- * in the frame that history was written in. @internal
128
+ * Current view space -> previous-frame clip space. @internal
82
129
  */ static UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP = 'zSSGIViewToPrevClip';
83
130
  /** Unprojects a screen-space sample back into current view space. @internal */ static UNIFORM_NAME_SSGI_INV_PROJECTION = 'zSSGIInvProjection';
84
131
  /** Scratch for the view -> previous clip composition. @internal */ static _viewToPrevClip = new Matrix4x4();
@@ -163,8 +210,7 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
163
210
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_WINDOW] = pb.vec3().uniform(0);
164
211
  }
165
212
  if (EnvShIBL.hasSSGIHistory(ctx)) {
166
- const irradianceSampler = pb.getDevice().type === 'webgl' ? 'clamp_nearest_nomip' : 'clamp_linear_nomip';
167
- pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE] = pb.tex2D().uniform(0).withSampler(getSamplerOptions(irradianceSampler));
213
+ pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_linear_nomip'));
168
214
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_SURFACE] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_nearest_nomip'));
169
215
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_CURRENT_DEPTH] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_nearest_nomip'));
170
216
  if (ctx?.motionVectorTexture) {
@@ -175,6 +221,7 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
175
221
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP] = pb.mat4().uniform(0);
176
222
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_INV_PROJECTION] = pb.mat4().uniform(0);
177
223
  }
224
+ this.initProbeBindings(pb, ctx);
178
225
  }
179
226
  }
180
227
  /**
@@ -196,7 +243,7 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
196
243
  bg.setValue(EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_WINDOW, this.irradianceWindow);
197
244
  }
198
245
  if (EnvShIBL.hasSSGIHistory(ctx)) {
199
- bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE, ctx.SSGIIrradianceHistoryTexture, fetchSampler(ctx.device.type === 'webgl' ? 'clamp_nearest_nomip' : 'clamp_linear_nomip'));
246
+ bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE, ctx.SSGIIrradianceHistoryTexture, fetchSampler('clamp_linear_nomip'));
200
247
  bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_SURFACE, ctx.SSGISurfaceHistoryTexture, fetchSampler('clamp_nearest_nomip'));
201
248
  bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_CURRENT_DEPTH, ctx.linearDepthTexture, fetchSampler('clamp_nearest_nomip'));
202
249
  if (ctx.motionVectorTexture) {
@@ -204,15 +251,13 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
204
251
  }
205
252
  bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_TARGET_SIZE, new Vector2(ctx.renderWidth, ctx.renderHeight));
206
253
  bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_REPROJECTION, new Vector4(ctx.camera.ssgiDepthReject, ctx.camera.ssgiNormalReject, ctx.camera.getFarPlane(), ctx.camera.getNearPlane()));
207
- // View -> world -> previous clip. `prevVPMatrix` is null on the first frame
208
- // after a history reset; falling back to the current VP makes the expected
209
- // previous depth equal the current one, so the depth term is a no-op until
210
- // a real previous frame exists.
254
+ // View -> world -> previous clip; without a previous VP the current one makes the depth term a no-op.
211
255
  const prevVP = ctx.camera.prevVPMatrix ?? ctx.camera.viewProjectionMatrix;
212
256
  Matrix4x4.multiply(prevVP, ctx.camera.worldMatrix, EnvShIBL._viewToPrevClip);
213
257
  bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP, EnvShIBL._viewToPrevClip);
214
258
  bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_INV_PROJECTION, ctx.camera.getInvProjectionMatrix());
215
259
  }
260
+ this.updateProbeBindGroup(bg, ctx);
216
261
  }
217
262
  /**
218
263
  * {@inheritDoc EnvironmentLighting.getRadiance}
@@ -306,7 +351,7 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
306
351
  }
307
352
  this.$return(this.c);
308
353
  });
309
- const iblIrradiance = pb.getGlobalScope().Z_sh_eval(normal);
354
+ const iblIrradiance = this.applyProbes(scope, normal, ctx ?? null, pb.getGlobalScope().Z_sh_eval(normal));
310
355
  if (!EnvShIBL.hasSSGIHistory(ctx)) {
311
356
  return iblIrradiance;
312
357
  }
@@ -325,7 +370,8 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
325
370
  this.$l.motionValid = pb.bool(true);
326
371
  }
327
372
  this.$l.params = this[EnvShIBL.UNIFORM_NAME_SSGI_REPROJECTION];
328
- this.$l.fallback = pb.mul(this.ibl, this.light.envLightStrength);
373
+ // Already in the history's units: scaled by the environment strength, probes in place
374
+ this.$l.fallback = this.ibl;
329
375
  this.$l.normalizedCurrentNormal = pb.normalize(this.currentNormal);
330
376
  this.$l.depthTolerance = pb.max(this.params.x, 1e-4);
331
377
  this.$l.texelSize = pb.div(pb.vec2(1), this[EnvShIBL.UNIFORM_NAME_SSGI_TARGET_SIZE]);
@@ -336,22 +382,12 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
336
382
  this.$l.previousSurface = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_SURFACE], this.previousSampleUV, 0);
337
383
  this.$l.previousNormal = pb.normalize(pb.sub(pb.mul(this.previousSurface.rgb, 2), pb.vec3(1)));
338
384
  this.$l.currentDepthSample = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_CURRENT_DEPTH], this.uv, 0);
339
- this.$l.currentDepth = pb.mul(pb.getDevice().type === 'webgl' ? decodeNormalizedFloatFromRGBA(this, this.currentDepthSample) : this.currentDepthSample.r, this.params.z);
340
- // The surface history holds a Z measured in the *previous* frame's view
341
- // space, so the current Z cannot be compared against it directly: under
342
- // camera rotation a static, correctly reprojected point has
343
- // `dz ~ r * sin(theta) * dphi`, which crosses any fixed threshold at the
344
- // screen edges and drops history in the exact staircase pattern that
345
- // nearest-neighbour sampling of the reprojected UV produces. Rebuild the
346
- // current view-space position and push it through `view -> previous clip`
347
- // instead; `clip.w` is `-view.z`, i.e. the same positive view-space
348
- // distance the history stores.
385
+ this.$l.currentDepth = pb.mul(this.currentDepthSample.r, this.params.z);
386
+ // History Z is in the previous frame's view space; compare via view -> previous
387
+ // clip (`clip.w` = positive view distance) to avoid edge staircases under rotation.
349
388
  this.$l.ndc = pb.sub(pb.mul(this.uv, 2), pb.vec2(1));
350
389
  this.$l.nearPlaneRay = pb.mul(this[EnvShIBL.UNIFORM_NAME_SSGI_INV_PROJECTION], pb.vec4(this.ndc, REVERSE_Z ? 1 : -1, 1));
351
- // Perspective unprojection of the near-plane NDC depth (GL -1, reverse
352
- // ZO 1) lands on the near plane, where view z is exactly -near; scaling
353
- // that ray by depth/near walks it out to the sample without a
354
- // non-linear depth round trip.
390
+ // Unprojecting near-plane NDC depth lands at view z = -near; scale by depth/near.
355
391
  this.$l.viewPos = pb.mul(pb.div(this.nearPlaneRay.xyz, this.nearPlaneRay.w), pb.div(this.currentDepth, pb.max(this.params.w, 1e-6)));
356
392
  this.$l.expectedPreviousDepth = pb.mul(this[EnvShIBL.UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP], pb.vec4(this.viewPos, 1)).w;
357
393
  this.$l.depthDelta = pb.abs(pb.sub(this.previousSurface.a, this.expectedPreviousDepth));
@@ -364,44 +400,27 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
364
400
  this.$l.previousAlpha = pb.clamp(this.previousIrradiance.a, 0, 1);
365
401
  this.$l.exactHistoryValid = pb.and(this.previousUVInBounds, this.depthValid, this.normalValid, pb.greaterThan(this.previousAlpha, 1e-4));
366
402
  this.$if(this.exactHistoryValid, function() {
367
- // Weighting confidence by the depth term keeps the gate boundary a ramp
368
- // rather than a step, so residual reprojection error on moving geometry
369
- // and grazing surfaces fades out instead of outlining itself.
403
+ // Depth-weighted confidence ramps the gate boundary instead of stepping it.
370
404
  this.$l.exactConfidence = pb.mul(this.previousAlpha, this.depthWeight);
371
405
  this.$if(pb.greaterThan(this.exactConfidence, 1e-4), function() {
372
406
  this.$return(pb.mix(this.fallback, this.previousIrradiance.rgb, this.exactConfidence));
373
407
  });
374
408
  });
375
- // Repair disoccluded and off-screen history from nearby samples before
376
- // falling back to IBL. Sampling around the clamped reprojected position
377
- // fills camera-edge holes, while current UV provides a conservative
378
- // screen-stationary candidate for invalid motion vectors.
409
+ // Repair disoccluded/off-screen history from nearby samples before falling back to
410
+ // IBL: taps around the clamped reprojection, plus current UV for invalid motion.
379
411
  this.$l.repairCenter = this.$choice(this.motionValid, this.previousSampleUV, pb.clamp(this.uv, this.halfTexel, this.maxUV));
380
- // How far the reprojection had to be clamped to land back on screen. For a
381
- // hole in the interior this is zero and the taps really are neighbours of
382
- // the reprojected point, but for geometry rotating in from off screen the
383
- // clamp can travel hundreds of pixels -- and the depth and normal terms
384
- // cannot catch that, because the edge texel it lands on is usually the same
385
- // continuous surface (same normal, similar depth) merely sampled somewhere
386
- // spatially unrelated. Its irradiance therefore belongs to a different part
387
- // of the surface, so reading it as a point sample smears into streaks along
388
- // the direction of travel. Drive the tap radius with it instead, trading
389
- // that structure for a blur.
412
+ // Clamp travel back onto the screen: zero for interior holes, large for geometry
413
+ // rotating in, where the edge texel is the same surface but unrelated irradiance.
414
+ // It drives the tap radius, trading streaks for blur.
390
415
  this.$l.repairClampTexels = pb.div(pb.length(pb.sub(this.previousSampleUV, this.previousUV)), pb.max(pb.min(this.texelSize.x, this.texelSize.y), 1e-8));
391
- // Widen the taps as the clamp travel grows. Only meaningful while the motion
392
- // vector is usable: without one the centre is already the current UV by
393
- // construction, so there is no travel to react to.
416
+ // Widen taps with clamp travel; only while motion vectors are usable.
394
417
  this.$l.repairRadius = pb.mix(pb.float(SSGI_REPAIR_MIN_RADIUS_TEXELS), pb.float(SSGI_REPAIR_MAX_RADIUS_TEXELS), this.$choice(this.motionValid, pb.smoothStep(0, SSGI_REPAIR_WIDE_CLAMP_TEXELS, this.repairClampTexels), pb.float(0)));
395
- // Taps this far apart straddle real depth variation across the surface, so a
396
- // gate tuned for immediate neighbours would reject most of them and bring
397
- // the dark band back. Loosen it with the radius and lean on the normal term,
398
- // which stays strict, to keep the average on one surface.
418
+ // Wide taps straddle real depth variation: loosen the depth gate with the radius
419
+ // and rely on the strict normal term.
399
420
  this.$l.repairDepthTolerance = pb.mul(this.scaledDepthTolerance, SSGI_DEPTH_GATE_SCALE, pb.add(1, this.repairRadius));
400
421
  this.$l.repairSum = pb.vec3(0);
401
422
  this.$l.repairWeight = pb.float(0);
402
- // A full ring rather than a cross: at the wide end four taps are not an
403
- // average but four distant point copies, and their axis alignment paints
404
- // directional artifacts of its own.
423
+ // Full ring: four wide axis-aligned taps paint directional artifacts.
405
424
  const repairSamples = [
406
425
  {
407
426
  currentUV: false,
@@ -471,21 +490,16 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
471
490
  this.$l[`repairUVValid${i}`] = pb.and(pb.all(pb.greaterThanEqual(this[`repairUV${i}`], this.halfTexel)), pb.all(pb.lessThanEqual(this[`repairUV${i}`], this.maxUV)));
472
491
  this.$l[`repairSurface${i}`] = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_SURFACE], pb.clamp(this[`repairUV${i}`], this.halfTexel, this.maxUV), 0);
473
492
  this.$l[`repairNormal${i}`] = pb.normalize(pb.sub(pb.mul(this[`repairSurface${i}`].rgb, 2), pb.vec3(1)));
474
- // Compared against the reprojected depth, not the current one: the taps
475
- // are samples of the previous frame's surface, so they live in the same
476
- // space as `expectedPreviousDepth`.
493
+ // Compared against the reprojected depth: taps sample the previous frame's surface.
477
494
  this.$l[`repairDepthDelta${i}`] = pb.abs(pb.sub(this[`repairSurface${i}`].a, this.expectedPreviousDepth));
478
495
  this.$l[`repairNormalDot${i}`] = pb.dot(this.normalizedCurrentNormal, this[`repairNormal${i}`]);
479
496
  this.$l[`repairSurfaceValid${i}`] = pb.and(this[`repairUVValid${i}`], pb.lessThanEqual(this[`repairDepthDelta${i}`], this.repairDepthTolerance), pb.greaterThanEqual(this[`repairNormalDot${i}`], this.params.y));
480
497
  this.$l[`repairIrradiance${i}`] = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE], pb.clamp(this[`repairUV${i}`], this.halfTexel, this.maxUV), 0);
481
- // Same widening as the hard gate above: a falloff tuned for immediate
482
- // neighbours decays to nothing across a wide tap and starves the average.
498
+ // Same widening as the hard gate above.
483
499
  this.$l[`repairDepthWeight${i}`] = pb.exp(pb.neg(pb.div(this[`repairDepthDelta${i}`], this.repairDepthTolerance)));
484
500
  this.$l[`repairNormalWeight${i}`] = pb.pow(pb.max(0, this[`repairNormalDot${i}`]), 8);
485
- this.$l[`repairSampleWeight${i}`] = pb.mul(pb.float(this[`repairSurfaceValid${i}`]), pb.clamp(this[`repairIrradiance${i}`].a, 0, 1), this[`repairDepthWeight${i}`], this[`repairNormalWeight${i}`], // The screen-stationary tap only exists to cover unusable motion
486
- // vectors; while motion is valid it is a history read at the wrong world
487
- // point, which survives the depth term on any flat surface and leaves a
488
- // stationary ghost.
501
+ this.$l[`repairSampleWeight${i}`] = pb.mul(pb.float(this[`repairSurfaceValid${i}`]), pb.clamp(this[`repairIrradiance${i}`].a, 0, 1), this[`repairDepthWeight${i}`], this[`repairNormalWeight${i}`], // The screen-stationary tap only covers unusable motion vectors; otherwise it
502
+ // leaves a stationary ghost.
489
503
  sample.currentUV ? pb.float(pb.not(this.motionValid)) : pb.float(1), sample.kernel);
490
504
  this.repairSum = pb.add(this.repairSum, pb.mul(this[`repairIrradiance${i}`].rgb, this[`repairSampleWeight${i}`]));
491
505
  this.repairWeight = pb.add(this.repairWeight, this[`repairSampleWeight${i}`]);
@@ -502,7 +516,7 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
502
516
  return scope.Z_ssgi_reprojectIrradiance(normal, iblIrradiance);
503
517
  }
504
518
  /** Whether all textures required by the lighting reprojection are scoped. @internal */ static hasSSGIHistory(ctx) {
505
- return !!(ctx?.SSGI && ctx.SSGIIrradianceHistoryTexture && ctx.SSGISurfaceHistoryTexture && (ctx.device.type === 'webgl' || ctx.motionVectorTexture) && ctx.linearDepthTexture);
519
+ return !!(ctx?.SSGI && ctx.SSGIIrradianceHistoryTexture && ctx.SSGISurfaceHistoryTexture && ctx.motionVectorTexture && ctx.linearDepthTexture);
506
520
  }
507
521
  /**
508
522
  * {@inheritDoc EnvironmentLighting.hasRadiance}
@@ -563,46 +577,52 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
563
577
  /**
564
578
  * {@inheritDoc EnvironmentLighting.initShaderBindings}
565
579
  * @override
566
- */ initShaderBindings(pb) {
580
+ */ initShaderBindings(pb, ctx) {
567
581
  if (pb.shaderKind === 'fragment') {
568
582
  pb.getGlobalScope()[EnvConstantAmbient.UNIFORM_NAME_CONSTANT_AMBIENT] = pb.vec4().uniform(0);
583
+ this.initProbeBindings(pb, ctx);
569
584
  }
570
585
  }
571
586
  /**
572
587
  * {@inheritDoc EnvironmentLighting.updateBindGroup}
573
588
  * @override
574
- */ updateBindGroup(bg) {
589
+ */ updateBindGroup(bg, ctx) {
575
590
  bg.setValue(EnvConstantAmbient.UNIFORM_NAME_CONSTANT_AMBIENT, this._ambientColor);
591
+ this.updateProbeBindGroup(bg, ctx);
576
592
  }
577
593
  /**
578
594
  * {@inheritDoc EnvironmentLighting.getRadiance}
579
595
  * @override
580
- */ getRadiance(_scope, _refl, _roughness) {
581
- return null;
596
+ *
597
+ * @remarks
598
+ * A uniform environment prefilters to itself, so radiance is the ambient color. It
599
+ * must be present: at grazing angles specular takes the diffuse energy, else silhouettes go black.
600
+ */ getRadiance(scope, _refl, _roughness) {
601
+ return scope[EnvConstantAmbient.UNIFORM_NAME_CONSTANT_AMBIENT].rgb;
582
602
  }
583
603
  /**
584
604
  * {@inheritDoc EnvironmentLighting.getSheenRadiance}
585
605
  * @override
586
- */ getSheenRadiance(_scope, _refl, _roughness) {
587
- return null;
606
+ */ getSheenRadiance(scope, refl, roughness) {
607
+ return this.getRadiance(scope, refl, roughness);
588
608
  }
589
609
  /**
590
610
  * {@inheritDoc EnvironmentLighting.getIrradiance}
591
611
  * @override
592
- */ getIrradiance(scope, _normal) {
593
- return scope[EnvConstantAmbient.UNIFORM_NAME_CONSTANT_AMBIENT].rgb;
612
+ */ getIrradiance(scope, normal, ctx) {
613
+ return this.applyProbes(scope, normal, ctx ?? null, scope[EnvConstantAmbient.UNIFORM_NAME_CONSTANT_AMBIENT].rgb);
594
614
  }
595
615
  /**
596
616
  * {@inheritDoc EnvironmentLighting.hasRadiance}
597
617
  * @override
598
618
  */ hasRadiance() {
599
- return false;
619
+ return true;
600
620
  }
601
621
  /**
602
622
  * {@inheritDoc EnvironmentLighting.hasSheenRadiance}
603
623
  * @override
604
624
  */ hasSheenRadiance() {
605
- return false;
625
+ return true;
606
626
  }
607
627
  /**
608
628
  * {@inheritDoc EnvironmentLighting.hasIrradiance}
@@ -653,18 +673,20 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
653
673
  /**
654
674
  * {@inheritDoc EnvironmentLighting.initShaderBindings}
655
675
  * @override
656
- */ initShaderBindings(pb) {
676
+ */ initShaderBindings(pb, ctx) {
657
677
  if (pb.shaderKind === 'fragment') {
658
678
  pb.getGlobalScope()[EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_UP] = pb.vec4().uniform(0);
659
679
  pb.getGlobalScope()[EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_DOWN] = pb.vec4().uniform(0);
680
+ this.initProbeBindings(pb, ctx);
660
681
  }
661
682
  }
662
683
  /**
663
684
  * {@inheritDoc EnvironmentLighting.updateBindGroup}
664
685
  * @override
665
- */ updateBindGroup(bg) {
686
+ */ updateBindGroup(bg, ctx) {
666
687
  bg.setValue(EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_UP, this._ambientUp);
667
688
  bg.setValue(EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_DOWN, this._ambientDown);
689
+ this.updateProbeBindGroup(bg, ctx);
668
690
  }
669
691
  /**
670
692
  * {@inheritDoc EnvironmentLighting.getRadiance}
@@ -683,10 +705,10 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
683
705
  /**
684
706
  * {@inheritDoc EnvironmentLighting.getIrradiance}
685
707
  * @override
686
- */ getIrradiance(scope, normal) {
708
+ */ getIrradiance(scope, normal, ctx) {
687
709
  const pb = scope.$builder;
688
710
  const factor = pb.add(pb.mul(normal.y, 0.5), 0.5);
689
- return pb.mix(scope[EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_DOWN], scope[EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_UP], factor).rgb;
711
+ return this.applyProbes(scope, normal, ctx ?? null, pb.mix(scope[EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_DOWN], scope[EnvHemisphericAmbient.UNIFORM_NAME_AMBIENT_UP], factor).rgb);
690
712
  }
691
713
  /**
692
714
  * {@inheritDoc EnvironmentLighting.hasRadiance}
@@ -707,6 +729,67 @@ const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
707
729
  return true;
708
730
  }
709
731
  }
732
+ /**
733
+ * Environment lighting for type `none`: no sky, only probe-volume GI over black,
734
+ * since bounced scene light does not depend on the environment. Used only while
735
+ * the probe volume is ready.
736
+ * @internal
737
+ */ class EnvProbesOnly extends EnvironmentLighting {
738
+ /**
739
+ * {@inheritDoc EnvironmentLighting.getType}
740
+ * @override
741
+ */ getType() {
742
+ return 'none';
743
+ }
744
+ /**
745
+ * {@inheritDoc EnvironmentLighting.initShaderBindings}
746
+ * @override
747
+ */ initShaderBindings(pb, ctx) {
748
+ this.initProbeBindings(pb, ctx);
749
+ }
750
+ /**
751
+ * {@inheritDoc EnvironmentLighting.updateBindGroup}
752
+ * @override
753
+ */ updateBindGroup(bg, ctx) {
754
+ this.updateProbeBindGroup(bg, ctx);
755
+ }
756
+ /**
757
+ * {@inheritDoc EnvironmentLighting.getRadiance}
758
+ * @override
759
+ */ getRadiance(_scope, _refl, _roughness) {
760
+ return null;
761
+ }
762
+ /**
763
+ * {@inheritDoc EnvironmentLighting.getSheenRadiance}
764
+ * @override
765
+ */ getSheenRadiance(_scope, _refl, _roughness) {
766
+ return null;
767
+ }
768
+ /**
769
+ * {@inheritDoc EnvironmentLighting.getIrradiance}
770
+ * @override
771
+ */ getIrradiance(scope, normal, ctx) {
772
+ return this.applyProbes(scope, normal, ctx ?? null, scope.$builder.vec3(0));
773
+ }
774
+ /**
775
+ * {@inheritDoc EnvironmentLighting.hasRadiance}
776
+ * @override
777
+ */ hasRadiance() {
778
+ return false;
779
+ }
780
+ /**
781
+ * {@inheritDoc EnvironmentLighting.hasSheenRadiance}
782
+ * @override
783
+ */ hasSheenRadiance() {
784
+ return false;
785
+ }
786
+ /**
787
+ * {@inheritDoc EnvironmentLighting.hasIrradiance}
788
+ * @override
789
+ */ hasIrradiance() {
790
+ return true;
791
+ }
792
+ }
710
793
 
711
- export { EnvConstantAmbient, EnvHemisphericAmbient, EnvShIBL, EnvironmentLighting };
794
+ export { EnvConstantAmbient, EnvHemisphericAmbient, EnvProbesOnly, EnvShIBL, EnvironmentLighting };
712
795
  //# sourceMappingURL=envlight.js.map