@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 +1 @@
1
- {"version":3,"file":"shadow_region.js","sources":["../../src/shadow/shadow_region.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\nimport { AABB, Disposable, DWeakRef } from '@zephyr3d/base';\nimport type { SceneNode } from '../scene/scene_node';\n\ntype StaticShadowCasterEntry = {\n ref: DWeakRef<SceneNode>;\n aabb: AABB;\n};\n\ntype DynamicShadowCasterEntry = {\n ref: DWeakRef<SceneNode>;\n callback: (node: SceneNode) => void;\n};\n\n/**\n * Maintains the world-space region used by directional light shadow maps.\n *\n * @public\n */\nexport class ShadowRegion extends Disposable {\n /** @internal */\n private _manualRegion: Nullable<AABB>;\n /** @internal */\n private readonly _staticRegion: AABB;\n /** @internal */\n private readonly _dynamicRegion: AABB;\n /** @internal */\n private readonly _region: AABB;\n /** @internal */\n private readonly _staticCasters: StaticShadowCasterEntry[];\n /** @internal */\n private readonly _dynamicCasters: DynamicShadowCasterEntry[];\n\n /**\n * Creates a shadow region.\n *\n * @param region - Optional manual world-space AABB used to initialize the region.\n */\n constructor(region?: Nullable<AABB>) {\n super();\n this._manualRegion = region ? new AABB(region) : null;\n this._staticRegion = new AABB().beginExtend();\n this._dynamicRegion = new AABB().beginExtend();\n this._region = new AABB().beginExtend();\n this._staticCasters = [];\n this._dynamicCasters = [];\n this.updateRegion();\n }\n\n /**\n * Final world-space shadow region.\n *\n * @returns The union of the manual, static caster, and dynamic caster regions, or `null` if no valid region exists.\n */\n get region(): Nullable<AABB> {\n return this._region.isValid() ? this._region : null;\n }\n\n /**\n * Region contributed by manually assigned AABB.\n *\n * @returns The manually assigned region, or `null` if no manual region is set.\n */\n get manualRegion(): Nullable<AABB> {\n return this._manualRegion;\n }\n\n /**\n * Region contributed by static shadow casters.\n *\n * @returns The combined static caster region, or `null` if no valid static caster region exists.\n */\n get staticRegion(): Nullable<AABB> {\n return this._staticRegion.isValid() ? this._staticRegion : null;\n }\n\n /**\n * Region contributed by dynamic shadow casters.\n *\n * @returns The combined dynamic caster region, or `null` if no valid dynamic caster region exists.\n */\n get dynamicRegion(): Nullable<AABB> {\n return this._dynamicRegion.isValid() ? this._dynamicRegion : null;\n }\n\n /**\n * Assigns a manual world-space AABB to the region.\n *\n * @param region - The manual world-space AABB to use, or `null` to clear the manual region.\n */\n setRegion(region: Nullable<AABB>) {\n this._manualRegion = region ? new AABB(region) : null;\n this.updateRegion();\n }\n\n /**\n * Adds a static shadow caster using a snapshot of its current world-space AABB.\n *\n * @param caster - The mesh or clipmap terrain node to include as a static caster.\n * @returns `this` for chaining.\n */\n addStaticCaster(caster: SceneNode): this {\n if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {\n return this;\n }\n const aabb = this.getCasterAABB(caster);\n if (!aabb) {\n return this;\n }\n this._staticCasters.push({\n ref: new DWeakRef(caster),\n aabb\n });\n this.extendRegion(this._staticRegion, aabb);\n this.updateRegion();\n return this;\n }\n\n /**\n * Adds a dynamic shadow caster and tracks its bounding volume changes.\n *\n * @param caster - The mesh or clipmap terrain node to include as a dynamic caster.\n * @returns `this` for chaining.\n */\n addDynamicCaster(caster: SceneNode): this {\n if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {\n return this;\n }\n const callback = () => {\n this.rebuildDynamicRegion();\n };\n caster.on('bvchanged', callback);\n this._dynamicCasters.push({\n ref: new DWeakRef(caster),\n callback\n });\n const aabb = this.getCasterAABB(caster);\n if (aabb) {\n this.extendRegion(this._dynamicRegion, aabb);\n this.updateRegion();\n }\n return this;\n }\n\n /**\n * Removes a previously added shadow caster.\n *\n * @param caster - The caster node to remove from the static or dynamic caster list.\n * @returns `this` for chaining.\n */\n removeCaster(caster: SceneNode): this {\n let removed = false;\n let changed = false;\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\n const entry = this._staticCasters[i];\n const node = entry.ref.get();\n if (!node || node === caster) {\n entry.ref.dispose();\n this._staticCasters.splice(i, 1);\n changed = true;\n removed ||= node === caster;\n }\n }\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\n const entry = this._dynamicCasters[i];\n const node = entry.ref.get();\n if (!node || node === caster) {\n (node ?? caster).off('bvchanged', entry.callback);\n entry.ref.dispose();\n this._dynamicCasters.splice(i, 1);\n changed = true;\n removed ||= node === caster;\n }\n }\n if (changed) {\n this.rebuildStaticRegion();\n this.rebuildDynamicRegion();\n }\n return this;\n }\n\n /**\n * Removes all shadow casters while keeping the manual region.\n */\n clearCasters() {\n for (const entry of this._dynamicCasters) {\n entry.ref.get()?.off('bvchanged', entry.callback);\n entry.ref.dispose();\n }\n for (const entry of this._staticCasters) {\n entry.ref.dispose();\n }\n this._staticCasters.length = 0;\n this._dynamicCasters.length = 0;\n this._staticRegion.beginExtend();\n this._dynamicRegion.beginExtend();\n this.updateRegion();\n }\n\n /**\n * Clears the manual region and all shadow casters.\n *\n * @returns `this` for chaining.\n */\n clear(): this {\n this._manualRegion = null;\n this.clearCasters();\n return this;\n }\n\n /** {@inheritDoc Disposable.onDispose} */\n protected onDispose(): void {\n this.clear();\n }\n\n /** @internal */\n private hasCaster(caster: SceneNode): boolean {\n return (\n this._staticCasters.some((entry) => entry.ref.get() === caster) ||\n this._dynamicCasters.some((entry) => entry.ref.get() === caster)\n );\n }\n\n /** @internal */\n private isShadowCaster(caster: SceneNode): boolean {\n return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain() || caster.isHair());\n }\n\n /** @internal */\n private getCasterAABB(caster: SceneNode): Nullable<AABB> {\n const bbox = caster.getWorldBoundingVolume()?.toAABB();\n return bbox?.isValid() ? new AABB(bbox) : null;\n }\n\n /** @internal */\n private rebuildStaticRegion() {\n this._staticRegion.beginExtend();\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\n const entry = this._staticCasters[i];\n if (!entry.ref.get()) {\n entry.ref.dispose();\n this._staticCasters.splice(i, 1);\n } else {\n this.extendRegion(this._staticRegion, entry.aabb);\n }\n }\n this.updateRegion();\n }\n\n /** @internal */\n private rebuildDynamicRegion() {\n this._dynamicRegion.beginExtend();\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\n const entry = this._dynamicCasters[i];\n const caster = entry.ref.get();\n if (!caster || !this.isShadowCaster(caster)) {\n caster?.off('bvchanged', entry.callback);\n entry.ref.dispose();\n this._dynamicCasters.splice(i, 1);\n continue;\n }\n const aabb = this.getCasterAABB(caster);\n if (aabb) {\n this.extendRegion(this._dynamicRegion, aabb);\n }\n }\n this.updateRegion();\n }\n\n /** @internal */\n private updateRegion() {\n this._region.beginExtend();\n if (this._manualRegion?.isValid()) {\n this.extendRegion(this._region, this._manualRegion);\n }\n if (this._staticRegion.isValid()) {\n this.extendRegion(this._region, this._staticRegion);\n }\n if (this._dynamicRegion.isValid()) {\n this.extendRegion(this._region, this._dynamicRegion);\n }\n }\n\n /** @internal */\n private extendRegion(region: AABB, aabb: AABB) {\n region.extend(aabb.minPoint);\n region.extend(aabb.maxPoint);\n }\n}\n"],"names":["ShadowRegion","Disposable","region","_manualRegion","AABB","_staticRegion","beginExtend","_dynamicRegion","_region","_staticCasters","_dynamicCasters","updateRegion","isValid","manualRegion","staticRegion","dynamicRegion","setRegion","addStaticCaster","caster","isShadowCaster","hasCaster","aabb","getCasterAABB","push","ref","DWeakRef","extendRegion","addDynamicCaster","callback","rebuildDynamicRegion","on","removeCaster","changed","i","length","entry","node","get","dispose","splice","off","rebuildStaticRegion","clearCasters","clear","some","disposed","isMesh","isClipmapTerrain","isHair","bbox","getWorldBoundingVolume","toAABB","extend","minPoint","maxPoint"],"mappings":"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"}
1
+ {"version":3,"file":"shadow_region.js","sources":["../../src/shadow/shadow_region.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { AABB, Disposable, DWeakRef } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../scene/scene_node';\r\n\r\ntype StaticShadowCasterEntry = {\r\n ref: DWeakRef<SceneNode>;\r\n aabb: AABB;\r\n};\r\n\r\ntype DynamicShadowCasterEntry = {\r\n ref: DWeakRef<SceneNode>;\r\n callback: (node: SceneNode) => void;\r\n};\r\n\r\n/**\r\n * Maintains the world-space region used by directional light shadow maps.\r\n *\r\n * @remarks\r\n * The region is the union of a manual AABB and the bounds of the static and dynamic\r\n * casters, clipped to the optional limit set with {@link ShadowRegion.setLimit}.\r\n * The limit keeps tracked casters that leave the play area, such as a falling\r\n * physics body, from stretching the shadow map over empty space.\r\n *\r\n * @public\r\n */\r\nexport class ShadowRegion extends Disposable {\r\n /** @internal */\r\n private _manualRegion: Nullable<AABB>;\r\n /** @internal */\r\n private _limit: Nullable<AABB>;\r\n /** @internal */\r\n private readonly _staticRegion: AABB;\r\n /** @internal */\r\n private readonly _dynamicRegion: AABB;\r\n /** @internal */\r\n private readonly _region: AABB;\r\n /** @internal */\r\n private readonly _staticCasters: StaticShadowCasterEntry[];\r\n /** @internal */\r\n private readonly _dynamicCasters: DynamicShadowCasterEntry[];\r\n\r\n /**\r\n * Creates a shadow region.\r\n *\r\n * @param region - Optional manual world-space AABB used to initialize the region.\r\n */\r\n constructor(region?: Nullable<AABB>) {\r\n super();\r\n this._manualRegion = region ? new AABB(region) : null;\r\n this._limit = null;\r\n this._staticRegion = new AABB().beginExtend();\r\n this._dynamicRegion = new AABB().beginExtend();\r\n this._region = new AABB().beginExtend();\r\n this._staticCasters = [];\r\n this._dynamicCasters = [];\r\n this.updateRegion();\r\n }\r\n\r\n /**\r\n * Final world-space shadow region.\r\n *\r\n * @returns The union of the manual, static caster, and dynamic caster regions clipped to\r\n * {@link ShadowRegion.limit}, or `null` if no valid region exists or the union lies\r\n * entirely outside the limit.\r\n */\r\n get region(): Nullable<AABB> {\r\n return this._region.isValid() ? this._region : null;\r\n }\r\n\r\n /**\r\n * Region contributed by manually assigned AABB.\r\n *\r\n * @returns The manually assigned region, or `null` if no manual region is set.\r\n */\r\n get manualRegion(): Nullable<AABB> {\r\n return this._manualRegion;\r\n }\r\n\r\n /**\r\n * World-space AABB the final region is clipped to.\r\n *\r\n * @returns The limit, or `null` if the region is not limited.\r\n */\r\n get limit(): Nullable<AABB> {\r\n return this._limit;\r\n }\r\n\r\n /**\r\n * Limits the final region to a world-space AABB.\r\n *\r\n * @param limit - The AABB to clip the region to, or `null` to remove the limit.\r\n * @returns `this` for chaining.\r\n */\r\n setLimit(limit: Nullable<AABB>): this {\r\n this._limit = limit?.isValid() ? new AABB(limit) : null;\r\n this.updateRegion();\r\n return this;\r\n }\r\n\r\n /**\r\n * Region contributed by static shadow casters.\r\n *\r\n * @returns The combined static caster region, or `null` if no valid static caster region exists.\r\n */\r\n get staticRegion(): Nullable<AABB> {\r\n return this._staticRegion.isValid() ? this._staticRegion : null;\r\n }\r\n\r\n /**\r\n * Region contributed by dynamic shadow casters.\r\n *\r\n * @returns The combined dynamic caster region, or `null` if no valid dynamic caster region exists.\r\n */\r\n get dynamicRegion(): Nullable<AABB> {\r\n return this._dynamicRegion.isValid() ? this._dynamicRegion : null;\r\n }\r\n\r\n /**\r\n * Assigns a manual world-space AABB to the region.\r\n *\r\n * @param region - The manual world-space AABB to use, or `null` to clear the manual region.\r\n */\r\n setRegion(region: Nullable<AABB>) {\r\n this._manualRegion = region ? new AABB(region) : null;\r\n this.updateRegion();\r\n }\r\n\r\n /**\r\n * Adds a static shadow caster using a snapshot of its current world-space AABB.\r\n *\r\n * @param caster - The mesh or clipmap terrain node to include as a static caster.\r\n * @returns `this` for chaining.\r\n */\r\n addStaticCaster(caster: SceneNode): this {\r\n if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {\r\n return this;\r\n }\r\n const aabb = this.getCasterAABB(caster);\r\n if (!aabb) {\r\n return this;\r\n }\r\n this._staticCasters.push({\r\n ref: new DWeakRef(caster),\r\n aabb\r\n });\r\n this.extendRegion(this._staticRegion, aabb);\r\n this.updateRegion();\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a dynamic shadow caster and tracks its bounding volume changes.\r\n *\r\n * @param caster - The mesh or clipmap terrain node to include as a dynamic caster.\r\n * @returns `this` for chaining.\r\n */\r\n addDynamicCaster(caster: SceneNode): this {\r\n if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {\r\n return this;\r\n }\r\n const callback = () => {\r\n this.rebuildDynamicRegion();\r\n };\r\n caster.on('bvchanged', callback);\r\n this._dynamicCasters.push({\r\n ref: new DWeakRef(caster),\r\n callback\r\n });\r\n const aabb = this.getCasterAABB(caster);\r\n if (aabb) {\r\n this.extendRegion(this._dynamicRegion, aabb);\r\n this.updateRegion();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes a previously added shadow caster.\r\n *\r\n * @param caster - The caster node to remove from the static or dynamic caster list.\r\n * @returns `this` for chaining.\r\n */\r\n removeCaster(caster: SceneNode): this {\r\n let removed = false;\r\n let changed = false;\r\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\r\n const entry = this._staticCasters[i];\r\n const node = entry.ref.get();\r\n if (!node || node === caster) {\r\n entry.ref.dispose();\r\n this._staticCasters.splice(i, 1);\r\n changed = true;\r\n removed ||= node === caster;\r\n }\r\n }\r\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\r\n const entry = this._dynamicCasters[i];\r\n const node = entry.ref.get();\r\n if (!node || node === caster) {\r\n (node ?? caster).off('bvchanged', entry.callback);\r\n entry.ref.dispose();\r\n this._dynamicCasters.splice(i, 1);\r\n changed = true;\r\n removed ||= node === caster;\r\n }\r\n }\r\n if (changed) {\r\n this.rebuildStaticRegion();\r\n this.rebuildDynamicRegion();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all shadow casters while keeping the manual region.\r\n */\r\n clearCasters() {\r\n for (const entry of this._dynamicCasters) {\r\n entry.ref.get()?.off('bvchanged', entry.callback);\r\n entry.ref.dispose();\r\n }\r\n for (const entry of this._staticCasters) {\r\n entry.ref.dispose();\r\n }\r\n this._staticCasters.length = 0;\r\n this._dynamicCasters.length = 0;\r\n this._staticRegion.beginExtend();\r\n this._dynamicRegion.beginExtend();\r\n this.updateRegion();\r\n }\r\n\r\n /**\r\n * Clears the manual region and all shadow casters. The limit is kept.\r\n *\r\n * @returns `this` for chaining.\r\n */\r\n clear(): this {\r\n this._manualRegion = null;\r\n this.clearCasters();\r\n return this;\r\n }\r\n\r\n /** {@inheritDoc Disposable.onDispose} */\r\n protected onDispose(): void {\r\n this.clear();\r\n }\r\n\r\n /** @internal */\r\n private hasCaster(caster: SceneNode): boolean {\r\n return (\r\n this._staticCasters.some((entry) => entry.ref.get() === caster) ||\r\n this._dynamicCasters.some((entry) => entry.ref.get() === caster)\r\n );\r\n }\r\n\r\n /** @internal */\r\n private isShadowCaster(caster: SceneNode): boolean {\r\n return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain() || caster.isHair());\r\n }\r\n\r\n /** @internal */\r\n private getCasterAABB(caster: SceneNode): Nullable<AABB> {\r\n const bbox = caster.getWorldBoundingVolume()?.toAABB();\r\n return bbox?.isValid() ? new AABB(bbox) : null;\r\n }\r\n\r\n /** @internal */\r\n private rebuildStaticRegion() {\r\n this._staticRegion.beginExtend();\r\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\r\n const entry = this._staticCasters[i];\r\n if (!entry.ref.get()) {\r\n entry.ref.dispose();\r\n this._staticCasters.splice(i, 1);\r\n } else {\r\n this.extendRegion(this._staticRegion, entry.aabb);\r\n }\r\n }\r\n this.updateRegion();\r\n }\r\n\r\n /** @internal */\r\n private rebuildDynamicRegion() {\r\n this._dynamicRegion.beginExtend();\r\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\r\n const entry = this._dynamicCasters[i];\r\n const caster = entry.ref.get();\r\n if (!caster || !this.isShadowCaster(caster)) {\r\n caster?.off('bvchanged', entry.callback);\r\n entry.ref.dispose();\r\n this._dynamicCasters.splice(i, 1);\r\n continue;\r\n }\r\n const aabb = this.getCasterAABB(caster);\r\n if (aabb) {\r\n this.extendRegion(this._dynamicRegion, aabb);\r\n }\r\n }\r\n this.updateRegion();\r\n }\r\n\r\n /** @internal */\r\n private updateRegion() {\r\n this._region.beginExtend();\r\n if (this._manualRegion?.isValid()) {\r\n this.extendRegion(this._region, this._manualRegion);\r\n }\r\n if (this._staticRegion.isValid()) {\r\n this.extendRegion(this._region, this._staticRegion);\r\n }\r\n if (this._dynamicRegion.isValid()) {\r\n this.extendRegion(this._region, this._dynamicRegion);\r\n }\r\n if (this._limit && this._region.isValid()) {\r\n const min = this._region.minPoint;\r\n const max = this._region.maxPoint;\r\n const lmin = this._limit.minPoint;\r\n const lmax = this._limit.maxPoint;\r\n min.setXYZ(Math.max(min.x, lmin.x), Math.max(min.y, lmin.y), Math.max(min.z, lmin.z));\r\n max.setXYZ(Math.min(max.x, lmax.x), Math.min(max.y, lmax.y), Math.min(max.z, lmax.z));\r\n if (min.x > max.x || min.y > max.y || min.z > max.z) {\r\n this._region.beginExtend();\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n private extendRegion(region: AABB, aabb: AABB) {\r\n region.extend(aabb.minPoint);\r\n region.extend(aabb.maxPoint);\r\n }\r\n}\r\n"],"names":["ShadowRegion","Disposable","region","_manualRegion","AABB","_limit","_staticRegion","beginExtend","_dynamicRegion","_region","_staticCasters","_dynamicCasters","updateRegion","isValid","manualRegion","limit","setLimit","staticRegion","dynamicRegion","setRegion","addStaticCaster","caster","isShadowCaster","hasCaster","aabb","getCasterAABB","push","ref","DWeakRef","extendRegion","addDynamicCaster","callback","rebuildDynamicRegion","on","removeCaster","changed","i","length","entry","node","get","dispose","splice","off","rebuildStaticRegion","clearCasters","clear","some","disposed","isMesh","isClipmapTerrain","isHair","bbox","getWorldBoundingVolume","toAABB","min","minPoint","max","maxPoint","lmin","lmax","setXYZ","Math","x","y","z","extend"],"mappings":";;AAcA;;;;;;;;;;IAWO,MAAMA,YAAqBC,SAAAA,UAAAA,CAAAA;qBAEhC,aAAsC;qBAEtC,MAA+B;qBAE/B,aAAqC;qBAErC,cAAsC;qBAEtC,OAA+B;qBAE/B,cAA2D;qBAE3D,eAA6D;AAE7D;;;;MAKA,WAAA,CAAYC,MAAuB,CAAE;QACnC,KAAK,EAAA;AACL,QAAA,IAAI,CAACC,aAAa,GAAGD,MAAS,GAAA,IAAIE,KAAKF,MAAU,CAAA,GAAA,IAAA;QACjD,IAAI,CAACG,MAAM,GAAG,IAAA;AACd,QAAA,IAAI,CAACC,aAAa,GAAG,IAAIF,OAAOG,WAAW,EAAA;AAC3C,QAAA,IAAI,CAACC,cAAc,GAAG,IAAIJ,OAAOG,WAAW,EAAA;AAC5C,QAAA,IAAI,CAACE,OAAO,GAAG,IAAIL,OAAOG,WAAW,EAAA;QACrC,IAAI,CAACG,cAAc,GAAG,EAAE;QACxB,IAAI,CAACC,eAAe,GAAG,EAAE;AACzB,QAAA,IAAI,CAACC,YAAY,EAAA;AACnB;AAEA;;;;;;AAMC,MACD,IAAIV,MAAyB,GAAA;QAC3B,OAAO,IAAI,CAACO,OAAO,CAACI,OAAO,EAAK,GAAA,IAAI,CAACJ,OAAO,GAAG,IAAA;AACjD;AAEA;;;;AAIC,MACD,IAAIK,YAA+B,GAAA;QACjC,OAAO,IAAI,CAACX,aAAa;AAC3B;AAEA;;;;AAIC,MACD,IAAIY,KAAwB,GAAA;QAC1B,OAAO,IAAI,CAACV,MAAM;AACpB;AAEA;;;;;MAMAW,QAAAA,CAASD,KAAqB,EAAQ;AACpC,QAAA,IAAI,CAACV,MAAM,GAAGU,OAAOF,OAAY,EAAA,GAAA,IAAIT,KAAKW,KAAS,CAAA,GAAA,IAAA;AACnD,QAAA,IAAI,CAACH,YAAY,EAAA;AACjB,QAAA,OAAO,IAAI;AACb;AAEA;;;;AAIC,MACD,IAAIK,YAA+B,GAAA;QACjC,OAAO,IAAI,CAACX,aAAa,CAACO,OAAO,EAAK,GAAA,IAAI,CAACP,aAAa,GAAG,IAAA;AAC7D;AAEA;;;;AAIC,MACD,IAAIY,aAAgC,GAAA;QAClC,OAAO,IAAI,CAACV,cAAc,CAACK,OAAO,EAAK,GAAA,IAAI,CAACL,cAAc,GAAG,IAAA;AAC/D;AAEA;;;;MAKAW,SAAAA,CAAUjB,MAAsB,EAAE;AAChC,QAAA,IAAI,CAACC,aAAa,GAAGD,MAAS,GAAA,IAAIE,KAAKF,MAAU,CAAA,GAAA,IAAA;AACjD,QAAA,IAAI,CAACU,YAAY,EAAA;AACnB;AAEA;;;;;MAMAQ,eAAAA,CAAgBC,MAAiB,EAAQ;QACvC,IAAI,CAAC,IAAI,CAACC,cAAc,CAACD,WAAW,IAAI,CAACE,SAAS,CAACF,MAAS,CAAA,EAAA;AAC1D,YAAA,OAAO,IAAI;AACb;AACA,QAAA,MAAMG,IAAO,GAAA,IAAI,CAACC,aAAa,CAACJ,MAAAA,CAAAA;AAChC,QAAA,IAAI,CAACG,IAAM,EAAA;AACT,YAAA,OAAO,IAAI;AACb;AACA,QAAA,IAAI,CAACd,cAAc,CAACgB,IAAI,CAAC;AACvBC,YAAAA,GAAAA,EAAK,IAAIC,QAASP,CAAAA,MAAAA,CAAAA;AAClBG,YAAAA;AACF,SAAA,CAAA;AACA,QAAA,IAAI,CAACK,YAAY,CAAC,IAAI,CAACvB,aAAa,EAAEkB,IAAAA,CAAAA;AACtC,QAAA,IAAI,CAACZ,YAAY,EAAA;AACjB,QAAA,OAAO,IAAI;AACb;AAEA;;;;;MAMAkB,gBAAAA,CAAiBT,MAAiB,EAAQ;QACxC,IAAI,CAAC,IAAI,CAACC,cAAc,CAACD,WAAW,IAAI,CAACE,SAAS,CAACF,MAAS,CAAA,EAAA;AAC1D,YAAA,OAAO,IAAI;AACb;AACA,QAAA,MAAMU,QAAW,GAAA,IAAA;AACf,YAAA,IAAI,CAACC,oBAAoB,EAAA;AAC3B,SAAA;QACAX,MAAOY,CAAAA,EAAE,CAAC,WAAaF,EAAAA,QAAAA,CAAAA;AACvB,QAAA,IAAI,CAACpB,eAAe,CAACe,IAAI,CAAC;AACxBC,YAAAA,GAAAA,EAAK,IAAIC,QAASP,CAAAA,MAAAA,CAAAA;AAClBU,YAAAA;AACF,SAAA,CAAA;AACA,QAAA,MAAMP,IAAO,GAAA,IAAI,CAACC,aAAa,CAACJ,MAAAA,CAAAA;AAChC,QAAA,IAAIG,IAAM,EAAA;AACR,YAAA,IAAI,CAACK,YAAY,CAAC,IAAI,CAACrB,cAAc,EAAEgB,IAAAA,CAAAA;AACvC,YAAA,IAAI,CAACZ,YAAY,EAAA;AACnB;AACA,QAAA,OAAO,IAAI;AACb;AAEA;;;;;MAMAsB,YAAAA,CAAab,MAAiB,EAAQ;AAEpC,QAAA,IAAIc,OAAU,GAAA,KAAA;QACd,IAAK,IAAIC,CAAI,GAAA,IAAI,CAAC1B,cAAc,CAAC2B,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACxD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAAC5B,cAAc,CAAC0B,CAAE,CAAA;AACpC,YAAA,MAAMG,IAAOD,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA;YAC1B,IAAI,CAACD,IAAQA,IAAAA,IAAAA,KAASlB,MAAQ,EAAA;gBAC5BiB,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC/B,cAAc,CAACgC,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;gBAC9BD,OAAU,GAAA,IAAA;AAEZ;AACF;QACA,IAAK,IAAIC,CAAI,GAAA,IAAI,CAACzB,eAAe,CAAC0B,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACzD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAAC3B,eAAe,CAACyB,CAAE,CAAA;AACrC,YAAA,MAAMG,IAAOD,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA;YAC1B,IAAI,CAACD,IAAQA,IAAAA,IAAAA,KAASlB,MAAQ,EAAA;AAC3BkB,gBAAAA,CAAAA,QAAQlB,MAAK,EAAGsB,GAAG,CAAC,WAAA,EAAaL,MAAMP,QAAQ,CAAA;gBAChDO,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC9B,eAAe,CAAC+B,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;gBAC/BD,OAAU,GAAA,IAAA;AAEZ;AACF;AACA,QAAA,IAAIA,OAAS,EAAA;AACX,YAAA,IAAI,CAACS,mBAAmB,EAAA;AACxB,YAAA,IAAI,CAACZ,oBAAoB,EAAA;AAC3B;AACA,QAAA,OAAO,IAAI;AACb;AAEA;;AAEC,MACDa,YAAe,GAAA;AACb,QAAA,KAAK,MAAMP,KAAAA,IAAS,IAAI,CAAC3B,eAAe,CAAE;AACxC2B,YAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,IAAIG,GAAI,CAAA,WAAA,EAAaL,MAAMP,QAAQ,CAAA;YAChDO,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACnB;AACA,QAAA,KAAK,MAAMH,KAAAA,IAAS,IAAI,CAAC5B,cAAc,CAAE;YACvC4B,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACnB;AACA,QAAA,IAAI,CAAC/B,cAAc,CAAC2B,MAAM,GAAG,CAAA;AAC7B,QAAA,IAAI,CAAC1B,eAAe,CAAC0B,MAAM,GAAG,CAAA;QAC9B,IAAI,CAAC/B,aAAa,CAACC,WAAW,EAAA;QAC9B,IAAI,CAACC,cAAc,CAACD,WAAW,EAAA;AAC/B,QAAA,IAAI,CAACK,YAAY,EAAA;AACnB;AAEA;;;;AAIC,MACDkC,KAAc,GAAA;QACZ,IAAI,CAAC3C,aAAa,GAAG,IAAA;AACrB,QAAA,IAAI,CAAC0C,YAAY,EAAA;AACjB,QAAA,OAAO,IAAI;AACb;8CAGA,SAA4B,GAAA;AAC1B,QAAA,IAAI,CAACC,KAAK,EAAA;AACZ;AAEA,qBACQvB,SAAUF,CAAAA,MAAiB,EAAW;QAC5C,OACE,IAAI,CAACX,cAAc,CAACqC,IAAI,CAAC,CAACT,KAAUA,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA,KAAOnB,WACxD,IAAI,CAACV,eAAe,CAACoC,IAAI,CAAC,CAACT,KAAAA,GAAUA,KAAMX,CAAAA,GAAG,CAACa,GAAG,EAAOnB,KAAAA,MAAAA,CAAAA;AAE7D;AAEA,qBACQC,cAAeD,CAAAA,MAAiB,EAAW;AACjD,QAAA,OAAO,CAACA,MAAAA,CAAO2B,QAAQ,KAAK3B,MAAAA,CAAO4B,MAAM,EAAA,IAAM5B,MAAO6B,CAAAA,gBAAgB,EAAM7B,IAAAA,MAAAA,CAAO8B,MAAM,EAAC,CAAA;AAC5F;AAEA,qBACQ1B,aAAcJ,CAAAA,MAAiB,EAAkB;QACvD,MAAM+B,IAAAA,GAAO/B,MAAOgC,CAAAA,sBAAsB,EAAIC,EAAAA,MAAAA,EAAAA;AAC9C,QAAA,OAAOF,IAAMvC,EAAAA,OAAAA,EAAAA,GAAY,IAAIT,IAAAA,CAAKgD,IAAQ,CAAA,GAAA,IAAA;AAC5C;qBAGA,mBAA8B,GAAA;QAC5B,IAAI,CAAC9C,aAAa,CAACC,WAAW,EAAA;QAC9B,IAAK,IAAI6B,CAAI,GAAA,IAAI,CAAC1B,cAAc,CAAC2B,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACxD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAAC5B,cAAc,CAAC0B,CAAE,CAAA;AACpC,YAAA,IAAI,CAACE,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAI,EAAA;gBACpBF,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC/B,cAAc,CAACgC,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;aACzB,MAAA;gBACL,IAAI,CAACP,YAAY,CAAC,IAAI,CAACvB,aAAa,EAAEgC,MAAMd,IAAI,CAAA;AAClD;AACF;AACA,QAAA,IAAI,CAACZ,YAAY,EAAA;AACnB;qBAGA,oBAA+B,GAAA;QAC7B,IAAI,CAACJ,cAAc,CAACD,WAAW,EAAA;QAC/B,IAAK,IAAI6B,CAAI,GAAA,IAAI,CAACzB,eAAe,CAAC0B,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACzD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAAC3B,eAAe,CAACyB,CAAE,CAAA;AACrC,YAAA,MAAMf,MAASiB,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA;AAC5B,YAAA,IAAI,CAACnB,MAAU,IAAA,CAAC,IAAI,CAACC,cAAc,CAACD,MAAS,CAAA,EAAA;gBAC3CA,MAAQsB,EAAAA,GAAAA,CAAI,WAAaL,EAAAA,KAAAA,CAAMP,QAAQ,CAAA;gBACvCO,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC9B,eAAe,CAAC+B,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;AAC/B,gBAAA;AACF;AACA,YAAA,MAAMZ,IAAO,GAAA,IAAI,CAACC,aAAa,CAACJ,MAAAA,CAAAA;AAChC,YAAA,IAAIG,IAAM,EAAA;AACR,gBAAA,IAAI,CAACK,YAAY,CAAC,IAAI,CAACrB,cAAc,EAAEgB,IAAAA,CAAAA;AACzC;AACF;AACA,QAAA,IAAI,CAACZ,YAAY,EAAA;AACnB;qBAGA,YAAuB,GAAA;QACrB,IAAI,CAACH,OAAO,CAACF,WAAW,EAAA;AACxB,QAAA,IAAI,IAAI,CAACJ,aAAa,EAAEU,OAAW,EAAA,EAAA;YACjC,IAAI,CAACgB,YAAY,CAAC,IAAI,CAACpB,OAAO,EAAE,IAAI,CAACN,aAAa,CAAA;AACpD;AACA,QAAA,IAAI,IAAI,CAACG,aAAa,CAACO,OAAO,EAAI,EAAA;YAChC,IAAI,CAACgB,YAAY,CAAC,IAAI,CAACpB,OAAO,EAAE,IAAI,CAACH,aAAa,CAAA;AACpD;AACA,QAAA,IAAI,IAAI,CAACE,cAAc,CAACK,OAAO,EAAI,EAAA;YACjC,IAAI,CAACgB,YAAY,CAAC,IAAI,CAACpB,OAAO,EAAE,IAAI,CAACD,cAAc,CAAA;AACrD;QACA,IAAI,IAAI,CAACH,MAAM,IAAI,IAAI,CAACI,OAAO,CAACI,OAAO,EAAI,EAAA;AACzC,YAAA,MAAM0C,GAAM,GAAA,IAAI,CAAC9C,OAAO,CAAC+C,QAAQ;AACjC,YAAA,MAAMC,GAAM,GAAA,IAAI,CAAChD,OAAO,CAACiD,QAAQ;AACjC,YAAA,MAAMC,IAAO,GAAA,IAAI,CAACtD,MAAM,CAACmD,QAAQ;AACjC,YAAA,MAAMI,IAAO,GAAA,IAAI,CAACvD,MAAM,CAACqD,QAAQ;YACjCH,GAAIM,CAAAA,MAAM,CAACC,IAAAA,CAAKL,GAAG,CAACF,GAAIQ,CAAAA,CAAC,EAAEJ,IAAAA,CAAKI,CAAC,CAAA,EAAGD,IAAKL,CAAAA,GAAG,CAACF,GAAAA,CAAIS,CAAC,EAAEL,IAAKK,CAAAA,CAAC,CAAGF,EAAAA,IAAAA,CAAKL,GAAG,CAACF,GAAIU,CAAAA,CAAC,EAAEN,IAAAA,CAAKM,CAAC,CAAA,CAAA;YACnFR,GAAII,CAAAA,MAAM,CAACC,IAAAA,CAAKP,GAAG,CAACE,GAAIM,CAAAA,CAAC,EAAEH,IAAAA,CAAKG,CAAC,CAAA,EAAGD,IAAKP,CAAAA,GAAG,CAACE,GAAAA,CAAIO,CAAC,EAAEJ,IAAKI,CAAAA,CAAC,CAAGF,EAAAA,IAAAA,CAAKP,GAAG,CAACE,GAAIQ,CAAAA,CAAC,EAAEL,IAAAA,CAAKK,CAAC,CAAA,CAAA;AACnF,YAAA,IAAIV,IAAIQ,CAAC,GAAGN,GAAIM,CAAAA,CAAC,IAAIR,GAAIS,CAAAA,CAAC,GAAGP,GAAAA,CAAIO,CAAC,IAAIT,GAAAA,CAAIU,CAAC,GAAGR,GAAAA,CAAIQ,CAAC,EAAE;gBACnD,IAAI,CAACxD,OAAO,CAACF,WAAW,EAAA;AAC1B;AACF;AACF;AAEA,qBACA,YAAQsB,CAAa3B,MAAY,EAAEsB,IAAU,EAAE;QAC7CtB,MAAOgE,CAAAA,MAAM,CAAC1C,IAAAA,CAAKgC,QAAQ,CAAA;QAC3BtD,MAAOgE,CAAAA,MAAM,CAAC1C,IAAAA,CAAKkC,QAAQ,CAAA;AAC7B;AACF;;;;"}
@@ -9,6 +9,7 @@ import { DOM } from './dom.js';
9
9
  import { LIGHT_TYPE_NONE, LIGHT_TYPE_POINT, LIGHT_TYPE_DIRECTIONAL } from '../values.js';
