@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
@@ -6,13 +6,14 @@ import { ShaderHelper } from '../material/shader/helper.js';
6
6
  import '../material/lambert.js';
7
7
  import '../material/blinn.js';
8
8
  import '../material/unlit.js';
9
+ import '../material/meshmaterial.js';
9
10
  import '../material/particle.js';
10
11
  import '../material/subsurfaceprofile.js';
11
- import '../material/skin.js';
12
+ import '../material/sssprofile.js';
13
+ import '../material/sss.js';
12
14
  import '../material/eye.js';
13
15
  import '@zephyr3d/device';
14
16
  import '../values.js';
15
- import '../material/meshmaterial.js';
16
17
  import '../material/hair.js';
17
18
  import '../material/hairstrand.js';
18
19
  import '../material/grassmaterial.js';
@@ -26,6 +27,8 @@ import '../material/sprite_std.js';
26
27
  import '../utility/blueprint/material/texture.js';
27
28
  import { linearToGamma } from '../shaders/misc.js';
28
29
  import { fetchSampler } from '../utility/misc.js';
30
+ import { getActiveProbeVolume } from '../render/gi/probe_volume.js';
31
+ import { declareProbeUniforms, sampleProbeIrradiance } from '../shaders/probes.js';
29
32
  import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
30
33
 
31
34
  const IRRADIANCE_FORMAT = 'rgba16f';
@@ -61,10 +64,10 @@ const MOMENT_LUMINANCE_MAX = 255;
61
64
  return !!ctx.SSGI;
62
65
  }
63
66
  /** {@inheritDoc AbstractPostEffect.requireMotionVectorTexture} */ requireMotionVectorTexture(ctx) {
64
- return !!ctx.SSGI && ctx.device.type !== 'webgl';
67
+ return !!ctx.SSGI;
65
68
  }
66
69
  /** {@inheritDoc AbstractPostEffect.requireHiZTexture} */ requireHiZTexture(ctx) {
67
- return !!ctx.SSGI && ctx.device.type !== 'webgl';
70
+ return !!ctx.SSGI;
68
71
  }
69
72
  /** {@inheritDoc AbstractPostEffect.requireSceneNormalTexture} */ requireSceneNormalTexture(ctx) {
70
73
  return !!ctx.SSGI;
@@ -78,12 +81,8 @@ const MOMENT_LUMINANCE_MAX = 255;
78
81
  const normalHandle = blackboard.get(FrameResources.SceneNormal);
79
82
  const motionHandle = blackboard.get(FrameResources.MotionVector);
80
83
  const hiZHandle = blackboard.get(FrameResources.HiZ);
81
- // Traced hits read this as outgoing surface radiance, so it must exclude the
82
- // fog the camera ray accumulated: that fog belongs to a different path than
83
- // the one being integrated, and feeding it back would brighten every bounce.
84
- // Absent when the scene has no fog, in which case SceneColor is already fog
85
- // free. Both the sampled color and the committed history use it, otherwise
86
- // the current and previous frames would disagree and flicker.
84
+ // Fog-free scene colour: traced hits read outgoing surface radiance, and camera
85
+ // fog would brighten every bounce. Trace and committed history must both use it.
87
86
  const noFogHandle = blackboard.get(FrameResources.SceneColorNoFog);
88
87
  const sampleColorHandle = noFogHandle ?? s.input;
89
88
  if (!linearDepthHandle || !normalHandle) {
@@ -140,19 +139,14 @@ const MOMENT_LUMINANCE_MAX = 255;
140
139
  const previousIrradianceHandle = findHistoryRead(RGHistoryResources.SSGI_IRRADIANCE);
141
140
  const previousSurfaceHandle = findHistoryRead(RGHistoryResources.SSGI_SURFACE);
142
141
  const previousMomentsHandle = history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_MOMENTS, momentsDesc, traceSize);
143
- // Only this effect's own temporal pass reads the AO history, so it is
144
- // imported directly instead of being routed through the light pass history
145
- // read bindings the way irradiance and surface are.
142
+ // Only this effect's temporal pass reads the AO history, so it is imported directly.
146
143
  const previousAOHandle = history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_AO, aoTraceDesc, traceSize);
147
- // Reprojecting last frame's colour needs motion vectors, which the WebGL1
148
- // backend does not produce. WebGL2 and WebGPU both do, so both take the
149
- // multi-bounce path.
150
- const previousSceneColorHandle = ctx.device.type !== 'webgl' ? history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_SCENE_COLOR, {
144
+ const previousSceneColorHandle = history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_SCENE_COLOR, {
151
145
  format: s.colorFormat,
152
146
  sizeMode: 'absolute',
153
147
  width: s.width,
154
148
  height: s.height
155
- }, fullSize) : null;
149
+ }, fullSize);
156
150
  const canSampleSceneHistory = !!(previousSceneColorHandle && previousSurfaceHandle && motionHandle);
157
151
  const readFrameInputs = (builder)=>{
158
152
  builder.read(linearDepthHandle);
@@ -167,9 +161,8 @@ const MOMENT_LUMINANCE_MAX = 255;
167
161
  builder.read(dep);
168
162
  }
169
163
  };
