@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.
- package/README.md +60 -27
- package/dist/animation/animation_bank.js +634 -0
- package/dist/animation/animation_bank.js.map +1 -0
- package/dist/animation/animation_bank_gpu.js +256 -0
- package/dist/animation/animation_bank_gpu.js.map +1 -0
- package/dist/animation/animationset.js +146 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_component.js +406 -0
- package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
- package/dist/animation/cloth/gpu_cloth_system.js +332 -202
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/gpu_animation_driver.js +289 -0
- package/dist/animation/gpu_animation_driver.js.map +1 -0
- package/dist/animation/joint_dynamics/collision.js +112 -1
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +6 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +50 -12
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/skeleton.js +300 -56
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skin_palette_atlas.js +252 -0
- package/dist/animation/skin_palette_atlas.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +298 -38
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +2 -0
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +159 -21
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_solver.js +173 -0
- package/dist/animation/spring/spring_solver.js.map +1 -0
- package/dist/animation/spring/spring_system.js +249 -24
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +32 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/app.js +26 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +86 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/gamepad.js +191 -0
- package/dist/app/gamepad.js.map +1 -0
- package/dist/app/inputactions.js +271 -0
- package/dist/app/inputactions.js.map +1 -0
- package/dist/app/inputmgr.js +331 -22
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/loading.js +138 -0
- package/dist/app/loading.js.map +1 -0
- package/dist/app/pipelinecache.js +209 -0
- package/dist/app/pipelinecache.js.map +1 -0
- package/dist/app/runtimescript.js +25 -0
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/scriptingsystem.js +54 -0
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +7 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/asset_manifest.js +59 -0
- package/dist/asset/asset_manifest.js.map +1 -0
- package/dist/asset/asset_preload.js +258 -0
- package/dist/asset/asset_preload.js.map +1 -0
- package/dist/asset/assetmanager.js +117 -65
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/dist/asset/loaders/ktx2/basis_location.js +17 -0
- package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
- package/dist/asset/mesh_lod_builder.js +104 -0
- package/dist/asset/mesh_lod_builder.js.map +1 -0
- package/dist/asset/mesh_settings.js +111 -0
- package/dist/asset/mesh_settings.js.map +1 -0
- package/dist/asset/meshopt_decoder.js +18 -0
- package/dist/asset/meshopt_decoder.js.map +1 -0
- package/dist/asset/meshopt_simplifier.js +26 -0
- package/dist/asset/meshopt_simplifier.js.map +1 -0
- package/dist/asset/model.js +177 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/asset/texture_settings.js +231 -0
- package/dist/asset/texture_settings.js.map +1 -0
- package/dist/asset/zmsh_binary.js +131 -0
- package/dist/asset/zmsh_binary.js.map +1 -0
- package/dist/asset/zsdf_binary.js +111 -0
- package/dist/asset/zsdf_binary.js.map +1 -0
- package/dist/blitter/bilateralblur.js +1 -2
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/gaussianblur.js +1 -6
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +31 -10
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +178 -200
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/follow.js +342 -0
- package/dist/camera/follow.js.map +1 -0
- package/dist/camera/fps.js +9 -7
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +46 -19
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +30475 -19865
- package/dist/index.js +67 -12
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +3 -0
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/eye.js +1 -1
- package/dist/material/eye.js.map +1 -1
- package/dist/material/hair.js +2 -3
- package/dist/material/hair.js.map +1 -1
- package/dist/material/hairstrand.js +235 -235
- package/dist/material/hairstrand.js.map +1 -1
- package/dist/material/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +362 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +118 -45
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +223 -83
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +31 -206
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +1 -1
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrmr.js +3 -0
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +3 -0
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/sdf_debug.js +78 -0
- package/dist/material/sdf_debug.js.map +1 -0
- package/dist/material/shader/helper.js +733 -190
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +204 -43
- package/dist/material/shader/terrain_blend.js.map +1 -1
- package/dist/material/skin.js +331 -297
- package/dist/material/skin.js.map +1 -1
- package/dist/material/skinprofile.js +1058 -0
- package/dist/material/skinprofile.js.map +1 -0
- package/dist/material/sss.js +353 -0
- package/dist/material/sss.js.map +1 -0
- package/dist/material/sss_kernel.js +265 -0
- package/dist/material/sss_kernel.js.map +1 -0
- package/dist/material/sssprofile.js +879 -0
- package/dist/material/sssprofile.js.map +1 -0
- package/dist/material/subsurfaceprofile.js +4 -8
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/terrain-cm.js +464 -188
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js +3 -0
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js +2009 -201
- package/dist/material/water.js.map +1 -1
- package/dist/node_modules/meshoptimizer/LICENSE +21 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
- package/dist/physics/character.js +226 -0
- package/dist/physics/character.js.map +1 -0
- package/dist/physics/collider.js +209 -0
- package/dist/physics/collider.js.map +1 -0
- package/dist/physics/events.js +79 -0
- package/dist/physics/events.js.map +1 -0
- package/dist/physics/joint.js +272 -0
- package/dist/physics/joint.js.map +1 -0
- package/dist/physics/node_physics.js +234 -0
- package/dist/physics/node_physics.js.map +1 -0
- package/dist/physics/part.js +91 -0
- package/dist/physics/part.js.map +1 -0
- package/dist/physics/rigid_body.js +379 -0
- package/dist/physics/rigid_body.js.map +1 -0
- package/dist/physics/vehicle.js +335 -0
- package/dist/physics/vehicle.js.map +1 -0
- package/dist/physics/world.js +25 -0
- package/dist/physics/world.js.map +1 -0
- package/dist/posteffect/bloom.js +49 -14
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/motionblur.js +668 -63
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +12 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +48 -50
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +605 -355
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +91 -162
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -11
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +34 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +1 -0
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +40 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +328 -62
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +958 -224
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +26 -5
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/debug_views.js +37 -0
- package/dist/render/debug_views.js.map +1 -0
- package/dist/render/depthpass.js +5 -1
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +53 -6
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +53 -53
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +196 -113
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +8 -13
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +268 -136
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +113 -28
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/gi/probe_volume.js +1334 -0
- package/dist/render/gi/probe_volume.js.map +1 -0
- package/dist/render/gi/scene_gi.js +282 -0
- package/dist/render/gi/scene_gi.js.map +1 -0
- package/dist/render/gi/voxel_atlas.js +198 -0
- package/dist/render/gi/voxel_atlas.js.map +1 -0
- package/dist/render/gi/voxel_lighting.js +652 -0
- package/dist/render/gi/voxel_lighting.js.map +1 -0
- package/dist/render/gi/voxel_scene.js +642 -0
- package/dist/render/gi/voxel_scene.js.map +1 -0
- package/dist/render/gi/voxelize_pass.js +223 -0
- package/dist/render/gi/voxelize_pass.js.map +1 -0
- package/dist/render/globalbindgroup_allocator.js +3 -2
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/gpu_picking.js +9 -36
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +23 -9
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/lod.js +46 -0
- package/dist/render/lod.js.map +1 -0
- package/dist/render/oit.js +11 -11
- package/dist/render/oit.js.map +1 -1
- package/dist/render/primitive.js +301 -9
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/primitive_readback.js +209 -0
- package/dist/render/primitive_readback.js.map +1 -0
- package/dist/render/render_queue.js +198 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +14 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +15 -1
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/executor.js +136 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +585 -59
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +8 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +31 -2
- package/dist/render/rendergraph/scene_render_context.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +28 -5
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sdf/box_allocator.js +98 -0
- package/dist/render/sdf/box_allocator.js.map +1 -0
- package/dist/render/sdf/global_sdf.js +865 -0
- package/dist/render/sdf/global_sdf.js.map +1 -0
- package/dist/render/sdf/scene_sdf.js +562 -0
- package/dist/render/sdf/scene_sdf.js.map +1 -0
- package/dist/render/sdf/sdf_atlas.js +227 -0
- package/dist/render/sdf/sdf_atlas.js.map +1 -0
- package/dist/render/sdf/sdf_programs.js +42 -0
- package/dist/render/sdf/sdf_programs.js.map +1 -0
- package/dist/render/sdf/sdf_view.js +199 -0
- package/dist/render/sdf/sdf_view.js.map +1 -0
- package/dist/render/sdf/waterline.js +610 -0
- package/dist/render/sdf/waterline.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +142 -25
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/shore_wave_generator.js +1193 -0
- package/dist/render/shore_wave_generator.js.map +1 -0
- package/dist/render/sky.js +516 -86
- package/dist/render/sky.js.map +1 -1
- package/dist/render/transmission_thickness_pass.js +477 -0
- package/dist/render/transmission_thickness_pass.js.map +1 -0
- package/dist/render/underwater.js +524 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/virtualtexture/virtual_texture.js +1214 -0
- package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_common.js +472 -0
- package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
- package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
- package/dist/render/volumetric_cloud/debug_view.js +131 -0
- package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
- package/dist/render/volumetric_cloud/resources.js +380 -0
- package/dist/render/volumetric_cloud/resources.js.map +1 -0
- package/dist/render/volumetric_cloud/sky_cache.js +380 -0
- package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
- package/dist/render/water_caustics.js +1195 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/water_foam.js +627 -0
- package/dist/render/water_foam.js.map +1 -0
- package/dist/render/water_interaction.js +1795 -0
- package/dist/render/water_interaction.js.map +1 -0
- package/dist/render/weightedblended_oit.js +36 -36
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +9 -4
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +108 -12
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +28 -7
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/foliage.js +1020 -0
- package/dist/scene/foliage.js.map +1 -0
- package/dist/scene/foliage_buckets.js +147 -0
- package/dist/scene/foliage_buckets.js.map +1 -0
- package/dist/scene/foliage_mask.js +358 -0
- package/dist/scene/foliage_mask.js.map +1 -0
- package/dist/scene/hair.js +15 -4
- package/dist/scene/hair.js.map +1 -1
- package/dist/scene/light.js +179 -13
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +327 -45
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +9 -3
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +9 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +8 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/physics_settings.js +157 -0
- package/dist/scene/physics_settings.js.map +1 -0
- package/dist/scene/scene.js +190 -44
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +147 -6
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
- package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +881 -42
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grass_gpu.js +929 -0
- package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js +180 -9
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +465 -36
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
- package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
- package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
- package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
- package/dist/scene/update_queue.js +54 -0
- package/dist/scene/update_queue.js.map +1 -0
- package/dist/scene/water.js +997 -96
- package/dist/scene/water.js.map +1 -1
- package/dist/scene/water_surface_sampler.js +324 -0
- package/dist/scene/water_surface_sampler.js.map +1 -0
- package/dist/scene/wind.js +317 -0
- package/dist/scene/wind.js.map +1 -0
- package/dist/shaders/atmosphere.js +388 -166
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +100 -32
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/gi.js +365 -0
- package/dist/shaders/gi.js.map +1 -0
- package/dist/shaders/ltc_rect.js +202 -0
- package/dist/shaders/ltc_rect.js.map +1 -0
- package/dist/shaders/misc.js +1 -10
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +5 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/probes.js +309 -0
- package/dist/shaders/probes.js.map +1 -0
- package/dist/shaders/sdf.js +537 -0
- package/dist/shaders/sdf.js.map +1 -0
- package/dist/shaders/shadow.js +104 -70
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/skin_brdf.js +243 -0
- package/dist/shaders/skin_brdf.js.map +1 -0
- package/dist/shaders/ssr.js +6 -159
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js +38 -27
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +40 -87
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +42 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +110 -19
- package/dist/shadow/dom.js.map +1 -1
- package/dist/shadow/esm.js +3 -3
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -48
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -53
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +34 -9
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +3 -8
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +87 -49
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +93 -53
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +18 -72
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -3
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/shape.js +44 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/utility/buoyancy.js +287 -0
- package/dist/utility/buoyancy.js.map +1 -0
- package/dist/utility/physical.js +10 -1
- package/dist/utility/physical.js.map +1 -1
- package/dist/utility/pmrem.js +17 -43
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/sdf/bake.js +435 -0
- package/dist/utility/sdf/bake.js.map +1 -0
- package/dist/utility/sdf/bvh.js +576 -0
- package/dist/utility/sdf/bvh.js.map +1 -0
- package/dist/utility/serialization/manager.js +36 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +77 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +11 -4
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +140 -279
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth.js +25 -0
- package/dist/utility/serialization/scene/cloth.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +14 -6
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/foliage.js +821 -0
- package/dist/utility/serialization/scene/foliage.js.map +1 -0
- package/dist/utility/serialization/scene/hair.js +11 -4
- package/dist/utility/serialization/scene/hair.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +115 -7
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +388 -220
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +69 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +140 -5
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/node_physics.js +1318 -0
- package/dist/utility/serialization/scene/node_physics.js.map +1 -0
- package/dist/utility/serialization/scene/particle.js +11 -4
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/physics.js +120 -0
- package/dist/utility/serialization/scene/physics.js.map +1 -0
- package/dist/utility/serialization/scene/primitive.js +124 -10
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +1687 -51
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +11 -4
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +163 -33
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +11 -4
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +2473 -114
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +97 -109
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/foam.js +170 -0
- package/dist/utility/textures/foam.js.map +1 -0
- package/dist/utility/textures/ggxlut.js +17 -43
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +4 -4
- package/dist/utility/textures/ltcdata.js.map +1 -1
- package/dist/utility/textures/ltclut.js +16 -6
- package/dist/utility/textures/ltclut.js.map +1 -1
- package/dist/utility/unsupported.js +24 -0
- package/dist/utility/unsupported.js.map +1 -0
- package/dist/values.js +13 -1
- package/dist/values.js.map +1 -1
- package/package.json +25 -12
- package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- 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":"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"}
|
|
@@ -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:
|
|
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
|
-
|
|
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 =
|
|
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
|
-
/**
|
|
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
|
|
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) :
|
|
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
|
|
586
|
-
const
|
|
587
|
-
|
|
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
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
1049
|
+
warnUnsupported("Deep opacity map shadows (shadow mode 'dom')", 'WebGPU', "falling back to 'pcf'");
|
|
1010
1050
|
this.applyMode('pcf');
|
|
1011
1051
|
return;
|
|
1012
1052
|
}
|