10
10
  import { getDevice } from '../app/api.js';
11
11
  import { ShadowRegion } from './shadow_region.js';
12
+ import { warnUnsupported } from '../utility/unsupported.js';
12
13
 
13
14
  const tmpMatrix = new Matrix4x4();
14
15
  const tmpFrustum = new Frustum(Matrix4x4.identity());
@@ -22,6 +23,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
22
23
  /** @internal */ static _frustumMin = new Vector3();
23
24
  /** @internal */ static _frustumMax = new Vector3();
24
25
  /** @internal */ static _frustumCenter = new Vector3();
26
+ /** @internal */ static _clipMin = new Vector3();
27
+ /** @internal */ static _clipMax = new Vector3();
28
+ /** @internal */ static _cameraPos = new Vector3();
25
29
  /** @internal */ static _lightCameras = new WeakMap();
26
30
  /** @internal */ static _shadowMapParams = [];
27
31
  /** @internal */ _light;
@@ -63,7 +67,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
63
67
  splitLambda: 0.5,
64
68
  depthBias: 0.003,
65
69
  normalBias: 1.5,
66
- nearClip: 1
70
+ nearClip: ShadowMapper.getDefaultNearClip(light)
67
71
  };
68
72
  this._resourceDirty = true;
69
73
  this._shadowMode = 'pcf';