170
- // Trace one or two cosine-weighted diffuse rays. A hit prefers the previous
171
- // frame through previousHitUV = hitUV - motion(hitUV) for multi-bounce
172
- // feedback and falls back to the current frame when that reprojection fails.
164
+ // Trace one or two cosine-weighted diffuse rays. A hit prefers the previous frame
165
+ // (previousHitUV = hitUV - motion(hitUV)) for multi-bounce, else the current frame.
173
166
  const traceResult = graph.addPass('SSGI:Trace', (builder)=>{
174
167
  builder.read(sampleColorHandle);
175
168
  readFrameInputs(builder);
@@ -211,8 +204,7 @@ const MOMENT_LUMINANCE_MAX = 255;
211
204
  ao
212
205
  };
213
206
  });
214
- // Store the current full-resolution surface independently from irradiance;
215
- // no albedo MRT is needed because the next lighting pass applies the BRDF.
207
+ // Surface stored separately; no albedo MRT, the lighting pass applies the BRDF.
216
208
  const surfaceHandle = graph.addPass('SSGI:Surface', (builder)=>{
217
209
  builder.read(linearDepthHandle);
218
210
  builder.read(normalHandle);
@@ -240,10 +232,8 @@ const MOMENT_LUMINANCE_MAX = 255;
240
232
  });
241
233
  return out;
242
234
  });
243
- const canTemporal = !!(ctx.device.type !== 'webgl' && ctx.camera.ssgiTemporal && motionHandle && previousIrradianceHandle && previousSurfaceHandle && previousMomentsHandle && previousAOHandle);
244
- // Temporal pass always creates moments. On the first frame it simply
245
- // initializes them; with valid history it rejects by depth and normal,
246
- // neighborhood-clamps radiance, and accumulates first/second moments.
235
+ const canTemporal = !!(ctx.camera.ssgiTemporal && motionHandle && previousIrradianceHandle && previousSurfaceHandle && previousMomentsHandle && previousAOHandle);
236
+ // Rejects by depth and normal, neighborhood-clamps radiance, accumulates moments.
247
237
  const temporalResult = graph.addPass('SSGI:Temporal', (builder)=>{
248
238
  builder.read(traceResult.irradiance);
249
239
  builder.read(traceResult.ao);
@@ -294,9 +284,7 @@ const MOMENT_LUMINANCE_MAX = 255;
294
284
  ao
295
285
  };
296
286
  });
297
- // Variance-guided, cross-bilateral a-trous filtering. The increasing
298
- // kernel step removes low-frequency Monte Carlo noise while depth/normal
299
- // weights preserve discontinuities.
287
+ // Variance-guided cross-bilateral a-trous filtering.
300
288
  let filteredHandle = temporalResult.irradiance;
301
289
  let filteredAOHandle = temporalResult.ao;
302
290
  for(let pass = 0; pass < settings.denoisePasses; pass++){
@@ -345,8 +333,7 @@ const MOMENT_LUMINANCE_MAX = 255;
345
333
  filteredHandle = filtered.irradiance;
346
334
  filteredAOHandle = filtered.ao;
347
335
  }
348
- // Half-resolution presets use a joint bilateral upsample before history is
349
- // consumed by full-resolution materials on the next frame.
336
+ // Joint bilateral upsample for half-resolution presets.
350
337
  let finalIrradianceHandle = filteredHandle;
351
338
  let finalAOHandle = filteredAOHandle;
352
339
  if (settings.halfRes) {
@@ -394,13 +381,10 @@ const MOMENT_LUMINANCE_MAX = 255;
394
381
  finalIrradianceHandle = upsampled.irradiance;
395
382
  finalAOHandle = upsampled.ao;
396
383
  }
397
- // Pinned before the commit closure captures it: the a-trous loop above
398
- // reassigns the handle, and the AO history has to be the trace-resolution
399
- // one regardless of whether an upsample ran.
384
+ // Pinned here: the a-trous loop reassigns the handle, and AO history stays at trace resolution.
400
385
  const traceResolutionAOHandle = filteredAOHandle;
401
- // SSGI history is independent from TAA/SSR history. Commit the opaque HDR
402
- // SceneColor input (before SSR/transparency/tone-map/AA), irradiance,
403
- // surface and moments, then pass SceneColor through unchanged.
386
+ // Commit opaque HDR SceneColor (pre SSR/transparency/tonemap/AA), irradiance,
387
+ // surface and moments; SceneColor passes through unchanged.
404
388
  return graph.addPass('SSGI:Commit', (builder)=>{
405
389
  builder.read(s.input);
406
390
  if (noFogHandle) {
@@ -408,8 +392,7 @@ const MOMENT_LUMINANCE_MAX = 255;
408
392
  }
409
393
  builder.read(finalIrradianceHandle);
410
394
  builder.read(finalAOHandle);
411
- // The trace-resolution AO is what goes back into history, so it has to be
412
- // read here too even when the upsampled one is what gets composited.
395
+ // The trace-resolution AO goes back into history.
413
396
  builder.read(traceResolutionAOHandle);
414
397
  builder.read(surfaceHandle);
415
398
  builder.read(temporalResult.moments);
@@ -430,17 +413,13 @@ const MOMENT_LUMINANCE_MAX = 255;
430
413
  } else {
431
414
  this.passThrough(ctx, sceneColor, output.srgbOutput);
432
415
  }
433
- if (ctx.device.type !== 'webgl') {
434
- // Commit the same fog-free color the trace sampled, so next frame's
435
- // reprojected history is on the same footing as this frame's fallback.
436
- this.commitHistory(history, RGHistoryResources.SSGI_SCENE_COLOR, rg.getTexture(sampleColorHandle));
437
- }
416
+ // Same fog-free colour the trace sampled.
417
+ this.commitHistory(history, RGHistoryResources.SSGI_SCENE_COLOR, rg.getTexture(sampleColorHandle));
438
418
  this.commitHistory(history, RGHistoryResources.SSGI_IRRADIANCE, irradiance);
439
419
  this.commitHistory(history, RGHistoryResources.SSGI_SURFACE, surface);
440
420
  this.commitHistory(history, RGHistoryResources.SSGI_MOMENTS, moments);
441
- // Committed at trace resolution: the temporal pass that consumes it
442
- // runs before the upsample, so a full-resolution AO would fail the
443
- // descriptor compatibility check and silently disable accumulation.
421
+ // Trace resolution: the temporal pass runs before the upsample and needs a
422
+ // compatible descriptor, else accumulation is silently disabled.
444
423
  this.commitHistory(history, RGHistoryResources.SSGI_AO, filteredAO);
445
424
  } finally{
446
425
  device.popDeviceStates();
@@ -462,17 +441,18 @@ const MOMENT_LUMINANCE_MAX = 255;
462
441
  }
