@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
@@ -1,8 +1,10 @@
1
- import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_POINT, LIGHT_TYPE_RECT } from '../../values.js';
1
+ import { REVERSE_Z } from '@zephyr3d/base';
2
+ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_POINT, LIGHT_TYPE_RECT, MAX_GLOBAL_LIGHTS } from '../../values.js';
2
3
  import { applyMaterialMixins } from '../meshmaterial.js';
3
4
  import { mixinTextureProps } from './texture.js';
4
5
  import { mixinAlbedoColor } from './albedocolor.js';
5
6
  import { ShaderHelper } from '../shader/helper.js';
7
+ import { defineLTCEdgeFunctions } from '../../shaders/ltc_rect.js';
6
8
 
7
9
  /**
8
10
  * Light mixin
@@ -332,7 +334,8 @@ import { ShaderHelper } from '../shader/helper.js';
332
334
  console.warn('getEnvLightIrradiance(): No need to calculate environment lighting');
333
335
  return scope.$builder.vec3(0);
334
336
  }
335
- return this.drawContext.env.light.envLight.hasIrradiance() ? this.drawContext.SSGI && this.drawContext.SSGIIrradianceHistoryTexture && this.drawContext.SSGISurfaceHistoryTexture && (this.drawContext.device.type === 'webgl' || this.drawContext.motionVectorTexture) ? this.drawContext.env.light.envLight.getIrradiance(scope, normal, this.drawContext).rgb : scope.$builder.mul(this.drawContext.env.light.envLight.getIrradiance(scope, normal, this.drawContext).rgb, ShaderHelper.getEnvLightStrength(scope)) : scope.$builder.vec3(0);
337
+ // Already scaled by the environment strength; see EnvironmentLighting.getIrradiance
338
+ return this.drawContext.env.light.envLight.hasIrradiance() ? this.drawContext.env.light.envLight.getIrradiance(scope, normal, this.drawContext).rgb : scope.$builder.vec3(0);
336
339
  }
337
340
  /**
338
341
  * Get Radiance of current environment light
@@ -375,6 +378,29 @@ import { ShaderHelper } from '../shader/helper.js';
375
378
  }
376
379
  return ShaderHelper.calculateShadow(scope, worldPos, worldNormal, NoL, this.drawContext);
377
380
  }
381
+ /**
382
+ * Whether this material's fragments are lit through water and so pick up the
383
+ * water caustics.
384
+ *
385
+ * True for ordinary surfaces, which may sit under a water body. A water
386
+ * surface itself must override this to false: the caustic lookup decides
387
+ * whether a fragment is submerged by comparing its own height against the
388
+ * displaced surface height on its *sun ray*, and those are two different
389
+ * points on the water unless the sun is exactly overhead. Under a tilted sun
390
+ * every water fragment has some other part of the surface upstream of it, so
391
+ * a fragment in a trough is read as being under the crest up-sun of it and
392
+ * gets the caustic pattern - whose peaks are well above 1 - painted onto the
393
+ * water as bright blotches that swim with the waves.
394
+ *
395
+ * Only the sampling is gated, not the uniform declarations: the caustic
396
+ * uniforms live in the pass-wide global bind group, whose layout is built
397
+ * once per {@link DrawContext.renderPassHash} and shared by every material
398
+ * drawn in that pass, so it cannot vary per material.
399
+ *
400
+ * @returns True when the water caustics modulate this material's lighting.
401
+ */ receivesWaterCaustics() {
402
+ return true;
403
+ }
378
404
  getClusterIndex(scope, fragCoord) {
379
405
  const pb = scope.$builder;
380
406
  const funcName = 'lm_getClusterIndex';
@@ -383,9 +409,24 @@ import { ShaderHelper } from '../shader/helper.js';
383
409
  ], function() {
384
410
  const clusterParams = ShaderHelper.getClusterParams(this);
385
411
  const countParams = ShaderHelper.getCountParams(this);
386
- this.$l.zTile = pb.int(pb.max(pb.add(pb.mul(pb.log2(ShaderHelper.nonLinearDepthToLinear(this, this.fragCoord.z)), clusterParams.z), clusterParams.w), 0));
387
- this.$l.f = pb.vec2(this.fragCoord.x, pb.sub(clusterParams.y, pb.add(this.fragCoord.y, 1)));
388
- this.$l.xyTile = pb.ivec2(pb.div(this.f, pb.div(clusterParams.xy, pb.vec2(countParams.xy))));
412
+ // Slice = t * scale + bias, with t = log2(view depth) for perspective (exponential
413
+ // slices) and the view depth itself for orthographic (linear slices), matching the
414
+ // index pass. Orthographic device depth is linear between near and far.
415
+ this.$l.sliceDepth = pb.float();
416
+ this.$if(pb.notEqual(ShaderHelper.getClusterOrthographic(this), 0), function() {
417
+ const nearFar = ShaderHelper.getCameraParams(this);
418
+ this.sliceDepth = REVERSE_Z ? pb.mix(nearFar.y, nearFar.x, this.fragCoord.z) : pb.mix(nearFar.x, nearFar.y, this.fragCoord.z);
419
+ }).$else(function() {
420
+ this.sliceDepth = pb.log2(ShaderHelper.nonLinearDepthToLinear(this, this.fragCoord.z));
421
+ });
422
+ // Depth at (or jittered past) the far plane would land in slice countParams.z, one past
423
+ // the last row of the index texture, so clamp both ends. Clamped as float before the int
424
+ // conversion because GLSL ES 1.0 has no integer clamp.
425
+ this.$l.zTile = pb.int(pb.clamp(pb.add(pb.mul(this.sliceDepth, clusterParams.z), clusterParams.w), 0, pb.sub(pb.float(countParams.z), 1)));
426
+ // fragCoord holds pixel centers (n + 0.5); flipping to the top-down tile space of the
427
+ // index pass is H - fragCoord.y, with no extra -1 that would shift tile rows by a pixel.
428
+ this.$l.f = pb.vec2(this.fragCoord.x, pb.sub(clusterParams.y, this.fragCoord.y));
429
+ this.$l.xyTile = pb.ivec2(pb.clamp(pb.div(this.f, pb.div(clusterParams.xy, pb.vec2(countParams.xy))), pb.vec2(0), pb.sub(pb.vec2(countParams.xy), pb.vec2(1))));
389
430
  this.$return(pb.ivec3(this.xyTile, this.zTile));
390
431
  });