@@ -235,7 +239,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
235
239
  this.splitLambda = 0.75;
236
240
  this.depthBias = 0.005;
237
241
  this.normalBias = 2;
238
- this.nearClip = 0.2;
242
+ // Tighter than the default for spot lights; point and rect lights are
243
+ // already at their close-range default.
244
+ this.nearClip = Math.min(0.2, ShadowMapper.getDefaultNearClip(this._light));
239
245
  this.pcfKernelSize = 5;
240
246
  this.numShadowCascades = this._light.isDirectionLight() ? 3 : 1;
241
247
  return;
@@ -246,7 +252,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
246
252
  this.splitLambda = 0.6;
247
253
  this.depthBias = 0.0035;
248
254
  this.normalBias = 1.5;
249
- this.nearClip = 1;
255
+ this.nearClip = ShadowMapper.getDefaultNearClip(this._light);
250
256
  this.pcfKernelSize = 3;
251
257
  this.numShadowCascades = this._light.isDirectionLight() ? 4 : 1;
252
258
  }
@@ -289,7 +295,13 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
289
295
  }
290
296
  }
291
297
  }
292
- /** Light radius for PCSS shadow, measured in shadow-map texels */ get pcssLightRadius() {
298
+ /**
299
+ * Light radius for PCSS shadow, measured in shadow-map texels.
300
+ *
301
+ * @remarks
302
+ * Ignored for rect lights, whose penumbra is derived from their actual size
303
+ * and the receiver's distance instead.
304
+ */ get pcssLightRadius() {
293
305
  return this._pcssLightRadius;
294
306
  }
295
307
  set pcssLightRadius(val) {
@@ -559,7 +571,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
559
571
  }
560
572
  /** @internal */ static fetchTemporalFramebuffer(autoRelease, lightType, numCascades, width, height, colorFormat, depthFormat, mipmapping) {
561
573
  const device = getDevice();
562
- const useTextureArray = numCascades > 1 && device.type !== 'webgl';
574
+ const useTextureArray = numCascades > 1;
563
575
  const colorAttachments = colorFormat ? useTextureArray ? [
564
576
  device.pool.fetchTemporalTexture2DArray(false, colorFormat, width, height, numCascades, mipmapping)
565
577
  ] : lightType === LIGHT_TYPE_POINT ? [
@@ -567,7 +579,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
567
579
  ] : [
568
580
  device.pool.fetchTemporalTexture2D(false, colorFormat, width, height, mipmapping)
569
581
  ] : null;
570
- const depthAttachment = depthFormat ? useTextureArray ? device.pool.fetchTemporalTexture2DArray(false, depthFormat, width, height, numCascades, false) : device.type !== 'webgl' && lightType === LIGHT_TYPE_POINT ? device.pool.fetchTemporalTextureCube(false, depthFormat, width, false) : device.pool.fetchTemporalTexture2D(false, depthFormat, width, height, false) : null;
582
+ const depthAttachment = depthFormat ? useTextureArray ? device.pool.fetchTemporalTexture2DArray(false, depthFormat, width, height, numCascades, false) : lightType === LIGHT_TYPE_POINT ? device.pool.fetchTemporalTextureCube(false, depthFormat, width, false) : device.pool.fetchTemporalTexture2D(false, depthFormat, width, height, false) : null;
571
583
  const fb = device.pool.createTemporalFramebuffer(autoRelease, colorAttachments, depthAttachment);
572
584
  if (colorAttachments) {
573
585
  device.pool.releaseTexture(colorAttachments[0]);
@@ -578,39 +590,29 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
578
590
  return fb;
579
591
  }
580
592
  /** @internal */ updateResources(shadowMapParams) {
581
- const device = getDevice();
582
593
  const colorFormat = shadowMapParams.impl.getShadowMapColorFormat(shadowMapParams);
583
594
  const depthFormat = shadowMapParams.impl.getShadowMapDepthFormat(shadowMapParams);
584
595
  const numCascades = shadowMapParams.numShadowCascades;
585
- const useTextureArray = numCascades > 1 && device.type !== 'webgl';
586
- const shadowMapWidth = numCascades > 1 && !useTextureArray ? 2 * this._config.shadowMapSize : this._config.shadowMapSize;
587
- const shadowMapHeight = numCascades > 2 && !useTextureArray ? 2 * this._config.shadowMapSize : this._config.shadowMapSize;
588
- /*
589
- const colorAttachments = colorFormat
590
- ? useTextureArray
591
- ? [device.pool.fetchTemporalTexture2DArray(false, colorFormat, shadowMapWidth, shadowMapHeight, numCascades, false)]
592
- : this._light.isPointLight()
593
- ? [device.pool.fetchTemporalTextureCube(false, colorFormat, shadowMapWidth, false)]
594
- : [device.pool.fetchTemporalTexture2D(false, colorFormat, shadowMapWidth, shadowMapHeight, false)]
595
- : null;
596
- const depthAttachment = depthFormat
597
- ? useTextureArray
598
- ? device.pool.fetchTemporalTexture2DArray(false, depthFormat, shadowMapWidth, shadowMapHeight, numCascades, false)
599
- : device.type !== 'webgl' && this._light.isPointLight()
600
- ? device.pool.fetchTemporalTextureCube(false, depthFormat, shadowMapWidth, false)
601
- : device.pool.fetchTemporalTexture2D(false, depthFormat, shadowMapWidth, shadowMapHeight, false)
602
- : null;
603
- shadowMapParams.shadowMapFramebuffer = device.pool.createTemporalFramebuffer(false, colorAttachments, depthAttachment);
604
- if (colorAttachments) {
605
- device.pool.releaseTexture(colorAttachments[0]);
606
- }
607
- if (depthAttachment) {
608
- device.pool.releaseTexture(depthAttachment);
609
- }
610
- */ shadowMapParams.shadowMapFramebuffer = ShadowMapper.fetchTemporalFramebuffer(true, this._light.lightType, numCascades, shadowMapWidth, shadowMapHeight, colorFormat, depthFormat);
596
+ const shadowMapWidth = this._config.shadowMapSize;
597
+ const shadowMapHeight = this._config.shadowMapSize;
598
+ shadowMapParams.shadowMapFramebuffer = ShadowMapper.fetchTemporalFramebuffer(true, shadowMapParams.lightType, numCascades, shadowMapWidth, shadowMapHeight, colorFormat, depthFormat);
611
599
  shadowMapParams.impl = this._impl;
612
600
  this._impl.updateResources(shadowMapParams);
613
601
  }
602
+ /**
603
+ * Default shadow camera near plane for a light, in world units.
604
+ *
605
+ * @internal
606
+ */ static getDefaultNearClip(light) {
607
+ return light.isPointLight() || light.isRectLight() ? 0.1 : 1;
608
+ }
609
+ /**
610
+ * The projection a light's shadow map is rendered with, which is not always the light's own type.
611
+ *
612
+ * @internal
613
+ */ static getShadowProjectionType(light) {
614
+ return light.isRectLight() ? LIGHT_TYPE_POINT : light.lightType;
615
+ }
614
616
  /** @internal */ createLightCameraPoint(lightCamera) {
615
617
  //lightCamera.reparent(this._light);
616
618
  lightCamera.parent = lightCamera.scene.rootNode;
@@ -630,16 +632,6 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
630
632
  const fov = spot.scene?.lightingMode === 'physical' ? 2 * spot.outerConeAngle : 2 * Math.acos(spot.cutoff);
631
633
  lightCamera.setPerspective(fov, 1, this._config.nearClip, Math.min(this._shadowDistance, spot.positionAndRange.w));
632
634
  }
633
- /** @internal */ createLightCameraRect(lightCamera) {
634
- const rect = this._light;
635
- this._light.worldMatrix.decompose(null, lightCamera.rotation, lightCamera.position);
636
- lightCamera.parent = this._light.scene?.rootNode ?? null;
637
- lightCamera.scale.setXYZ(1, 1, 1);
638
- const halfW = rect.width * 0.5;
639
- const halfH = rect.height * 0.5;
640
- const far = Math.min(this._shadowDistance, rect.range);
641
- lightCamera.setOrtho(-halfW, halfW, -halfH, halfH, this._config.nearClip, Math.max(this._config.nearClip + 0.001, far));
642
- }
643
635
  /** @internal */ createLightCameraDirectional(sceneAABB, sceneCamera, lightCamera, cropMatrix, border) {
644
636
  let frustum = sceneCamera.frustumViewSpace;
645
637
  if (this._shadowDistance < sceneCamera.getFarPlane()) {
@@ -667,11 +659,35 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
667
659
  });
668
660
  let radius = Vector3.distance(frustumMin, frustumMax) * 0.5 * paddingScale;
669
661
  const center = sceneCamera.thisToWorld(Vector3.add(frustumMin, frustumMax, frustumCenter).scaleBy(0.5), frustumCenter);
670
- // Clamp to the scene bounds first, then apply the filter border.
671
- const sceneRadius = sceneAABB.diagonalLength * 0.5 * paddingScale;
672
- if (sceneRadius < radius) {
673
- radius = sceneRadius;
674
- Vector3.add(sceneAABB.minPoint, sceneAABB.maxPoint, center).scaleBy(0.5);
662
+ // Clamp to the scene bounds, but only to the part of them that is within
663
+ // the shadow distance of the camera. Clipping first is what makes the two
664
+ // settings compose. The clamp replaces the centre as well as the radius, so
665
+ // without the clip a region is taken whole or not at all: one caster
666
+ // wandering off drags the region - and with it the shadow map - after it,
667
+ // however short the shadow distance is, until the region finally outgrows
668
+ // the frustum and the clamp stops applying altogether. Clipped, a caster
669
+ // beyond the shadow distance simply stops counting, which is what the
670
+ // shadow distance means.
671
+ //
672
+ // The clip volume is a box about the camera's position, not about the
673
+ // frustum, so the clipped extents - and the radius taken from them - do not
674
+ // depend on where the camera is looking. That is deliberate: a radius that
675
+ // changed with the view direction would make the shadow edges crawl as the
676
+ // camera turned.
677
+ const clipDistance = Math.min(this._shadowDistance, sceneCamera.getFarPlane());
678
+ const cameraPos = sceneCamera.getWorldPosition(ShadowMapper._cameraPos);
679
+ const clipMin = ShadowMapper._clipMin;
680
+ const clipMax = ShadowMapper._clipMax;
681
+ clipMin.setXYZ(Math.max(sceneAABB.minPoint.x, cameraPos.x - clipDistance), Math.max(sceneAABB.minPoint.y, cameraPos.y - clipDistance), Math.max(sceneAABB.minPoint.z, cameraPos.z - clipDistance));
682
+ clipMax.setXYZ(Math.min(sceneAABB.maxPoint.x, cameraPos.x + clipDistance), Math.min(sceneAABB.maxPoint.y, cameraPos.y + clipDistance), Math.min(sceneAABB.maxPoint.z, cameraPos.z + clipDistance));
683
+ // An empty intersection means nothing within the shadow distance casts a
684
+ // shadow. There is no tighter volume to move to, so the frustum stands.
685
+ if (clipMax.x >= clipMin.x && clipMax.y >= clipMin.y && clipMax.z >= clipMin.z) {
686
+ const sceneRadius = Vector3.distance(clipMin, clipMax) * 0.5 * paddingScale;
687
+ if (sceneRadius < radius) {
688
+ radius = sceneRadius;
689
+ Vector3.add(clipMin, clipMax, center).scaleBy(0.5);
690
+ }
675
691
  }
676
692
  target.setXYZ(center.x + this._light.directionAndCutoff.x, center.y + this._light.directionAndCutoff.y, center.z + this._light.directionAndCutoff.z);
677
693
  up.setXYZ(0, 1, 0);
@@ -760,6 +776,8 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
760
776
  // Pooled objects retain last frame's ordinal; clear it so it is only set
761
777
  // again by ShadowMaskRenderer for lights actually written to the mask.
762
778
  params.maskOrdinal = undefined;
779
+ params.cubeFace = undefined;
780
+ params.depthRange = undefined;
763
781
  return params;
764
782
  } else {
765
783
  return {
@@ -810,6 +828,20 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
810
828
  camera.remove();
811
829
  cameras.push(camera);
812
830
  }
831
+ /**
832
+ * View distances bounding the cascades a directional light's shadow map will be rendered with
833
+ * for a camera, the same ones render() computes: cascade i covers [result[i], result[i + 1]].
834
+ * A shadow map without cascades has one, up to the shadow distance.
835
+ * @internal
836
+ */ getCascadeDistances(camera) {
837
+ const numCascades = this._light.isDirectionLight() && this._impl.supportsCascades() ? this._config.numCascades ?? 1 : 1;
838
+ const near = camera.getNearPlane();
839
+ const far = Math.min(this._shadowDistance, camera.getFarPlane());
840
+ return numCascades > 1 ? this.calcSplitDistances(near, far, numCascades).slice(0, numCascades + 1) : [
841
+ near,
842
+ far
843
+ ];
844
+ }
813
845
  /** @internal */ calcSplitDistances(nearPlane, farPlane, numCascades) {
814
846
  const result = [
815
847
  0,
@@ -848,8 +880,15 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
848
880
  }
849
881
  const shadowMapParams = ShadowMapper.fetchShadowMapParams();
850
882
  shadowMapParams.impl = this._impl;
851
- shadowMapParams.lightType = this.light.lightType;
883
+ shadowMapParams.lightType = ShadowMapper.getShadowProjectionType(this.light);
884
+ if (this._impl instanceof PCSS) {
885
+ // A rect light's penumbra follows its size: the radius of the disc of
886
+ // equal area, in world units. Refreshed every frame so resizing the
887
+ // light is picked up without touching the shadow settings.
888
+ this._impl.physicalLightRadius = this._light.isRectLight() ? Math.sqrt(this._light.width * this._light.height / Math.PI) : 0;
889
+ }
852
890
  shadowMapParams.numShadowCascades = shadowMapParams.lightType === LIGHT_TYPE_DIRECTIONAL && this._impl.supportsCascades() ? this._config.numCascades ?? 1 : 1;
891
+ shadowMapParams.cascadeIndex = 0;
853
892
  ctx.shadowMapInfo.set(this.light, shadowMapParams);
854
893
  const scene = ctx.scene;
855
894
  const camera = ctx.camera;
@@ -889,13 +928,14 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
889
928
  };
890
929
  const directionalShadowRegion = this._shadowRegion.region;
891
930
  const shadowRegion = this._light.isDirectionLight() && directionalShadowRegion?.isValid() ? directionalShadowRegion : scene.boundingBox;
892
- if (this._light.isPointLight()) {
931
+ if (shadowMapParams.lightType === LIGHT_TYPE_POINT) {
893
932
  const shadowMapRenderCamera = ShadowMapper.fetchCameraForScene(scene);
894
933
  this.createLightCameraPoint(shadowMapRenderCamera);
895
934
  this.calcDepthBiasParams(shadowMapRenderCamera, this._config.shadowMapSize, this._config.depthBias, this._config.normalBias, depthScale, shadowMapParams.depthBiasValues[0]);
896
935
  shadowMapParams.cameraParams.setXYZW(shadowMapRenderCamera.getNearPlane(), shadowMapRenderCamera.getFarPlane(), this._config.shadowMapSize, this._shadowDistance);
897
936
  device.setFramebuffer(fb);
898
937
  shadowMapParams.shadowMatrices.set(Matrix4x4.transpose(shadowMapRenderCamera.viewMatrix));
938
+ shadowMapParams.depthRange = this._light.positionAndRange.w;
899
939
  for (const face of [
900
940
  CubeFace.PX,
901
941
  CubeFace.NX,
@@ -907,6 +947,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
907
947
  shadowMapRenderCamera.lookAtCubeFace(face);
908
948
  fb.setColorAttachmentCubeFace(0, face);
909
949
  fb.setDepthAttachmentCubeFace(face);
950
+ shadowMapParams.cubeFace = face;
910
951
  renderGeometry(shadowMapRenderCamera);
911
952
  }
912
953
  shadowMapParams.shadowMatrices.set(Matrix4x4.identity());
@@ -967,6 +1008,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
967
1008
  }
968
1009
  device.setFramebuffer(fb);
969
1010
  device.setScissor(scissor);
1011
+ shadowMapParams.cascadeIndex = split;
970
1012
  renderGeometry(shadowMapRenderCamera, shadowMapCullCamera);
971
1013
  shadowMapParams.shadowMatrices.set(Matrix4x4.transpose(shadowMapRenderCamera.viewProjectionMatrix), split * 16);
972
1014
  shadowMapParams.cascadeDistances[split] = distances[split + 1];
@@ -981,8 +1023,6 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
981
1023
  shadowMapRenderCamera.clipMask = AABB.ClipLeft | AABB.ClipRight | AABB.ClipBottom | AABB.ClipTop;
982
1024
  if (this._light.isDirectionLight()) {
983
1025
  this.createLightCameraDirectional(shadowRegion, camera, shadowMapRenderCamera, snapMatrix, shadowMapParams.impl.getShadowMapBorder(shadowMapParams));
984
- } else if (this._light.isRectLight()) {
985
- this.createLightCameraRect(shadowMapRenderCamera);
986
1026
  } else {
987
1027
  this.createLightCameraSpot(shadowMapRenderCamera);
988
1028
  }
@@ -1006,7 +1046,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
1006
1046
  // The strand geometry this mode exists to shadow is WebGPU only, so the
1007
1047
  // WebGL paths were never built. Falling back keeps a scene authored with it
1008
1048
  // renderable rather than failing to produce a shadow map at all.
1009
- console.warn(`ShadowMapper.setShadowMode(): 'dom' requires WebGPU, falling back to 'pcf'`);
1049
+ warnUnsupported("Deep opacity map shadows (shadow mode 'dom')", 'WebGPU', "falling back to 'pcf'");
1010
1050
  this.applyMode('pcf');
1011
1051
  return;
1012
1052
  }