463
442
  /** @internal */ trace(ctx, currentColor, previousColor, depth, normal, motion, previousSurface, hiZ, width, height) {
464
443
  const sampleHistory = !!(previousColor && motion && previousSurface);
465
- const envHash = ctx.env.light.getHash();
444
+ const probes = getActiveProbeVolume(ctx.scene);
445
+ const envHash = `${ctx.env.light.getHash()}:probes${probes ? 1 : 0}`;
466
446
  const historyHash = sampleHistory ? `${previousColor.uid}:${motion.uid}:${previousSurface.uid}` : '';
467
447
  const hizHash = hiZ ? `${hiZ.uid}` : '';
468
448
  const programHash = `${sampleHistory ? '1' : '0'}:${hiZ ? '1' : '0'}:${ctx.camera.ssgiResolvedSettings.raysPerPixel}:${envHash}`;
469
449
  const bindGroupHash = `${currentColor.uid}:${depth.uid}:${normal.uid}:(${historyHash}):(${hizHash}):${ctx.camera.ssgiResolvedSettings.raysPerPixel}:${envHash}`;
470
450
  let program = SSGI._tracePrograms[programHash];
471
451
  if (!program) {
472
- program = this.createTraceProgram(ctx, !!hiZ, sampleHistory);
452
+ program = this.createTraceProgram(ctx, !!hiZ, sampleHistory, !!probes);
473
453
  SSGI._tracePrograms[programHash] = program;
474
454
  }
475
- const colorSampler = fetchSampler(ctx.device.type === 'webgl' ? 'clamp_nearest_nomip' : 'clamp_linear_nomip');
455
+ const colorSampler = fetchSampler('clamp_linear_nomip');
476
456
  let bindGroup = this._traceBindGroups[bindGroupHash];
477
457
  if (!bindGroup) {
478
458
  bindGroup = ctx.device.createBindGroup(program.bindGroupLayouts[0]);
@@ -504,6 +484,7 @@ const MOMENT_LUMINANCE_MAX = 255;
504
484
  bindGroup.setValue('skyOcclusion', ctx.camera.ssgiSkyOcclusion);
505
485
  bindGroup.setValue('flip', this.needFlip(ctx.device) ? 1 : 0);
506
486
  ctx.env.light.envLight.updateBindGroup(bindGroup);
487
+ probes?.applyBindGroup(bindGroup);
507
488
  ctx.device.setProgram(program);
508
489
  ctx.device.setBindGroup(0, bindGroup);
509
490
  this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'always'));
@@ -528,9 +509,7 @@ const MOMENT_LUMINANCE_MAX = 255;
528
509
  bindGroup.setTexture('previousIrradianceTex', previousIrradiance, fetchSampler('clamp_linear_nomip'));
529
510
  bindGroup.setTexture('previousSurfaceTex', previousSurface, fetchSampler('clamp_nearest_nomip'));
530
511
  bindGroup.setTexture('previousMomentsTex', previousMoments, fetchSampler('clamp_linear_nomip'));
531
- // Linear is safe here: this branch never runs on WebGL1, and both
532
- // WebGL2 and WebGPU filter r16f unconditionally. The read is at a
533
- // reprojected UV.
512
+ // r16f is filterable on WebGL2 and WebGPU.
534
513
  bindGroup.setTexture('previousAOTex', previousAO, fetchSampler('clamp_linear_nomip'));
535
514
  }
536
515
  this._temporalBindGroups[hash] = bindGroup;
@@ -561,9 +540,8 @@ const MOMENT_LUMINANCE_MAX = 255;
561
540
  }
562
541
  bindGroup.setValue('targetSize', new Vector4(width, height, depth.width, depth.height));
563
542
  bindGroup.setValue('filterParams', new Vector4(step, Math.max(0.001, ctx.camera.ssgiDepthReject), Math.max(1, ctx.camera.ssgiNormalReject * 32), 4));
564
- // Number of accumulated frames a pixel needs before its variance estimate is
565
- // trusted. Zero disables the ramp for paths that never build history, where
566
- // the stored length is pinned at 1 and would read as permanently new.
543
+ // Accumulated frames before the variance estimate is trusted. Zero disables the
544
+ // ramp for paths without history (stored length pinned at 1).
567
545
  bindGroup.setValue('denoiseParams', new Vector4(hasTemporalHistory ? 8 : 0, 0, 0, 0));