391
432
  return pb.getGlobalScope()[funcName](fragCoord);
@@ -409,9 +450,10 @@ import { ShaderHelper } from '../shader/helper.js';
409
450
  }
410
451
  calculateSpotLightAttenuation(scope, worldPos, posRange, dirCutoff, angleScaleOffset) {
411
452
  const pb = scope.$builder;
453
+ const that = this;
412
454
  const physical = this.drawContext.scene.lightingMode === 'physical';
413
- // The two modes emit different falloff and cone-attenuation bodies, so they must not share a
414
- // cached function under one name.
455
+ // The two modes emit different cone-attenuation bodies, so they must not share a cached
456
+ // function under one name.
415
457
  const funcName = physical ? 'Z_calculateSpotLightAttenuationPhysical' : 'Z_calculateSpotLightAttenuation';
416
458
  pb.func(funcName, [
417
459
  pb.vec3('worldPos'),
@@ -419,18 +461,9 @@ import { ShaderHelper } from '../shader/helper.js';
419
461
  pb.vec4('dirCutoff'),
420
462
  pb.vec2('angleScaleOffset')
421
463
  ], function() {
422
- this.$l.dist = pb.distance(this.posRange.xyz, this.worldPos);
423
- if (physical) {
424
- this.$l.dist2 = pb.mul(this.dist, this.dist);
425
- this.$l.lightAtten = pb.div(1, pb.max(this.dist2, 0.0001));
426
- this.$l.range2 = pb.mul(this.posRange.w, this.posRange.w);
427
- this.$l.f = pb.div(this.dist2, pb.max(this.range2, 0.0001));
428
- this.$l.f2 = pb.clamp(pb.sub(1, pb.mul(this.f, this.f)), 0, 1);
429
- this.$l.falloff = pb.mul(this.lightAtten, this.f2, this.f2);
430
- } else {
431
- this.$l.falloff = pb.max(0, pb.sub(1, pb.div(this.dist, this.posRange.w)));
432
- this.falloff = pb.mul(this.falloff, this.falloff);
433
- }
464
+ // The point light's distance falloff in both modes: inverse square with the windowing
465
+ // to the range, so a spot and a point light of one intensity light a surface alike
466
+ this.$l.falloff = that.calculatePointLightAttenuation(this, this.worldPos, this.posRange);
434
467
  this.$l.cd = pb.dot(pb.normalize(pb.sub(this.worldPos, this.posRange.xyz)), this.dirCutoff.xyz);
435
468
  if (physical) {
436
469
  // Filament's getAngleAttenuation: saturate(cd * scale + offset) squared. The scale/offset
@@ -445,15 +478,116 @@ import { ShaderHelper } from '../shader/helper.js';
445
478
  const resolvedScaleOffset = physical && angleScaleOffset ? angleScaleOffset : pb.vec2(0);
446
479
  return pb.getGlobalScope()[funcName](worldPos, posRange, dirCutoff, resolvedScaleOffset);
447
480
  }
481
+ /**
482
+ * A rect light reduced to one direction and one magnitude, for BxDFs that
483
+ * have no area-light integration of their own.
484
+ *
485
+ * @internal
486
+ */ calculateRectLightVectorIrradiance(scope, worldPos, posRange, axisX, axisY) {
487
+ const pb = scope.$builder;
488
+ defineLTCEdgeFunctions(scope);
489
+ pb.func('Z_rectLightVectorIrradiance', [
490
+ pb.vec3('worldPos'),
491
+ pb.vec4('posRange'),
492
+ pb.vec3('ax'),
493
+ pb.vec3('ay')
494
+ ], function() {
495
+ this.$l.toCenter = pb.sub(this.posRange.xyz, this.worldPos);
496
+ this.$l.dist = pb.length(this.toCenter);
497
+ this.$l.centerDir = pb.div(this.toCenter, pb.max(this.dist, 1e-6));
498
+ this.$l.planeNormal = pb.cross(this.ax, this.ay);
499
+ // The rect emits along -(ax x ay), so a lit point lies on that side of
500
+ // it, where the vector back to the centre points along +(ax x ay).
501
+ this.$if(pb.or(pb.lessThan(pb.dot(this.planeNormal, this.planeNormal), 1e-12), pb.lessThanEqual(pb.dot(this.planeNormal, this.toCenter), 0)), function() {
502
+ this.$return(pb.vec4(this.centerDir, 0));
503
+ });
504
+ this.$l.v0 = pb.normalize(pb.sub(pb.sub(this.toCenter, this.ax), this.ay));
505
+ this.$l.v1 = pb.normalize(pb.sub(pb.add(this.toCenter, this.ax), this.ay));
506
+ this.$l.v2 = pb.normalize(pb.add(pb.add(this.toCenter, this.ax), this.ay));
507
+ this.$l.v3 = pb.normalize(pb.add(pb.sub(this.toCenter, this.ax), this.ay));
508
+ this.$l.F = pb.add(this.Z_LTCIntegrateEdgeVec(this.v0, this.v1), this.Z_LTCIntegrateEdgeVec(this.v1, this.v2), this.Z_LTCIntegrateEdgeVec(this.v2, this.v3), this.Z_LTCIntegrateEdgeVec(this.v3, this.v0));
509
+ this.$l.len = pb.length(this.F);
510
+ this.$if(pb.lessThan(this.len, 1e-8), function() {
511
+ this.$return(pb.vec4(this.centerDir, 0));
512
+ });
513
+ this.$l.falloff = pb.float(1);
514
+ this.$if(pb.greaterThan(this.posRange.w, 0), function() {
515
+ this.falloff = pb.sub(1, pb.smoothStep(pb.mul(this.posRange.w, 0.9), this.posRange.w, this.dist));
516
+ });
517
+ this.$return(pb.vec4(pb.div(this.F, this.len), pb.mul(this.len, this.falloff)));
518
+ });
519
+ return pb.getGlobalScope().Z_rectLightVectorIrradiance(worldPos, posRange, axisX, axisY);
520
+ }
448
521
  calculateLightAttenuation(scope, type, worldPos, posRange, dirCutoff, extra) {
449
522
  const pb = scope.$builder;
450
- return scope.$choice(pb.equal(type, LIGHT_TYPE_DIRECTIONAL), pb.float(1), scope.$choice(pb.equal(type, LIGHT_TYPE_POINT), this.calculatePointLightAttenuation(scope, worldPos.xyz, posRange), scope.$choice(pb.equal(type, LIGHT_TYPE_RECT), this.calculatePointLightAttenuation(scope, worldPos.xyz, posRange), this.calculateSpotLightAttenuation(scope, worldPos.xyz, posRange, dirCutoff, extra?.xy))));
523
+ const that = this;
524
+ const physical = this.drawContext.scene.lightingMode === 'physical';
525
+ // Branches rather than a $choice, which would evaluate every light type's
526
+ // attenuation - the rect's vector form factor included - for every light.
527
+ // Named per mode because the spot light body it calls differs by mode.
528
+ const funcName = physical ? 'Z_calculateLightAttenuationPhysical' : 'Z_calculateLightAttenuation';
529
+ pb.func(funcName, [
530
+ pb.int('lightType'),
531
+ pb.vec3('worldPos'),
532
+ pb.vec4('posRange'),
533
+ pb.vec4('dirCutoff'),
534
+ pb.vec4('extra')
535
+ ], function() {
536
+ this.$if(pb.equal(this.lightType, LIGHT_TYPE_DIRECTIONAL), function() {
537
+ this.$return(pb.float(1));
538
+ });
539
+ this.$if(pb.equal(this.lightType, LIGHT_TYPE_POINT), function() {
540
+ this.$return(that.calculatePointLightAttenuation(this, this.worldPos, this.posRange));
541
+ });
542
+ this.$if(pb.equal(this.lightType, LIGHT_TYPE_RECT), function() {
543
+ // extra.xyz carries the rect's half-height axis; see RectLight.computeUniforms.
544
+ this.$return(pb.mul(that.calculateRectLightVectorIrradiance(this, this.worldPos, this.posRange, this.dirCutoff.xyz, this.extra.xyz).w, Math.PI));
545
+ });
546
+ this.$return(that.calculateSpotLightAttenuation(this, this.worldPos, this.posRange, this.dirCutoff, this.extra.xy));
547
+ });
548
+ const attenuation = pb.getGlobalScope()[funcName](type, worldPos.xyz, posRange, dirCutoff, extra ?? pb.vec4(0));
549
+ // Water caustics ride here rather than on calculateShadow(): every light
550
+ // model already folds this value into its light colour and nothing else
551
+ // reads it, so a vec3 return applies the caustic tint everywhere without
552
+ // touching a single call site. It also covers both lighting paths, which
553
+ // matters because a shadow-casting sun goes through the clustered path
554
+ // when the screen-space shadow mask is on and through a per-light additive
555
+ // pass when it is off.
556
+ const caustic = this.receivesWaterCaustics() ? ShaderHelper.calculateWaterCaustic(scope, worldPos.xyz, type, dirCutoff.xyz, this.drawContext) : null;
557
+ return caustic ? pb.mul(caustic, attenuation) : attenuation;
451
558
  }
452
- calculateLightDirection(scope, type, worldPos, posRange, dirCutoff) {
559
+ /**
560
+ * Unit vector from `worldPos` towards the light.
561
+ *
562
+ * @remarks
563
+ * For a rect light this is the direction of its vector form factor (see
564
+ * {@link calculateRectLightVectorIrradiance}), which needs the rect's second
565
+ * axis from `extra`. Without `extra` a rect light falls back to the direction
566
+ * of its centre.
567
+ */ calculateLightDirection(scope, type, worldPos, posRange, dirCutoff, extra) {
453
568
  const pb = scope.$builder;
454
- return scope.$choice(pb.equal(type, LIGHT_TYPE_DIRECTIONAL), pb.neg(dirCutoff.xyz), pb.normalize(pb.sub(posRange.xyz, worldPos.xyz)));
569
+ if (!extra) {
570
+ return scope.$choice(pb.equal(type, LIGHT_TYPE_DIRECTIONAL), pb.neg(dirCutoff.xyz), pb.normalize(pb.sub(posRange.xyz, worldPos.xyz)));
571
+ }
572
+ const that = this;
573
+ pb.func('Z_calculateLightDirection', [
574
+ pb.int('lightType'),
575
+ pb.vec3('worldPos'),
576
+ pb.vec4('posRange'),
577
+ pb.vec4('dirCutoff'),
578
+ pb.vec4('extra')
579
+ ], function() {
580
+ this.$if(pb.equal(this.lightType, LIGHT_TYPE_DIRECTIONAL), function() {
581
+ this.$return(pb.neg(this.dirCutoff.xyz));
582
+ });
583
+ this.$if(pb.equal(this.lightType, LIGHT_TYPE_RECT), function() {
584
+ this.$return(that.calculateRectLightVectorIrradiance(this, this.worldPos, this.posRange, this.dirCutoff.xyz, this.extra.xyz).xyz);
585
+ });
586
+ this.$return(pb.normalize(pb.sub(this.posRange.xyz, this.worldPos)));
587
+ });
588
+ return pb.getGlobalScope().Z_calculateLightDirection(type, worldPos.xyz, posRange, dirCutoff, extra);
455
589
  }
456
- forEachLight(scope, callback) {
590
+ /** Invokes `callback` once per light affecting the fragment. */ forEachLight(scope, callback) {
457
591
  const pb = scope.$builder;
458
592
  const that = this;
459
593
  if (that.drawContext.renderPass.type !== RENDER_PASS_TYPE_LIGHT) {
@@ -467,75 +601,81 @@ import { ShaderHelper } from '../shader/helper.js';
467
601
  const extra = scope.light.extraParams ?? pb.vec4(0);
468
602
  scope.$scope(function() {
469
603
  const lightType = pb.int(extra.w);
470
- callback.call(this, lightType, posRange, dirCutoff, colorIntensity, extra, true);
604
+ // The per-light additive path has no thickness texture: it is produced
605
+ // for the clustered queue only. 1 is the "no data" sentinel the
606
+ // thickness pass can never write, so consumers read this as "this
607
+ // light contributes no transmission" rather than as zero thickness —
608
+ // which would be the *most* transmissive reading of the encoding.
609
+ callback.call(this, lightType, posRange, dirCutoff, colorIntensity, extra, true, pb.float(1), colorIntensity);
471
610
  });
472
611
  } else {
612
+ // Emits the shading of the light at buffer index `index` (an int or uint).
613
+ const shadeLight = function(index) {
614
+ this.$l.positionRange = ShaderHelper.getLightPositionAndRange(this, index);
615
+ this.$l.directionCutoff = ShaderHelper.getLightDirectionAndCutoff(this, index);
616
+ this.$l.diffuseIntensity = ShaderHelper.getLightColorAndIntensity(this, index);
617
+ this.$l.extra = ShaderHelper.getLightExtra(this, index);
618
+ this.$l.unshadowedIntensity = this.diffuseIntensity;
619
+ if (that.drawContext.screenSpaceShadowMask) {
620
+ // Shadow-casting lights (buffer index <= numShadowLights) attenuate
621
+ // by the pre-rendered screen-space shadow mask; others return 1.0.
622
+ this.$l.shadowMask = ShaderHelper.sampleShadowMask(this, pb.int(index));
623
+ this.diffuseIntensity = pb.vec4(pb.mul(this.diffuseIntensity.rgb, this.shadowMask), this.diffuseIntensity.w);
624
+ }
625
+ this.$l.thickness = pb.float(1);
626
+ if (that.drawContext.transmissionThickness) {
627
+ this.thickness = ShaderHelper.sampleTransmissionThickness(this, pb.int(index));
628
+ }
629
+ this.$l.lightType = pb.int(this.extra.w);
630
+ this.$scope(function() {
631
+ callback.call(this, this.lightType, this.positionRange, this.directionCutoff, this.diffuseIntensity, this.extra, false, this.thickness, this.unshadowedIntensity);
632
+ });
633
+ };
473
634
  scope.$scope(function() {
635
+ // Lights that reach every fragment (directional) are kept out of the clusters.
636
+ const globalLights = ShaderHelper.getGlobalLights(this);
637
+ this.$for(pb.int('g'), 0, MAX_GLOBAL_LIGHTS, function() {
638
+ this.$l.gi = globalLights.at(this.g);
639
+ this.$if(pb.equal(this.gi, 0), function() {
640
+ this.$break();
641
+ });
642
+ this.$scope(function() {
643
+ shadeLight.call(this, this.gi);
644
+ });
645
+ });
474
646
  const countParams = ShaderHelper.getCountParams(this);
475
647
  this.$l.cluster = that.getClusterIndex(this, this.$builtins.fragCoord.xyz);
476
648
  this.$l.clusterIndex = pb.add(this.cluster.x, pb.mul(this.cluster.y, countParams.x), pb.mul(this.cluster.z, countParams.x, countParams.y));
477
- this.$l.texSize = scope.light.lightIndexTexSize;
478
- if (pb.getDevice().type === 'webgl') {
479
- this.$l.texCoordX = pb.div(pb.add(pb.mod(pb.float(this.clusterIndex), pb.float(this.texSize.x)), 0.5), pb.float(this.texSize.x));
480
- this.$l.texCoordY = pb.div(pb.add(pb.float(pb.div(this.clusterIndex, this.texSize.x)), 0.5), pb.float(this.texSize.y));
481
- this.$l.samp = pb.textureSample(ShaderHelper.getClusteredLightIndexTexture(this), pb.vec2(this.texCoordX, this.texCoordY));
482
- } else {
483
- this.$l.texCoordX = pb.mod(this.clusterIndex, this.texSize.x);
484
- this.$l.texCoordY = pb.div(this.clusterIndex, this.texSize.x);
485
- this.$l.samp = pb.textureLoad(ShaderHelper.getClusteredLightIndexTexture(this), pb.ivec2(this.texCoordX, this.texCoordY), 0);
486
- }
487
- if (pb.getDevice().type === 'webgl') {
488
- this.$for(pb.int('i'), 0, 4, function() {
489
- this.$l.k = this.samp.at(this.i);
490
- this.$l.lights = pb.int[2]();
491
- this.$l.lights[0] = pb.int(pb.mod(this.k, 256));
492
- this.$l.lights[1] = pb.int(pb.div(this.k, 256));
493
- this.$for(pb.int('k'), 0, 2, function() {
494
- this.$l.li = this.lights.at(this.k);
495
- this.$if(pb.greaterThan(this.li, 0), function() {
496
- this.$for(pb.int('j'), 1, 256, function() {
497
- this.$if(pb.equal(this.j, this.li), function() {
498
- this.$l.positionRange = ShaderHelper.getLightPositionAndRange(this, this.j);
499
- this.$l.directionCutoff = ShaderHelper.getLightDirectionAndCutoff(this, this.j);
500
- this.$l.diffuseIntensity = ShaderHelper.getLightColorAndIntensity(this, this.j);
501
- this.$l.extra = ShaderHelper.getLightExtra(this, this.j);
502
- if (that.drawContext.screenSpaceShadowMask) {
503
- this.$l.shadowMask = ShaderHelper.sampleShadowMask(this, this.j);
504
- this.diffuseIntensity = pb.vec4(pb.mul(this.diffuseIntensity.rgb, this.shadowMask), this.diffuseIntensity.w);
505
- }
506
- this.$l.lightType = pb.int(this.extra.w);
507
- this.$scope(function() {
508
- callback.call(this, this.lightType, this.positionRange, this.directionCutoff, this.diffuseIntensity, this.extra, false);
509
- });
510
- this.$break();
511
- });
512
- });
513
- });
514
- });
515
- });
516
- } else {
517
- this.$for(pb.uint('i'), 0, 4, function() {
518
- this.$for(pb.uint('k'), 0, 4, function() {
519
- this.$l.c = pb.compAnd(pb.sar(this.samp.at(this.i), pb.mul(this.k, 8)), 0xff);
520
- this.$if(pb.greaterThan(this.c, 0), function() {
521
- this.$l.positionRange = ShaderHelper.getLightPositionAndRange(this, this.c);
522
- this.$l.directionCutoff = ShaderHelper.getLightDirectionAndCutoff(this, this.c);
523
- this.$l.diffuseIntensity = ShaderHelper.getLightColorAndIntensity(this, this.c);
524
- this.$l.extra = ShaderHelper.getLightExtra(this, this.c);
525
- if (that.drawContext.screenSpaceShadowMask) {
526
- // Shadow-casting lights (buffer index <= numShadowLights) attenuate
527
- // by the pre-rendered screen-space shadow mask; others return 1.0.
528
- this.$l.shadowMask = ShaderHelper.sampleShadowMask(this, pb.int(this.c));
529
- this.diffuseIntensity = pb.vec4(pb.mul(this.diffuseIntensity.rgb, this.shadowMask), this.diffuseIntensity.w);
530
- }
531
- this.$l.lightType = pb.int(this.extra.w);
532
- this.$scope(function() {
533
- callback.call(this, this.lightType, this.positionRange, this.directionCutoff, this.diffuseIntensity, this.extra, false);
534
- });
535
- });
649
+ if (ShaderHelper.usesClusterLightLists()) {
650
+ // The cluster's lights are list[offset .. offset + count), however many.
651
+ const grid = ShaderHelper.getClusterGrid(this);
652
+ const list = ShaderHelper.getClusterLightList(this);
653
+ this.$l.cell = pb.mul(pb.uint(this.clusterIndex), 2);
654
+ this.$l.listOffset = grid.at(this.cell);
655
+ this.$l.listCount = grid.at(pb.add(this.cell, 1));
656
+ this.$for(pb.uint('n'), 0, this.listCount, function() {
657
+ this.$l.c = list.at(pb.add(this.listOffset, this.n));
658
+ this.$scope(function() {
659
+ shadeLight.call(this, this.c);
536
660
  });
537
661
  });
662
+ return;
538
663
  }
664
+ this.$l.texSize = scope.light.lightIndexTexSize;
665
+ this.$l.texCoordX = pb.mod(this.clusterIndex, this.texSize.x);
666
+ this.$l.texCoordY = pb.div(this.clusterIndex, this.texSize.x);
667
+ this.$l.samp = pb.textureLoad(ShaderHelper.getClusteredLightIndexTexture(this), pb.ivec2(this.texCoordX, this.texCoordY), 0);
668
+ // Slots are packed front to back (slot 0 in the top byte of .r) with a zero tail, so
669
+ // walk them in that order and stop at the first empty one.
670
+ this.$for(pb.uint('n'), 0, 16, function() {
671
+ this.$l.c = pb.compAnd(pb.sar(this.samp.at(pb.div(this.n, 4)), pb.sub(24, pb.mul(pb.compAnd(this.n, 3), 8))), 0xff);
672
+ this.$if(pb.equal(this.c, 0), function() {
673
+ this.$break();
674
+ });
675
+ this.$scope(function() {
676
+ shadeLight.call(this, this.c);
677
+ });
678
+ });
539
679
  });
540
680
  }
541
681
  }