568
546
  bindGroup.setValue('cameraFar', ctx.camera.getFarPlane());
569
547
  bindGroup.setValue('flip', this.needFlip(ctx.device) ? 1 : 0);
@@ -615,7 +593,7 @@ const MOMENT_LUMINANCE_MAX = 255;
615
593
  ctx.device.setBindGroup(0, bindGroup);
616
594
  this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'always'));
617
595
  }
618
- /** @internal */ createTraceProgram(ctx, useHiZ, sampleHistory) {
596
+ /** @internal */ createTraceProgram(ctx, useHiZ, sampleHistory, useProbes) {
619
597
  const raysPerPixel = ctx.camera.ssgiResolvedSettings.raysPerPixel;
620
598
  const program = ctx.device.buildRenderProgram({
621
599
  vertex (pb) {
@@ -632,9 +610,7 @@ const MOMENT_LUMINANCE_MAX = 255;
632
610
  },
633
611
  fragment (pb) {
634
612
  this.currentColorTex = pb.tex2D().uniform(0);
635
- // Linear depth is r32f (or rg32f when thickness is enabled). These
636
- // formats are not filterable without the optional float32-filterable
637
- // feature, and all SSGI depth reads use a nearest sampler.
613
+ // Linear depth is r32f/rg32f, not filterable without float32-filterable; nearest only.
638
614
  this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
639
615
  this.normalTex = pb.tex2D().uniform(0);
640
616
  if (sampleHistory) {
@@ -644,9 +620,8 @@ const MOMENT_LUMINANCE_MAX = 255;
644
620
  this.historyRejectParams = pb.vec2().uniform(0);
645
621
  }
646
622
  if (useHiZ) {
647
- // Hi-Z is stored as r32f. It is only read with a nearest sampler,
648
- // so use the unfilterable sample type for adapters without the
649
- // optional float32-filterable feature (notably some AMD iGPUs).
623
+ // Hi-Z is r32f read with nearest; unfilterable sample type for adapters without
624
+ // float32-filterable (notably some AMD iGPUs).
650
625
  this.hizTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
651
626
  this.depthMipLevels = pb.int().uniform(0);
652
627
  }
@@ -660,6 +635,9 @@ const MOMENT_LUMINANCE_MAX = 255;
660
635
  this.radianceParams = pb.vec4().uniform(0);
661
636
  this.skyOcclusion = pb.float().uniform(0);
662
637
  ctx.env.light.envLight.initShaderBindings(pb);
638
+ if (useProbes) {
639
+ declareProbeUniforms(this, 0);
640
+ }
663
641
  this.$outputs.outColor = pb.vec4();
664
642
  this.$outputs.outAO = pb.vec4();
665
643
  pb.func('SSGI_getPosition', [
@@ -695,33 +673,32 @@ const MOMENT_LUMINANCE_MAX = 255;
695
673
  this.$l.pos = this.SSGI_getPosition(this.uv);
696
674
  this.$if(pb.greaterThanEqual(this.pos.w, 1), function() {
697
675
  this.$outputs.outColor = pb.vec4(0);
698
- // Sky is unoccluded. Its irradiance validity is zero, so this value
699
- // is never read as a weight, but it must not be a dark texel: the
700
- // a-trous and upsample kernels reach across the silhouette.
676
+ // Sky: validity is zero, but the texel must not be dark since the a-trous and
677
+ // upsample kernels reach across the silhouette.
701
678
  this.$outputs.outAO = pb.vec4(1);
702
679
  }).$else(function() {
703
680
  this.$l.worldNormal = pb.normalize(pb.sub(pb.mul(pb.textureSampleLevel(this.normalTex, this.uv, 0).rgb, 2), pb.vec3(1)));
704
681
  this.$l.viewNormal = pb.normalize(pb.mul(this.viewMatrix, pb.vec4(this.worldNormal, 0)).xyz);
705
- // Use the SH-integrated diffuse IBL as an exact, noise-free
706
- // baseline. Stochastic rays only estimate the screen-space
707
- // replacement relative to the environment in the same direction.
708
- //
709
- // getIrradiance returns the cosine-convolved SH, which already
710
- // carries the 1/PI of the Lambert BRDF: materials consume it as
711
- // k_D * irradiance with no further division, matching punctual
712
- // lights that apply 1/PI explicitly. The published history is mixed
713
- // against that same value in the lighting pass, so this baseline
714
- // must stay in those units and must not be scaled by PI.
682
+ // Baseline is the SH diffuse IBL; rays only estimate the screen-space correction.
683
+ // getIrradiance already carries the Lambert 1/PI, as does the lighting pass that
684
+ // mixes the history, so this must not be scaled by PI.
715
685
  this.$l.iblIrradiance = pb.mul(ctx.env.light.envLight.getIrradiance(this, this.worldNormal), this.radianceParams.z);
686
+ // With probes the baseline is their irradiance, which already includes occlusion
687
+ // and bounces; rays only add on-screen detail.
688
+ this.$l.probeValid = pb.float(0);
689
+ if (useProbes) {
690
+ this.$l.worldPos = pb.mul(this.invViewMatrix, pb.vec4(this.pos.xyz, 1)).xyz;
691
+ this.$l.cameraPos = pb.mul(this.invViewMatrix, pb.vec4(0, 0, 0, 1)).xyz;
692
+ this.$l.probe = sampleProbeIrradiance(this, this.worldPos, this.worldNormal, pb.sub(this.cameraPos, this.worldPos));
693
+ this.iblIrradiance = pb.mix(this.iblIrradiance, this.probe.rgb, this.probe.a);
694
+ this.probeValid = this.probe.a;
695
+ }
716
696
  this.$l.correctionSum = pb.vec3(0);
717
- // Rays whose outcome the depth buffer cannot resolve (they left the
718
- // screen or ran out of iterations behind geometry) are excluded from
719
- // the average instead of counted as unoccluded sky.
697
+ // Rays the depth buffer cannot resolve (off-screen or out of iterations) are
698
+ // excluded from the average, not counted as sky.
720
699
  this.$l.determinateSum = pb.float(0);
721
700
  this.$l.escapedSum = pb.float(0);
722
- // Ambient occlusion reuses the very same visibility measurement the
723
- // sky removal is built on, so the two can never disagree. No extra
724
- // ray march: only this accumulator is new.
701
+ // AO reuses the sky-removal visibility measurement, so the two never disagree.
725
702
  this.$l.occludedSum = pb.float(0);
726
703
  this.$for(pb.float('rayIndex'), 0, raysPerPixel, function() {
727
704
  this.$l.xi = this.SSGI_hash22(pb.add(pb.mul(this.uv, this.targetSize.xy), pb.vec2(this.rayIndex, pb.mul(this.rayIndex, 7))), pb.add(this.radianceParams.w, pb.mul(this.rayIndex, 17)));
@@ -731,29 +708,24 @@ const MOMENT_LUMINANCE_MAX = 255;
731
708
  // vec3(occluded, escaped, rawConfidence) - see screenSpaceRayTracing_Linear2D.
732
709
  this.$l.giTrace = pb.vec3(0);
733
710
  if (useHiZ) {
734
- // UE5 SSGI: diffuse rays march with RayRoughness = 1 (fast mip
735
- // ramp) and StepOffset = noise - 0.9. A dedicated hash keeps
736
- // the jitter decorrelated from the direction sample.
737
711
  this.$l.stepOffset = pb.sub(this.SSGI_hash22(pb.add(pb.mul(this.uv, this.targetSize.xy), pb.vec2(pb.mul(this.rayIndex, 23), 11)), pb.add(this.radianceParams.w, pb.mul(this.rayIndex, 29))).x, 0.9);
738
712
  this.$l.hit = screenSpaceRayTracing_HiZ(this, this.rayOrigin, this.viewRay, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.depthMipLevels, this.traceParams.z, this.traceParams.x, this.traceParams.y, this.targetSize, this.hizTex, this.normalTex, this.giTrace, 1, this.stepOffset);
739
713
  } else {
740
714
  this.$l.hit = screenSpaceRayTracing_Linear2D(this, this.rayOrigin, this.viewRay, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.traceParams.x, this.traceParams.z, this.traceParams.y, this.traceParams.w, this.targetSize, this.depthTex, this.normalTex, false, this.giTrace);
741
715
  }
742
- // Grazing/projectively degenerate rays can return Inf or NaN.
743
- // A zero weight is not sufficient because NaN * 0 remains NaN and
744
- // the spatial passes then spread it into a dark block.
716
+ // Degenerate rays can return Inf/NaN; a zero weight is not enough (NaN * 0 = NaN).
745
717
  this.$l.hitFinite = pb.all(pb.lessThan(pb.abs(this.hit), pb.vec4(1e30)));
746
- // Visibility and radiance are kept apart: whether the ray was
747
- // blocked is independent of whether the blocker's outgoing
748
- // radiance can be read back from the screen. Geometric certainty
749
- // gates occlusion so a thin-object false positive cannot darken,
750
- // while the hit's screen colour is always a usable radiance
751
- // estimate because the marcher only ever stops on-screen.
718
+ // Visibility and radiance are separate: geometric certainty gates occlusion so thin
719
+ // false positives cannot darken, while the on-screen hit colour is always usable.
752
720
  this.$l.occluded = pb.mul(pb.float(this.hitFinite), pb.clamp(this.giTrace.x, 0, 1), pb.clamp(this.giTrace.z, 0, 1));
753
721
  this.$l.escaped = pb.mul(pb.float(this.hitFinite), pb.clamp(this.giTrace.y, 0, 1));
754
722
  this.$l.hitUV = this.$choice(pb.greaterThan(this.occluded, 0), pb.clamp(this.hit.xy, pb.vec2(0), pb.vec2(1)), this.uv);
755
723
  this.$l.rawEnvRadiance = pb.mul(ctx.env.light.envLight.getRadiance(this, this.worldRay, pb.float(0)), this.radianceParams.z);
756
724
  this.$l.envRadiance = this.$choice(pb.all(pb.lessThan(pb.abs(this.rawEnvRadiance), pb.vec3(1e30))), this.rawEnvRadiance, pb.vec3(0));
725
+ if (useProbes) {
726
+ // A hit is judged against what the probes expect there, not the open sky
727
+ this.envRadiance = pb.mix(this.envRadiance, this.iblIrradiance, this.probeValid);
728
+ }
757
729
  this.$l.currentRadiance = pb.textureSampleLevel(this.currentColorTex, this.hitUV, 0).rgb;
758
730
  if (sampleHistory) {
759
731
  this.$l.hitMotion = pb.textureSampleLevel(this.motionTex, this.hitUV, 0).xy;
@@ -765,11 +737,8 @@ const MOMENT_LUMINANCE_MAX = 255;
765
737
  this.$l.previousHitSurface = pb.textureSampleLevel(this.previousSurfaceTex, pb.clamp(this.previousHitUV, pb.vec2(0), pb.vec2(1)), 0);
766
738
  this.$l.previousHitNormal = pb.normalize(pb.sub(pb.mul(this.previousHitSurface.rgb, 2), pb.vec3(1)));
767
739
  this.historyValid = pb.and(this.historyValid, pb.lessThanEqual(pb.abs(pb.sub(this.previousHitSurface.a, this.currentHitDepth)), this.historyRejectParams.x), pb.greaterThanEqual(pb.dot(this.currentHitNormal, this.previousHitNormal), this.historyRejectParams.y));
768
- // Prefer the reprojected previous frame for multi-bounce
769
- // feedback, but fall back to this frame's already-shaded opaque
770
- // colour rather than dropping the sample. Losing one bounce of
771
- // feedback is a far smaller error than reverting to unoccluded
772
- // IBL, which is what made newly disoccluded regions flash.
740
+ // Prefer the reprojected previous frame for multi-bounce, else this frame's
741
+ // shaded colour rather than dropping the sample (avoids disocclusion flashes).
773
742
  this.$l.screenRadiance = this.$choice(this.historyValid, this.historyRadiance, this.currentRadiance);
774
743
  } else {
775
744
  this.$l.screenRadiance = this.currentRadiance;
@@ -779,44 +748,27 @@ const MOMENT_LUMINANCE_MAX = 255;
779
748
  this.$l.maxComponent = pb.max(pb.max(this.screenRadiance.r, this.screenRadiance.g), this.screenRadiance.b);
780
749
  this.$l.fireflyScale = this.$choice(pb.greaterThan(this.maxComponent, this.radianceParams.y), pb.div(this.radianceParams.y, pb.max(this.maxComponent, 1e-5)), pb.float(1));
781
750
  this.$l.clampedScreenRadiance = pb.mul(this.screenRadiance, this.fireflyScale);
782
- // Split the correction into the bounce the blocker adds and the sky
783
- // it takes away. The bounce is always kept: the hit is on-screen, so
784
- // its colour is a real measurement. Only the removal is scaled by
785
- // skyOcclusion, which lets the sky be dimmed less than physically
786
- // implied without also discarding measured bounce light.
751
+ // Bounce added by the blocker is always kept; only the sky removal is scaled by skyOcclusion.
787
752
  this.$l.bounceGain = pb.max(pb.sub(this.clampedScreenRadiance, this.envRadiance), pb.vec3(0));
788
753
  this.$l.skyLoss = pb.mul(pb.max(pb.sub(this.envRadiance, this.clampedScreenRadiance), pb.vec3(0)), this.skyOcclusion);
789
- // Cosine-weighted sampling makes the estimator of E/PI - the unit
790
- // the baseline and the lighting pass both use - the plain mean of
791
- // the sampled radiance, so no PI appears here either.
754
+ // Cosine-weighted sampling: the plain mean estimates E/PI, so no PI here.
792
755
  this.$l.correction = pb.mul(pb.sub(this.bounceGain, this.skyLoss), this.occluded, this.radianceParams.x);
793
756
  this.correctionSum = pb.add(this.correctionSum, this.correction);
794
757
  this.determinateSum = pb.add(this.determinateSum, pb.max(this.occluded, this.escaped));
795
758
  this.escapedSum = pb.add(this.escapedSum, this.escaped);
796
759
  this.occludedSum = pb.add(this.occludedSum, this.occluded);
797
760
  });
798
- // Average over resolved rays only. Dividing by raysPerPixel would
799
- // implicitly treat every indeterminate ray as an unoccluded sky
800
- // sample, which is the systematic sky leak this pass has to avoid.
761
+ // Average over resolved rays only, so indeterminate rays do not leak sky.
801
762
  this.$l.determinateCount = pb.max(this.determinateSum, 1);
802
763
  this.$l.irradiance = pb.add(this.iblIrradiance, pb.div(this.correctionSum, this.determinateCount));
803
- // radianceParams.x blends the traced estimate over the IBL baseline. A finite-ray
804
- // correction can have much higher variance than the integrated physical sky and must
805
- // not remove more than that blend permits (at the default 0.7, at least 30% remains).
806
- // That reserved share is itself scaled by measured visibility, otherwise no amount of
807
- // occlusion could ever darken an enclosed corner.
808
- this.$l.minimumIrradiance = pb.mul(this.iblIrradiance, pb.max(0, pb.sub(1, this.radianceParams.x)), pb.mix(pb.float(1), pb.div(this.escapedSum, this.determinateCount), this.skyOcclusion));
809
- // Clamp before the render-target conversion: a finite value that overflows becomes Inf
810
- // in the texture, and every a-trous pass then expands the contaminated region by its
811
- // kernel radius. Pre-exposed lighting makes this unlikely, but a bright emissive hit
812
- // amplified by a low-probability ray can still reach it.
764
+ // radianceParams.x blends the traced estimate over the IBL baseline; the reserved
765
+ // share (30% at 0.7) is scaled by visibility so corners can still darken.
766
+ // With probes the baseline is already occluded, so the floor is not scaled down again
767
+ this.$l.minimumIrradiance = pb.mul(this.iblIrradiance, pb.max(0, pb.sub(1, this.radianceParams.x)), pb.mix(pb.mix(pb.float(1), pb.div(this.escapedSum, this.determinateCount), this.skyOcclusion), pb.float(1), this.probeValid));
768
+ // Clamp before the RT conversion: overflow becomes Inf and a-trous spreads it.
813
769
  this.$l.boundedIrradiance = pb.clamp(pb.max(this.irradiance, this.minimumIrradiance), pb.vec3(0), pb.vec3(HALF_FLOAT_MAX));
814
770
  this.$outputs.outColor = pb.vec4(this.boundedIrradiance, 1);
815
- // Cosine-weighted sampling makes the mean of `occluded` over the
816
- // resolved rays an unbiased estimate of cosine-weighted visibility.
817
- // Averaging over the determinate set - not raysPerPixel - is what
818
- // keeps an indeterminate ray from reading as unoccluded, the same
819
- // reasoning the irradiance average uses above.
771
+ // Mean of `occluded` over resolved rays estimates cosine-weighted visibility.
820
772
  this.$outputs.outAO = pb.vec4(pb.clamp(pb.sub(1, pb.div(this.occludedSum, this.determinateCount)), 0, 1));
821
773
  });
822
774
  });
@@ -901,15 +853,12 @@ const MOMENT_LUMINANCE_MAX = 255;
901
853
  this.$l.previousClamped = pb.clamp(this.previous.rgb, this.neighborhoodMin, this.neighborhoodMax);
902
854
  this.$l.previousMoment = pb.textureSampleLevel(this.previousMomentsTex, pb.clamp(this.previousUV, pb.vec2(0), pb.vec2(1)), 0);
903
855
  this.$l.validity = pb.mul(pb.float(pb.and(this.validUV, this.surfaceValid)), pb.clamp(this.previous.a, 0, 1));
904
- // Start new histories as a running average, then cap their weight
905
- // at the configured value once enough samples have accumulated.
856
+ // Running average until the configured history weight cap is reached.
906
857
  this.$l.runningAverageWeight = pb.div(this.previousMoment.z, pb.add(this.previousMoment.z, 1));
907
858
  this.$l.historyWeight = pb.min(this.temporalParams.x, this.runningAverageWeight);
908
859
  this.$l.weight = pb.mul(this.historyWeight, this.validity);
909
860
  this.result = pb.mix(this.current.rgb, this.previousClamped, this.weight);
910
- // AO accumulates on exactly the same validity and weight as the
911
- // irradiance: it was measured by the same rays against the same
912
- // surface, so any disagreement between the two would be an artifact.
861
+ // AO accumulates with the same validity and weight as irradiance.
913
862
  this.$l.previousAO = pb.textureSampleLevel(this.previousAOTex, pb.clamp(this.previousUV, pb.vec2(0), pb.vec2(1)), 0).r;
914
863
  this.$l.previousAOClamped = pb.clamp(this.previousAO, this.aoNeighborhoodMin, this.aoNeighborhoodMax);
915
864
  this.resultAO = pb.mix(this.currentAO, this.previousAOClamped, this.weight);
@@ -918,9 +867,7 @@ const MOMENT_LUMINANCE_MAX = 255;
918
867
  this.$l.variance = pb.max(0, pb.sub(this.momentXY.y, pb.mul(this.momentXY.x, this.momentXY.x)));
919
868
  this.moment = pb.vec4(this.momentXY, this.historyLength, this.variance);
920
869
  } else {
921
- // The WebGL1 fallback has no motion-vector temporal resolve. Seed
922
- // a-trous with spatial variance so its luminance weighting can
923
- // still remove Monte Carlo noise instead of treating it as an edge.
870
+ // No temporal history: seed a-trous with spatial variance.
924
871
  this.$l.spatialLum = pb.float(0);
925
872
  this.$l.spatialLum2 = pb.float(0);
926
873
  for(let y = -1; y <= 1; y++){
@@ -982,17 +929,9 @@ const MOMENT_LUMINANCE_MAX = 255;
982
929
  this.$l.centerNormal = pb.normalize(pb.sub(pb.mul(pb.textureSampleLevel(this.normalTex, this.uv, 0).rgb, 2), pb.vec3(1)));
983
930
  this.$l.centerLum = this.SSGI_luminance(this.center.rgb);
984
931
  this.$l.moments = pb.textureSampleLevel(this.momentsTex, this.uv, 0);
985
- // A pixel with little accumulated history has an unreliable variance
986
- // estimate, so the edge-stopping functions would preserve Monte Carlo
987
- // noise as if it were detail. Widen the kernel and relax the luminance
988
- // and normal tests until enough frames have converged, then hand back
989
- // to the sharp weights (standard SVGF history-driven ramp).
990
- //
991
- // A path that never accumulates history (no temporal resolve, so
992
- // moments.z is pinned at 1) is permanently unconverged, not converged:
993
- // it is the noisiest input this filter ever sees. Sending it to the
994
- // relaxed end is the whole point of the ramp - the sharp end would give
995
- // it the narrowest kernel and one eighth the luminance tolerance.
932
+ // SVGF history-driven ramp: low-history pixels get a wider kernel and relaxed
933
+ // luminance/normal tests. Paths without history (moments.z pinned at 1) are
934
+ // treated as unconverged.
996
935
  this.$l.historyConfidence = this.$choice(pb.greaterThan(this.denoiseParams.x, 0), pb.clamp(pb.div(this.moments.z, this.denoiseParams.x), 0, 1), pb.float(0));
997
936
  this.$l.stepScale = pb.mix(pb.float(2), pb.float(1), this.historyConfidence);
998
937
  this.$l.effStep = pb.mul(this.filterParams.x, this.stepScale);
@@ -1022,11 +961,8 @@ const MOMENT_LUMINANCE_MAX = 255;
1022
961
  this.$l.weight = pb.mul(kernelWeight, this.depthWeight, this.normalWeight, this.colorWeight, this.sampleValue.a);
1023
962
  this.sum = pb.add(this.sum, pb.mul(this.sampleValue.rgb, this.weight));
1024
963
  this.weightSum = pb.add(this.weightSum, this.weight);
1025
- // AO deliberately drops colorWeight: that term is driven by the
1026
- // moments' luminance variance, which describes the irradiance and
1027
- // says nothing about AO. Leaving it out is a stronger smoothing,
1028
- // which is what a per-ray binary quantity needs - with 1-2 rays per
1029
- // pixel, single-frame AO is close to binary.
964
+ // AO drops colorWeight (driven by irradiance variance) for stronger smoothing;
965
+ // with 1-2 rays per pixel single-frame AO is nearly binary.
1030
966
  this.$l.aoWeight = pb.mul(kernelWeight, this.depthWeight, this.normalWeight, this.sampleValue.a);
1031
967
  this.$l.sampleAO = pb.textureSampleLevel(this.aoSourceTex, this.sampleUV, 0).r;
1032
968
  this.aoSum = pb.add(this.aoSum, pb.mul(this.sampleAO, this.aoWeight));
@@ -1075,10 +1011,8 @@ const MOMENT_LUMINANCE_MAX = 255;
1075
1011
  return program;
1076
1012
  }
1077
1013
  /**
1078
- * Multiply the traced ambient occlusion into the scene color.
1079
- *
1080
- * This is the same multiply-into-final-color semantics the standalone SAO post
1081
- * effect applies, so enabling both double darkens.
1014
+ * Multiplies the traced ambient occlusion into the scene color, like the SAO
1015
+ * effect, so enabling both double darkens.
1082
1016
  *
1083
1017
  * @internal
1084
1018
  */ compositeAO(ctx, sceneColor, ao, srgbOutput) {
@@ -1093,9 +1027,7 @@ const MOMENT_LUMINANCE_MAX = 255;
1093
1027
  if (!bindGroup) {
1094
1028
  bindGroup = ctx.device.createBindGroup(program.bindGroupLayouts[0]);
1095
1029
  bindGroup.setTexture('colorTex', sceneColor, fetchSampler('clamp_nearest_nomip'));
1096
- // Nearest, not linear: the AO handed to this pass is already at full
1097
- // resolution, so filtering would only add a dependency on the WebGL
1098
- // half-float linear filtering cap for no gain.
1030
+ // Nearest: AO is already full resolution.
1099
1031
  bindGroup.setTexture('aoTex', ao, fetchSampler('clamp_nearest_nomip'));
1100
1032
  this._compositeBindGroups[hash] = bindGroup;
1101
1033
  }
@@ -1127,9 +1059,7 @@ const MOMENT_LUMINANCE_MAX = 255;
1127
1059
  pb.main(function() {
1128
1060
  this.$l.color = pb.textureSampleLevel(this.colorTex, this.$inputs.uv, 0);
1129
1061
  this.$l.ao = pb.clamp(pb.textureSampleLevel(this.aoTex, this.$inputs.uv, 0).r, 0, 1);
1130
- // mix() toward 1 rather than a plain multiply: intensity then doubles as
1131
- // the fallback for noisy or unresolved texels, which matters most on the
1132
- // WebGL1 path where there is no temporal accumulation to converge them.
1062
+ // mix() toward 1: intensity also tempers noisy or unresolved texels.
1133
1063
  this.$l.shapedAO = pb.pow(this.ao, this.aoParams.y);
1134
1064
  this.$l.finalAO = pb.mix(pb.float(1), this.shapedAO, this.aoParams.x);
1135
1065
  this.$l.occludedColor = pb.mul(this.color.rgb, this.finalAO);
@@ -1182,8 +1112,7 @@ const MOMENT_LUMINANCE_MAX = 255;
1182
1112
  this.$l.weight = pb.mul(this.depthWeight, this.normalWeight, this.sampleValue.a);
1183
1113
  this.sum = pb.add(this.sum, pb.mul(this.sampleValue.rgb, this.weight));
1184
1114
  this.weightSum = pb.add(this.weightSum, this.weight);
1185
- // Same joint bilateral weights as the irradiance, so the upsampled
1186
- // AO cannot cross a depth or normal edge the irradiance respects.
1115
+ // Same joint bilateral weights as the irradiance.
1187
1116
  this.aoSum = pb.add(this.aoSum, pb.mul(this.sampleAO, this.weight));
1188
1117
  }
1189
1118
  }