@zephyr3d/scene 0.9.27 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +54 -0
- 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 +279 -55
- 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 +171 -1
- 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 +104 -178
- 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 +25436 -15990
- package/dist/index.js +65 -11
- 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/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +66 -4
- 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 +191 -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 +333 -191
- 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 +1261 -1438
- 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 +106 -106
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +2 -6
- 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 +4 -13
- 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 +3 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +179 -64
- 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 +25 -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 +5 -5
- 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 +5 -10
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +247 -157
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +16 -38
- 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/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +19 -8
- 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/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 +162 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +10 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +14 -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 +272 -55
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +41 -0
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
- 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 +58 -158
- package/dist/render/underwater.js.map +1 -1
- 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 +134 -319
- package/dist/render/water_caustics.js.map +1 -1
- 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 +3 -3
- 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 +633 -268
- 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/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.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 +32 -82
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +7 -21
- package/dist/shaders/water_medium.js.map +1 -1
- 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 +40 -2
- 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 +34 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +46 -5
- 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 +87 -254
- 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 +1543 -264
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +10 -22
- 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
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import { Vector3, Vector4, Vector2, REVERSE_Z, DEPTH_FARTHEST, DEPTH_REDUCE_CLOSER, DEPTH_REDUCE_FARTHER } from '@zephyr3d/base';
|
|
2
|
-
import { RENDER_PASS_TYPE_DEPTH, RENDER_PASS_TYPE_SHADOWMAP, RENDER_PASS_TYPE_OBJECT_COLOR, RENDER_PASS_TYPE_LIGHT, MaterialVaryingFlags,
|
|
2
|
+
import { RENDER_PASS_TYPE_DEPTH, RENDER_PASS_TYPE_SHADOWMAP, RENDER_PASS_TYPE_OBJECT_COLOR, RENDER_PASS_TYPE_VOXELIZE, RENDER_PASS_TYPE_LIGHT, MaterialVaryingFlags, MORPH_WEIGHTS_VECTOR_COUNT, MAX_SKIN_EXTRA_INFLUENCE_PAIRS, MORPH_TARGET_POSITION, MORPH_TARGET_NORMAL, MORPH_TARGET_TANGENT, MORPH_ATTRIBUTE_VECTOR_COUNT, LIGHT_TYPE_DIRECTIONAL } from '../../values.js';
|
|
3
3
|
import { ProgramBuilder } from '@zephyr3d/device';
|
|
4
|
-
import {
|
|
4
|
+
import { linearToGamma } from '../../shaders/misc.js';
|
|
5
|
+
import { declareVoxelizeUniforms } from '../../shaders/gi.js';
|
|
5
6
|
import { getSamplerOptions, fetchSampler } from '../../utility/misc.js';
|
|
6
|
-
import { PHYSICAL_BAKE_EXPOSURE } from '../../utility/physical.js';
|
|
7
|
+
import { getGICacheExposure, PHYSICAL_BAKE_EXPOSURE } from '../../utility/physical.js';
|
|
7
8
|
import { getDevice } from '../../app/api.js';
|
|
8
9
|
import { getDefaultAtmosphereParams, getAtmosphereParamsStruct } from '../../shaders/atmosphere.js';
|
|
9
10
|
import { getDefaultHeightFogParams, getHeightFogParamsStruct, calculateFog } from '../../shaders/fog.js';
|
|
10
11
|
import { getShadowReceiverNoL, getShadowReceiverBiasFactor } from '../../shadow/receiver_bias.js';
|
|
12
|
+
import { declareGlobalSDFUniforms, declareDynamicSDFUniforms, GLOBAL_SDF_TEXTURE, sampleSceneSDF } from '../../shaders/sdf.js';
|
|
11
13
|
|
|
14
|
+
/** Clipmap levels of the scene field declared in a program, by program builder. */ const sceneSDFLevels = new WeakMap();
|
|
12
15
|
const UNIFORM_NAME_LIGHT_BUFFER = 'Z_UniformLightBuffer';
|
|
13
16
|
const UNIFORM_NAME_LIGHT_INDEX_TEXTURE = 'Z_UniformLightIndexTex';
|
|
17
|
+
const UNIFORM_NAME_CLUSTER_GRID = 'Z_ClusterGrid';
|
|
18
|
+
const UNIFORM_NAME_CLUSTER_LIGHT_LIST = 'Z_ClusterLightList';
|
|
14
19
|
const UNIFORM_NAME_BAKED_SKY_MAP = 'Z_UniformBakedSky';
|
|
15
20
|
const UNIFORM_NAME_AERIALPERSPECTIVE_LUT = 'Z_UniformAerialPerspectiveLUT';
|
|
16
21
|
const UNIFORM_NAME_SKYDISTANTLIGHT_LUT = 'Z_UniformSkyDistantLightLUT';
|
|
22
|
+
const UNIFORM_NAME_FOG_SKYLIGHT_CUBEMAP = 'Z_UniformFogSkyLightCubemap';
|
|
17
23
|
const UNIFORM_NAME_SHADOW_MAP = 'Z_UniformShadowMap';
|
|
18
24
|
const UNIFORM_NAME_SHADOW_MASK = 'Z_UniformShadowMask';
|
|
19
25
|
const UNIFORM_NAME_SHADOW_MASK_MODE = 'Z_UniformShadowMaskMode';
|
|
26
|
+
const UNIFORM_NAME_TRANSMISSION_THICKNESS = 'Z_UniformTransmissionThickness';
|
|
20
27
|
const UNIFORM_NAME_CAUSTIC_MAP = 'Z_UniformCausticMap';
|
|
21
28
|
const UNIFORM_NAME_CAUSTIC_HEIGHT_MAP = 'Z_UniformCausticHeightMap';
|
|
22
29
|
/**
|
|
@@ -55,6 +62,7 @@ const UNIFORM_NAME_INSTANCE_DATA_OFFSET = 'Z_UniformInstanceDataOffset';
|
|
|
55
62
|
const UNIFORM_NAME_BONE_MATRICES = 'Z_UniformBoneMatrices';
|
|
56
63
|
const UNIFORM_NAME_BONE_TEXTURE_SIZE = 'Z_UniformBoneTexSize';
|
|
57
64
|
const UNIFORM_NAME_BONE_INV_BIND_MATRIX = 'Z_UniformBoneInvBindMatrix';
|
|
65
|
+
const UNIFORM_NAME_SKIN_PALETTE_BASE = 'Z_UniformSkinPaletteBase';
|
|
58
66
|
const UNIFORM_NAME_SKIN_INFLUENCE_DATA = 'Z_UniformSkinInfluenceData';
|
|
59
67
|
const UNIFORM_NAME_SKIN_INFLUENCE_INFO = 'Z_UniformSkinInfluenceInfo';
|
|
60
68
|
const UNIFORM_NAME_MORPH_DATA = 'Z_UniformMorphData';
|
|
@@ -68,6 +76,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
68
76
|
static MATERIAL_INSTANCE_DATA_OFFSET = 9;
|
|
69
77
|
/** @internal */ static defaultSunDir = Vector3.one().inplaceNormalize();
|
|
70
78
|
/** @internal 1x1x1 fallback bound to the shadow-mask uniform when no mask exists this frame. */ static _dummyShadowMask = null;
|
|
79
|
+
static _dummyTransmissionThickness = null;
|
|
71
80
|
/** @internal */ static SKIN_MATRIX_NAME = 'Z_SkinMatrix';
|
|
72
81
|
static SKIN_PREV_MATRIX_NAME = 'Z_PrevSkinMatrix';
|
|
73
82
|
static SKIN_BONE_OFFSET = 'Z_boneOffset';
|
|
@@ -127,6 +136,9 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
127
136
|
static getBoneInvBindMatrixUniformName() {
|
|
128
137
|
return UNIFORM_NAME_BONE_INV_BIND_MATRIX;
|
|
129
138
|
}
|
|
139
|
+
static getSkinPaletteBaseUniformName() {
|
|
140
|
+
return UNIFORM_NAME_SKIN_PALETTE_BASE;
|
|
141
|
+
}
|
|
130
142
|
static getSkinInfluenceDataUniformName() {
|
|
131
143
|
return UNIFORM_NAME_SKIN_INFLUENCE_DATA;
|
|
132
144
|
}
|
|
@@ -231,8 +243,12 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
231
243
|
if (casterParams) {
|
|
232
244
|
casterParams.impl?.declareCasterUniforms(scope, casterParams);
|
|
233
245
|
}
|
|
234
|
-
} else if (ctx.renderPass.type === RENDER_PASS_TYPE_DEPTH || ctx.renderPass.type === RENDER_PASS_TYPE_OBJECT_COLOR) {
|
|
246
|
+
} else if (ctx.renderPass.type === RENDER_PASS_TYPE_DEPTH || ctx.renderPass.type === RENDER_PASS_TYPE_OBJECT_COLOR || ctx.renderPass.type === RENDER_PASS_TYPE_VOXELIZE) {
|
|
235
247
|
scope.camera = cameraStruct().uniform(0);
|
|
248
|
+
// Write-only storage textures are fragment-only in WebGPU
|
|
249
|
+
if (ctx.renderPass.type === RENDER_PASS_TYPE_VOXELIZE && pb.shaderKind === 'fragment') {
|
|
250
|
+
declareVoxelizeUniforms(scope, 0);
|
|
251
|
+
}
|
|
236
252
|
} else if (ctx.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
|
|
237
253
|
const useClusteredLighting = !ctx.currentShadowLight;
|
|
238
254
|
if (ctx.materialFlags & MaterialVaryingFlags.APPLY_FOG) {
|
|
@@ -248,6 +264,8 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
248
264
|
// Static samplers: LUTs are rgba16f without mipmaps
|
|
249
265
|
scope[UNIFORM_NAME_AERIALPERSPECTIVE_LUT] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_linear_nomip'));
|
|
250
266
|
scope[UNIFORM_NAME_SKYDISTANTLIGHT_LUT] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_linear_nomip'));
|
|
267
|
+
// Mipmapped radiance map, sampled at a roughness-selected LOD
|
|
268
|
+
scope[UNIFORM_NAME_FOG_SKYLIGHT_CUBEMAP] = pb.texCube().uniform(0).withSampler(getSamplerOptions('clamp_linear'));
|
|
251
269
|
}
|
|
252
270
|
const lightStruct = ctx.currentShadowLight ? pb.defineStruct([
|
|
253
271
|
pb.vec3('sunDir'),
|
|
@@ -271,7 +289,12 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
271
289
|
pb.float('envLightSpecularStrength'),
|
|
272
290
|
pb.vec4('clusterParams'),
|
|
273
291
|
pb.ivec4('countParams'),
|
|
292
|
+
// Buffer indices of the lights shaded outside the clusters, zero-terminated.
|
|
293
|
+
pb.ivec4('globalLights'),
|
|
274
294
|
pb.ivec2('lightIndexTexSize'),
|
|
295
|
+
// Nonzero when the clusters were sliced for an orthographic camera
|
|
296
|
+
// (linear depth slices instead of exponential).
|
|
297
|
+
pb.int('clusterOrtho'),
|
|
275
298
|
// Number of shadow-casting lights at the head of the clustered light
|
|
276
299
|
// buffer (indices 1..N). Only present on the screen-space shadow mask
|
|
277
300
|
// path (part of the global bind group hash), so the declared and bound
|
|
@@ -283,9 +306,17 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
283
306
|
scope.camera = cameraStruct().uniform(0);
|
|
284
307
|
scope.light = lightStruct().uniform(0);
|
|
285
308
|
if (useClusteredLighting) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
309
|
+
if (this.usesClusterLightLists()) {
|
|
310
|
+
// Storage buffers sized to the frame's lights: no cap on the lights in total or
|
|
311
|
+
// per cluster. See ClusteredLight for the layout of the grid and the lists.
|
|
312
|
+
scope[UNIFORM_NAME_LIGHT_BUFFER] = pb.vec4[0]().storageBufferReadonly(0);
|
|
313
|
+
scope[UNIFORM_NAME_CLUSTER_GRID] = pb.uint[0]().storageBufferReadonly(0);
|
|
314
|
+
scope[UNIFORM_NAME_CLUSTER_LIGHT_LIST] = pb.uint[0]().storageBufferReadonly(0);
|
|
315
|
+
} else {
|
|
316
|
+
scope[UNIFORM_NAME_LIGHT_BUFFER] = pb.vec4[(this.getMaxClusterLights() + 1) * 4]().uniformBuffer(0);
|
|
317
|
+
// The light index texture is fetched with textureLoad
|
|
318
|
+
scope[UNIFORM_NAME_LIGHT_INDEX_TEXTURE] = pb.utex2D().noSampler().uniform(0);
|
|
319
|
+
}
|
|
289
320
|
// Screen-space shadow mask array (rgba8unorm, 4 shadow lights per layer).
|
|
290
321
|
// Sampled by clustered lights whose buffer index is <= numShadowLights.
|
|
291
322
|
// Presence is keyed into the global bind group hash, so declared and bound
|
|
@@ -298,6 +329,12 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
298
329
|
// e.g. OIT hair, where the opaque-depth mask would be incorrect).
|
|
299
330
|
scope[UNIFORM_NAME_SHADOW_MASK_MODE] = pb.int().uniform(0);
|
|
300
331
|
}
|
|
332
|
+
// Light-space thickness for subsurface transmission, packed exactly like
|
|
333
|
+
// the shadow mask. Presence is keyed into the bind group hash through
|
|
334
|
+
// ctx.transmissionThickness, so declared and bound layouts always agree.
|
|
335
|
+
if (ctx.transmissionThickness) {
|
|
336
|
+
scope[UNIFORM_NAME_TRANSMISSION_THICKNESS] = pb.tex2DArray().uniform(0);
|
|
337
|
+
}
|
|
301
338
|
}
|
|
302
339
|
// Baked sky cube: rgba16f without mipmaps
|
|
303
340
|
scope[UNIFORM_NAME_BAKED_SKY_MAP] = pb.texCube().uniform(0).withSampler(getSamplerOptions('clamp_linear_nomip'));
|
|
@@ -378,75 +415,13 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
378
415
|
if (!this.hasSkinning(scope)) {
|
|
379
416
|
return null;
|
|
380
417
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
pb.func(funcNameGetBoneMatrixFromTexture, [
|
|
386
|
-
pb.int('boneIndex')
|
|
387
|
-
], function() {
|
|
388
|
-
const boneTexture = this[UNIFORM_NAME_BONE_MATRICES];
|
|
389
|
-
this.$l.uvOffsets = pb.textureSampleLevel(boneTexture, pb.div(pb.vec2(0.5), this[UNIFORM_NAME_BONE_TEXTURE_SIZE]), 0);
|
|
390
|
-
this.$l.currentOffset = pb.int(this.uvOffsets.x);
|
|
391
|
-
this.$l.w = this[UNIFORM_NAME_BONE_TEXTURE_SIZE].x;
|
|
392
|
-
this.$l.pixelIndex = pb.float(pb.mul(pb.add(this.boneIndex, this.currentOffset), 4));
|
|
393
|
-
this.$l.xIndex = pb.mod(this.pixelIndex, this.w);
|
|
394
|
-
this.$l.yIndex = pb.floor(pb.div(this.pixelIndex, this.w));
|
|
395
|
-
this.$l.u1 = pb.div(pb.add(this.xIndex, 0.5), this.w);
|
|
396
|
-
this.$l.u2 = pb.div(pb.add(this.xIndex, 1.5), this.w);
|
|
397
|
-
this.$l.u3 = pb.div(pb.add(this.xIndex, 2.5), this.w);
|
|
398
|
-
this.$l.u4 = pb.div(pb.add(this.xIndex, 3.5), this.w);
|
|
399
|
-
this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.w);
|
|
400
|
-
this.$l.row1 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u1, this.v), 0);
|
|
401
|
-
this.$l.row2 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u2, this.v), 0);
|
|
402
|
-
this.$l.row3 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u3, this.v), 0);
|
|
403
|
-
this.$l.row4 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u4, this.v), 0);
|
|
404
|
-
this.$return(pb.mat4(this.row1, this.row2, this.row3, this.row4));
|
|
405
|
-
});
|
|
406
|
-
const funcNameGetSkinningMatrix = 'Z_getSkinningMatrix';
|
|
407
|
-
pb.func(funcNameGetSkinningMatrix, [], function() {
|
|
408
|
-
const invBindMatrix = this[UNIFORM_NAME_BONE_INV_BIND_MATRIX];
|
|
409
|
-
const blendIndices = scope.$getVertexAttrib('blendIndices');
|
|
410
|
-
const blendWeights = scope.$getVertexAttrib('blendWeights');
|
|
411
|
-
this.$l.m0 = scope.$g[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[0]));
|
|
412
|
-
this.$l.m1 = scope.$g[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[1]));
|
|
413
|
-
this.$l.m2 = scope.$g[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[2]));
|
|
414
|
-
this.$l.m3 = scope.$g[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[3]));
|
|
415
|
-
this.$l.m = pb.add(pb.mul(this.m0, blendWeights.x), pb.mul(this.m1, blendWeights.y), pb.mul(this.m2, blendWeights.z), pb.mul(this.m3, blendWeights.w));
|
|
416
|
-
this.$l.skinInfo = this[UNIFORM_NAME_SKIN_INFLUENCE_INFO];
|
|
417
|
-
this.$if(pb.greaterThan(this.skinInfo.z, 4), function() {
|
|
418
|
-
this.$l.vertexIndex = isWebGL ? pb.int(scope.$inputs.zFakeVertexID) : pb.int(scope.$builtins.vertexIndex);
|
|
419
|
-
this.$l.texWidth = pb.int(this.skinInfo.x);
|
|
420
|
-
this.$l.pairCount = pb.int(this.skinInfo.w);
|
|
421
|
-
this.$for(pb.int('pairIndex'), 0, MAX_SKIN_EXTRA_INFLUENCE_PAIRS, function() {
|
|
422
|
-
this.$if(pb.greaterThanEqual(this.pairIndex, this.pairCount), function() {
|
|
423
|
-
this.$break();
|
|
424
|
-
});
|
|
425
|
-
this.$l.pixelIndex = pb.add(pb.mul(this.vertexIndex, this.pairCount), this.pairIndex);
|
|
426
|
-
this.$l.xIndex = pb.mod(this.pixelIndex, this.texWidth);
|
|
427
|
-
this.$l.yIndex = pb.div(this.pixelIndex, this.texWidth);
|
|
428
|
-
if (supportsTextureLoad) {
|
|
429
|
-
this.$l.extra = pb.textureLoad(this[UNIFORM_NAME_SKIN_INFLUENCE_DATA], pb.ivec2(this.xIndex, this.yIndex), 0);
|
|
430
|
-
} else {
|
|
431
|
-
this.$l.u = pb.div(pb.add(pb.float(this.xIndex), 0.5), this.skinInfo.x);
|
|
432
|
-
this.$l.v = pb.div(pb.add(pb.float(this.yIndex), 0.5), this.skinInfo.y);
|
|
433
|
-
this.$l.extra = pb.textureSampleLevel(this[UNIFORM_NAME_SKIN_INFLUENCE_DATA], pb.vec2(this.u, this.v), 0);
|
|
434
|
-
}
|
|
435
|
-
this.$if(pb.greaterThan(this.extra.y, 0), function() {
|
|
436
|
-
this.m = pb.add(this.m, pb.mul(scope.$g[funcNameGetBoneMatrixFromTexture](pb.int(this.extra.x)), this.extra.y));
|
|
437
|
-
});
|
|
438
|
-
this.$if(pb.greaterThan(this.extra.w, 0), function() {
|
|
439
|
-
this.m = pb.add(this.m, pb.mul(scope.$g[funcNameGetBoneMatrixFromTexture](pb.int(this.extra.z)), this.extra.w));
|
|
440
|
-
});
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
this.$return(pb.mul(invBindMatrix, this.m));
|
|
444
|
-
});
|
|
445
|
-
return scope.$g[funcNameGetSkinningMatrix]();
|
|
418
|
+
if (!scope[this.SKIN_MATRIX_NAME]) {
|
|
419
|
+
this.prepareSkinAnimation(scope);
|
|
420
|
+
}
|
|
421
|
+
return scope[this.SKIN_MATRIX_NAME];
|
|
446
422
|
}
|
|
447
423
|
static calculateMorphDelta(scope, attrib) {
|
|
448
424
|
const pb = scope.$builder;
|
|
449
|
-
const isWebGL1 = pb.getDevice().type === 'webgl';
|
|
450
425
|
if (pb.shaderKind !== 'vertex') {
|
|
451
426
|
throw new Error(`ShaderHelper.calculateMorphDelta(): must be called at vertex stage`);
|
|
452
427
|
}
|
|
@@ -458,7 +433,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
458
433
|
this.$if(pb.lessThan(this.offset, 0), function() {
|
|
459
434
|
this.$return(pb.vec4(0));
|
|
460
435
|
});
|
|
461
|
-
this.$l.vertexIndex =
|
|
436
|
+
this.$l.vertexIndex = pb.int(scope.$builtins.vertexIndex);
|
|
462
437
|
const morphInfo = scope[that.getMorphInfoUniformName()];
|
|
463
438
|
this.$l.metaData = pb.ivec4(morphInfo[0]);
|
|
464
439
|
this.$l.texWidth = pb.float(this.metaData.x);
|
|
@@ -466,43 +441,21 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
466
441
|
this.$l.numVertices = this.metaData.z;
|
|
467
442
|
this.$l.numTargets = this.metaData.w;
|
|
468
443
|
this.$l.value = pb.vec4(0);
|
|
469
|
-
|
|
470
|
-
this.$
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
this.$l.u = pb.div(pb.add(this.xIndex, 0.5), this.texWidth);
|
|
483
|
-
this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.texHeight);
|
|
484
|
-
this.$l.morphValue = pb.textureSampleLevel(this[that.getMorphDataUniformName()], pb.vec2(this.u, this.v), 0);
|
|
485
|
-
this.value = pb.add(this.value, pb.mul(this.morphValue, this.weight));
|
|
486
|
-
});
|
|
487
|
-
});
|
|
488
|
-
});
|
|
489
|
-
} else {
|
|
490
|
-
this.$for(pb.int('t'), 0, this.numTargets, function() {
|
|
491
|
-
this.$l.i = pb.sar(this.t, 2);
|
|
492
|
-
this.$l.j = pb.compAnd(this.t, 3);
|
|
493
|
-
this.$l.weight = morphInfo.at(pb.add(1, this.i)).at(this.j);
|
|
494
|
-
this.$if(pb.notEqual(this.weight, 0), function() {
|
|
495
|
-
this.$l.targetIndex = pb.int(morphInfo.at(pb.add(1 + MORPH_WEIGHTS_VECTOR_COUNT, this.i)).at(this.j));
|
|
496
|
-
this.$l.pixelIndex = pb.float(pb.add(this.offset, pb.mul(this.targetIndex, this.numVertices), this.vertexIndex));
|
|
497
|
-
this.$l.xIndex = pb.mod(this.pixelIndex, this.texWidth);
|
|
498
|
-
this.$l.yIndex = pb.floor(pb.div(this.pixelIndex, this.texWidth));
|
|
499
|
-
this.$l.u = pb.div(pb.add(this.xIndex, 0.5), this.texWidth);
|
|
500
|
-
this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.texHeight);
|
|
501
|
-
this.$l.morphValue = pb.textureSampleLevel(this[that.getMorphDataUniformName()], pb.vec2(this.u, this.v), 0);
|
|
502
|
-
this.value = pb.add(this.value, pb.mul(this.morphValue, this.weight));
|
|
503
|
-
});
|
|
444
|
+
this.$for(pb.int('t'), 0, this.numTargets, function() {
|
|
445
|
+
this.$l.i = pb.sar(this.t, 2);
|
|
446
|
+
this.$l.j = pb.compAnd(this.t, 3);
|
|
447
|
+
this.$l.weight = morphInfo.at(pb.add(1, this.i)).at(this.j);
|
|
448
|
+
this.$if(pb.notEqual(this.weight, 0), function() {
|
|
449
|
+
this.$l.targetIndex = pb.int(morphInfo.at(pb.add(1 + MORPH_WEIGHTS_VECTOR_COUNT, this.i)).at(this.j));
|
|
450
|
+
this.$l.pixelIndex = pb.float(pb.add(this.offset, pb.mul(this.targetIndex, this.numVertices), this.vertexIndex));
|
|
451
|
+
this.$l.xIndex = pb.mod(this.pixelIndex, this.texWidth);
|
|
452
|
+
this.$l.yIndex = pb.floor(pb.div(this.pixelIndex, this.texWidth));
|
|
453
|
+
this.$l.u = pb.div(pb.add(this.xIndex, 0.5), this.texWidth);
|
|
454
|
+
this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.texHeight);
|
|
455
|
+
this.$l.morphValue = pb.textureSampleLevel(this[that.getMorphDataUniformName()], pb.vec2(this.u, this.v), 0);
|
|
456
|
+
this.value = pb.add(this.value, pb.mul(this.morphValue, this.weight));
|
|
504
457
|
});
|
|
505
|
-
}
|
|
458
|
+
});
|
|
506
459
|
this.$return(this.value);
|
|
507
460
|
});
|
|
508
461
|
const pos = 1 + MORPH_WEIGHTS_VECTOR_COUNT * 2 + (attrib >> 2);
|
|
@@ -549,7 +502,6 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
549
502
|
* @internal
|
|
550
503
|
*/ static calculateMorphDirectionByDisplacement(scope, base, attrib) {
|
|
551
504
|
const pb = scope.$builder;
|
|
552
|
-
const isWebGL1 = pb.getDevice().type === 'webgl';
|
|
553
505
|
if (pb.shaderKind !== 'vertex') {
|
|
554
506
|
throw new Error(`ShaderHelper.calculateMorphDirectionByDisplacement(): must be called at vertex stage`);
|
|
555
507
|
}
|
|
@@ -561,7 +513,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
561
513
|
pb.int('directionOffset'),
|
|
562
514
|
pb.int('positionOffset')
|
|
563
515
|
], function() {
|
|
564
|
-
this.$l.vertexIndex =
|
|
516
|
+
this.$l.vertexIndex = pb.int(scope.$builtins.vertexIndex);
|
|
565
517
|
const morphInfo = scope[that.getMorphInfoUniformName()];
|
|
566
518
|
this.$l.metaData = pb.ivec4(morphInfo[0]);
|
|
567
519
|
this.$l.texWidth = pb.float(this.metaData.x);
|
|
@@ -599,27 +551,13 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
599
551
|
this.weightSum = pb.add(this.weightSum, this.displacementWeight);
|
|
600
552
|
});
|
|
601
553
|
};
|
|
602
|
-
|
|
603
|
-
this.$
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
this.$l.weight = morphInfo.at(pb.add(1, this.i)).at(this.j);
|
|
610
|
-
this.$l.targetIndex = pb.int(morphInfo.at(pb.add(1 + MORPH_WEIGHTS_VECTOR_COUNT, this.i)).at(this.j));
|
|
611
|
-
accumulateTarget(this);
|
|
612
|
-
});
|
|
613
|
-
});
|
|
614
|
-
} else {
|
|
615
|
-
this.$for(pb.int('t'), 0, this.numTargets, function() {
|
|
616
|
-
this.$l.i = pb.sar(this.t, 2);
|
|
617
|
-
this.$l.j = pb.compAnd(this.t, 3);
|
|
618
|
-
this.$l.weight = morphInfo.at(pb.add(1, this.i)).at(this.j);
|
|
619
|
-
this.$l.targetIndex = pb.int(morphInfo.at(pb.add(1 + MORPH_WEIGHTS_VECTOR_COUNT, this.i)).at(this.j));
|
|
620
|
-
accumulateTarget(this);
|
|
621
|
-
});
|
|
622
|
-
}
|
|
554
|
+
this.$for(pb.int('t'), 0, this.numTargets, function() {
|
|
555
|
+
this.$l.i = pb.sar(this.t, 2);
|
|
556
|
+
this.$l.j = pb.compAnd(this.t, 3);
|
|
557
|
+
this.$l.weight = morphInfo.at(pb.add(1, this.i)).at(this.j);
|
|
558
|
+
this.$l.targetIndex = pb.int(morphInfo.at(pb.add(1 + MORPH_WEIGHTS_VECTOR_COUNT, this.i)).at(this.j));
|
|
559
|
+
accumulateTarget(this);
|
|
560
|
+
});
|
|
623
561
|
this.$l.fallback = scope.$g[normalizeName](this.base, this.directionDelta);
|
|
624
562
|
this.$if(pb.lessThan(this.weightSum, 1e-6), function() {
|
|
625
563
|
this.$return(this.fallback);
|
|
@@ -663,8 +601,6 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
663
601
|
}
|
|
664
602
|
const that = this;
|
|
665
603
|
const pb = scope.$builder;
|
|
666
|
-
const isWebGL = pb.getDevice().type === 'webgl';
|
|
667
|
-
const supportsTextureLoad = !isWebGL;
|
|
668
604
|
const funcNameGetBoneMatrixFromTexture = 'Z_getBoneMatrixFromTexture';
|
|
669
605
|
pb.func(funcNameGetBoneMatrixFromTexture, [
|
|
670
606
|
pb.float('boneIndex'),
|
|
@@ -672,6 +608,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
672
608
|
], function() {
|
|
673
609
|
const boneTexture = this[UNIFORM_NAME_BONE_MATRICES];
|
|
674
610
|
this.$l.w = this[UNIFORM_NAME_BONE_TEXTURE_SIZE].x;
|
|
611
|
+
this.$l.h = this[UNIFORM_NAME_BONE_TEXTURE_SIZE].y;
|
|
675
612
|
this.$l.pixelIndex = pb.mul(pb.add(this.boneIndex, this.boneOffset), 4);
|
|
676
613
|
this.$l.xIndex = pb.mod(this.pixelIndex, this.w);
|
|
677
614
|
this.$l.yIndex = pb.floor(pb.div(this.pixelIndex, this.w));
|
|
@@ -679,7 +616,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
679
616
|
this.$l.u2 = pb.div(pb.add(this.xIndex, 1.5), this.w);
|
|
680
617
|
this.$l.u3 = pb.div(pb.add(this.xIndex, 2.5), this.w);
|
|
681
618
|
this.$l.u4 = pb.div(pb.add(this.xIndex, 3.5), this.w);
|
|
682
|
-
this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.
|
|
619
|
+
this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.h);
|
|
683
620
|
this.$l.row1 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u1, this.v), 0);
|
|
684
621
|
this.$l.row2 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u2, this.v), 0);
|
|
685
622
|
this.$l.row3 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u3, this.v), 0);
|
|
@@ -700,7 +637,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
700
637
|
this.$l.m = pb.add(pb.mul(this.m0, blendWeights.x), pb.mul(this.m1, blendWeights.y), pb.mul(this.m2, blendWeights.z), pb.mul(this.m3, blendWeights.w));
|
|
701
638
|
this.$l.skinInfo = this[UNIFORM_NAME_SKIN_INFLUENCE_INFO];
|
|
702
639
|
this.$if(pb.greaterThan(this.skinInfo.z, 4), function() {
|
|
703
|
-
this.$l.vertexIndex =
|
|
640
|
+
this.$l.vertexIndex = pb.int(scope.$builtins.vertexIndex);
|
|
704
641
|
this.$l.texWidth = pb.int(this.skinInfo.x);
|
|
705
642
|
this.$l.pairCount = pb.int(this.skinInfo.w);
|
|
706
643
|
this.$for(pb.int('pairIndex'), 0, MAX_SKIN_EXTRA_INFLUENCE_PAIRS, function() {
|
|
@@ -710,13 +647,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
710
647
|
this.$l.pixelIndex = pb.add(pb.mul(this.vertexIndex, this.pairCount), this.pairIndex);
|
|
711
648
|
this.$l.xIndex = pb.mod(this.pixelIndex, this.texWidth);
|
|
712
649
|
this.$l.yIndex = pb.div(this.pixelIndex, this.texWidth);
|
|
713
|
-
|
|
714
|
-
this.$l.extra = pb.textureLoad(this[UNIFORM_NAME_SKIN_INFLUENCE_DATA], pb.ivec2(this.xIndex, this.yIndex), 0);
|
|
715
|
-
} else {
|
|
716
|
-
this.$l.u = pb.div(pb.add(pb.float(this.xIndex), 0.5), this.skinInfo.x);
|
|
717
|
-
this.$l.v = pb.div(pb.add(pb.float(this.yIndex), 0.5), this.skinInfo.y);
|
|
718
|
-
this.$l.extra = pb.textureSampleLevel(this[UNIFORM_NAME_SKIN_INFLUENCE_DATA], pb.vec2(this.u, this.v), 0);
|
|
719
|
-
}
|
|
650
|
+
this.$l.extra = pb.textureLoad(this[UNIFORM_NAME_SKIN_INFLUENCE_DATA], pb.ivec2(this.xIndex, this.yIndex), 0);
|
|
720
651
|
this.$if(pb.greaterThan(this.extra.y, 0), function() {
|
|
721
652
|
this.m = pb.add(this.m, pb.mul(scope.$g[funcNameGetBoneMatrixFromTexture](this.extra.x, this.boneOffset), this.extra.y));
|
|
722
653
|
});
|
|
@@ -728,8 +659,12 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
728
659
|
this.$return(pb.mul(invBindMatrix, this.m));
|
|
729
660
|
});
|
|
730
661
|
const motionVector = !!this.getUnjitteredViewProjectionMatrix(scope);
|
|
662
|
+
// The palette header slot holds the slot indices of the current and previous matrix sets
|
|
731
663
|
const boneTexture = scope[UNIFORM_NAME_BONE_MATRICES];
|
|
732
|
-
scope
|
|
664
|
+
const paletteBase = scope[UNIFORM_NAME_SKIN_PALETTE_BASE] ?? this.getInstancedUniform(scope, 4).z;
|
|
665
|
+
const boneTextureSize = scope[UNIFORM_NAME_BONE_TEXTURE_SIZE];
|
|
666
|
+
scope.$l.Z_skinHeaderTexel = pb.mul(paletteBase, 4);
|
|
667
|
+
scope.$l[that.SKIN_BONE_OFFSET] = pb.textureSampleLevel(boneTexture, pb.div(pb.add(pb.vec2(pb.mod(scope.Z_skinHeaderTexel, boneTextureSize.x), pb.floor(pb.div(scope.Z_skinHeaderTexel, boneTextureSize.x))), pb.vec2(0.5)), boneTextureSize), 0).xy;
|
|
733
668
|
scope.$l[that.SKIN_MATRIX_NAME] = scope[funcNameGetSkinningMatrix](scope[that.SKIN_BONE_OFFSET].x);
|
|
734
669
|
if (motionVector) {
|
|
735
670
|
scope.$l[that.SKIN_PREV_MATRIX_NAME] = scope[funcNameGetSkinningMatrix](scope[that.SKIN_BONE_OFFSET].y);
|
|
@@ -964,6 +899,9 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
964
899
|
scope[UNIFORM_NAME_BONE_MATRICES] = pb.tex2D().uniform(1).sampleType('unfilterable-float');
|
|
965
900
|
scope[UNIFORM_NAME_BONE_INV_BIND_MATRIX] = pb.mat4().uniform(1);
|
|
966
901
|
scope[UNIFORM_NAME_BONE_TEXTURE_SIZE] = pb.vec2().uniform(1);
|
|
902
|
+
if (!instanced) {
|
|
903
|
+
scope[UNIFORM_NAME_SKIN_PALETTE_BASE] = pb.float().uniform(1);
|
|
904
|
+
}
|
|
967
905
|
scope[UNIFORM_NAME_SKIN_INFLUENCE_DATA] = pb.tex2D().uniform(1).sampleType('unfilterable-float');
|
|
968
906
|
scope[UNIFORM_NAME_SKIN_INFLUENCE_INFO] = pb.vec4().uniform(1);
|
|
969
907
|
}
|
|
@@ -977,7 +915,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
977
915
|
}
|
|
978
916
|
/** @internal */ static setCameraUniforms(bindGroup, ctx, camera, linear) {
|
|
979
917
|
const pos = camera.getWorldPosition();
|
|
980
|
-
const useJitter = ctx.motionVectors && ctx.renderPass.type !== RENDER_PASS_TYPE_SHADOWMAP && ctx.renderPass.type !== RENDER_PASS_TYPE_OBJECT_COLOR;
|
|
918
|
+
const useJitter = ctx.motionVectors && ctx.renderPass.type !== RENDER_PASS_TYPE_SHADOWMAP && ctx.renderPass.type !== RENDER_PASS_TYPE_OBJECT_COLOR && ctx.renderPass.type !== RENDER_PASS_TYPE_VOXELIZE;
|
|
981
919
|
const cameraStruct = {
|
|
982
920
|
position: new Vector4(pos.x, pos.y, pos.z, 0),
|
|
983
921
|
renderSize: new Vector2(ctx.renderWidth, ctx.renderHeight),
|
|
@@ -1026,12 +964,14 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1026
964
|
viewMatrix: light.viewMatrix,
|
|
1027
965
|
depthBias: shadowMapParams.depthBiasValues[0],
|
|
1028
966
|
implParams: shadowMapParams.impl.getParams(this._lightUniformShadow.implParams),
|
|
1029
|
-
|
|
967
|
+
// The shadow projection, not the light's own type: a rect light renders a point light's
|
|
968
|
+
// cube, so its casters must write the point light's radial depth.
|
|
969
|
+
lightType: shadowMapParams.lightType
|
|
1030
970
|
});
|
|
1031
971
|
shadowMapParams.impl?.applyCasterUniforms(bindGroup, shadowMapParams);
|
|
1032
972
|
}
|
|
1033
973
|
}
|
|
1034
|
-
/** @internal */ static setFogUniforms(bindGroup, withAerialPerspective, fogType, additive, atmosphereParams, heightFogParams, aerialPerspectiveLUT, skyDistantLightLUT) {
|
|
974
|
+
/** @internal */ static setFogUniforms(bindGroup, withAerialPerspective, fogType, additive, atmosphereParams, heightFogParams, aerialPerspectiveLUT, skyDistantLightLUT, skyLightCubemap) {
|
|
1035
975
|
this._fogUniforms.withAerialPerspective = withAerialPerspective;
|
|
1036
976
|
this._fogUniforms.fogType = fogType;
|
|
1037
977
|
this._fogUniforms.additive = additive;
|
|
@@ -1040,6 +980,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1040
980
|
bindGroup.setValue('fog', this._fogUniforms);
|
|
1041
981
|
bindGroup.setTexture(UNIFORM_NAME_AERIALPERSPECTIVE_LUT, aerialPerspectiveLUT);
|
|
1042
982
|
bindGroup.setTexture(UNIFORM_NAME_SKYDISTANTLIGHT_LUT, skyDistantLightLUT);
|
|
983
|
+
bindGroup.setTexture(UNIFORM_NAME_FOG_SKYLIGHT_CUBEMAP, skyLightCubemap);
|
|
1043
984
|
}
|
|
1044
985
|
/**
|
|
1045
986
|
* @internal
|
|
@@ -1053,6 +994,10 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1053
994
|
* quantity on the CPU so the HDR target stays near 1.0 and downstream passes need no unit
|
|
1054
995
|
* awareness. Legacy returns 1 so its uploads stay byte-identical.
|
|
1055
996
|
*/ static getPreExposure(ctx) {
|
|
997
|
+
// The voxelize pass writes the global illumination's caches, kept at a fixed exposure
|
|
998
|
+
if (ctx.renderPass?.type === RENDER_PASS_TYPE_VOXELIZE) {
|
|
999
|
+
return getGICacheExposure(ctx.scene.lightingMode);
|
|
1000
|
+
}
|
|
1056
1001
|
return ctx.scene.lightingMode === 'physical' ? ctx.camera.exposure : 1;
|
|
1057
1002
|
}
|
|
1058
1003
|
/**
|
|
@@ -1100,24 +1045,29 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1100
1045
|
const strength = env.light.strength ?? 0;
|
|
1101
1046
|
return ctx.scene.lightingMode === 'physical' ? this.getPreExposure(ctx) / PHYSICAL_BAKE_EXPOSURE * strength : strength;
|
|
1102
1047
|
}
|
|
1103
|
-
/** @internal */ static setLightUniforms(bindGroup, ctx,
|
|
1048
|
+
/** @internal */ static setLightUniforms(bindGroup, ctx, clusteredLight) {
|
|
1104
1049
|
const envLightStrength = this.getEnvLightLuminance(ctx);
|
|
1050
|
+
const lightIndexTexture = clusteredLight.lightIndexTexture;
|
|
1105
1051
|
bindGroup.setValue('light', {
|
|
1106
1052
|
sunDir: ctx.sunLight ? ctx.sunLight.directionAndCutoff.xyz().scaleBy(-1) : this.defaultSunDir,
|
|
1107
|
-
clusterParams:
|
|
1108
|
-
countParams:
|
|
1053
|
+
clusterParams: clusteredLight.clusterParam,
|
|
1054
|
+
countParams: clusteredLight.countParam,
|
|
1055
|
+
globalLights: clusteredLight.globalLights,
|
|
1109
1056
|
envLightStrength,
|
|
1110
1057
|
envLightSpecularStrength: ctx.env.light.specularStrength ?? 1,
|
|
1111
|
-
lightIndexTexSize:
|
|
1112
|
-
|
|
1113
|
-
lightIndexTexture.height
|
|
1114
|
-
]),
|
|
1058
|
+
lightIndexTexSize: clusteredLight.lightIndexTexSize,
|
|
1059
|
+
clusterOrtho: clusteredLight.orthographic ? 1 : 0,
|
|
1115
1060
|
...ctx.screenSpaceShadowMask ? {
|
|
1116
|
-
numShadowLights:
|
|
1061
|
+
numShadowLights: clusteredLight.numShadowLights
|
|
1117
1062
|
} : {}
|
|
1118
1063
|
});
|
|
1119
|
-
bindGroup.setBuffer(UNIFORM_NAME_LIGHT_BUFFER, lightBuffer);
|
|
1120
|
-
|
|
1064
|
+
bindGroup.setBuffer(UNIFORM_NAME_LIGHT_BUFFER, clusteredLight.lightBuffer);
|
|
1065
|
+
if (this.usesClusterLightLists()) {
|
|
1066
|
+
bindGroup.setBuffer(UNIFORM_NAME_CLUSTER_GRID, clusteredLight.clusterGridBuffer);
|
|
1067
|
+
bindGroup.setBuffer(UNIFORM_NAME_CLUSTER_LIGHT_LIST, clusteredLight.lightListBuffer);
|
|
1068
|
+
} else {
|
|
1069
|
+
bindGroup.setTexture(UNIFORM_NAME_LIGHT_INDEX_TEXTURE, lightIndexTexture);
|
|
1070
|
+
}
|
|
1121
1071
|
if (ctx.screenSpaceShadowMask) {
|
|
1122
1072
|
// The mask array is declared for the clustered light pass whenever the flag is
|
|
1123
1073
|
// on (keyed into the global bind group hash). When there are no shadow lights
|
|
@@ -1125,6 +1075,11 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1125
1075
|
// be bound: fall back to a 1x1 dummy.
|
|
1126
1076
|
bindGroup.setTexture(UNIFORM_NAME_SHADOW_MASK, ctx.shadowMaskTexture ?? this.getDummyShadowMask(ctx.device), fetchSampler('clamp_nearest'));
|
|
1127
1077
|
}
|
|
1078
|
+
if (ctx.transmissionThickness) {
|
|
1079
|
+
// Falls back to a white dummy, not the shadow mask's zero one: 0 encodes
|
|
1080
|
+
// maximum optical depth here, which would read as full transmission.
|
|
1081
|
+
bindGroup.setTexture(UNIFORM_NAME_TRANSMISSION_THICKNESS, ctx.transmissionThicknessTexture ?? this.getDummyTransmissionThickness(ctx.device), fetchSampler('clamp_nearest'));
|
|
1082
|
+
}
|
|
1128
1083
|
bindGroup.setTexture(UNIFORM_NAME_BAKED_SKY_MAP, ctx.scene.env.sky.getBakedSkyTexture(ctx));
|
|
1129
1084
|
if (this.usesWaterCaustics(ctx)) {
|
|
1130
1085
|
this.setWaterCausticUniforms(bindGroup, ctx);
|
|
@@ -1153,7 +1108,62 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1153
1108
|
* @param ctx - Current draw context.
|
|
1154
1109
|
* @returns True when the caustic uniforms take part in this pass.
|
|
1155
1110
|
* @internal
|
|
1156
|
-
*/
|
|
1111
|
+
*/ /**
|
|
1112
|
+
* The scene's signed distance field as light-pass materials see it, or null
|
|
1113
|
+
* when it is off or cannot be built (WebGL2). Part of the light pass's global
|
|
1114
|
+
* bind group and shader variant hashes.
|
|
1115
|
+
* @internal
|
|
1116
|
+
*/ static getSceneSDF(ctx) {
|
|
1117
|
+
if (ctx.renderPass?.type !== RENDER_PASS_TYPE_LIGHT || !ctx.scene?.sdf.enabled) {
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
return ctx.scene.sdf.global;
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Declares the scene signed distance field in a material's bind group, when
|
|
1124
|
+
* the scene has one for this draw ({@link ShaderHelper.getSceneSDF}).
|
|
1125
|
+
* Opt-in per material, so the textures it binds only count against the
|
|
1126
|
+
* shaders that read them. Bind it with {@link ShaderHelper.applySceneSDF}.
|
|
1127
|
+
*
|
|
1128
|
+
* @returns Whether it was declared; without it, fall back to something else.
|
|
1129
|
+
*/ static declareSceneSDF(scope, ctx, group) {
|
|
1130
|
+
const sdf = this.getSceneSDF(ctx);
|
|
1131
|
+
if (!sdf) {
|
|
1132
|
+
return false;
|
|
1133
|
+
}
|
|
1134
|
+
declareGlobalSDFUniforms(scope, group, sdf.levels);
|
|
1135
|
+
declareDynamicSDFUniforms(scope, group);
|
|
1136
|
+
sceneSDFLevels.set(scope.$builder, sdf.levels);
|
|
1137
|
+
return true;
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Binds what {@link ShaderHelper.declareSceneSDF} declared. The values change
|
|
1141
|
+
* every frame (the clipmap follows the camera, dynamic meshes move), so call
|
|
1142
|
+
* it from `applyUniforms` on every draw, not from `applyUniformValues`, which
|
|
1143
|
+
* only runs when the material itself changed.
|
|
1144
|
+
*/ static applySceneSDF(bindGroup, ctx) {
|
|
1145
|
+
this.getSceneSDF(ctx)?.applyBindGroup(bindGroup);
|
|
1146
|
+
}
|
|
1147
|
+
/** Whether {@link ShaderHelper.declareSceneSDF} declared the field in this program. */ static hasSceneSDF(scope) {
|
|
1148
|
+
return !!scope[GLOBAL_SDF_TEXTURE];
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Signed distance in world units from a world position to the scene's
|
|
1152
|
+
* geometry: static meshes and terrain from the global clipmap, merged with
|
|
1153
|
+
* the nearest dynamic meshes at their current transforms. Negative inside.
|
|
1154
|
+
* Only valid when {@link ShaderHelper.hasSceneSDF} is true.
|
|
1155
|
+
*
|
|
1156
|
+
* Near surfaces the value is accurate to a fraction of the finest voxel
|
|
1157
|
+
* (0.25 m by default); farther away it is a lower bound clamped to a few
|
|
1158
|
+
* voxels of the level covering the point, safe for sphere tracing.
|
|
1159
|
+
*/ static sampleSceneSDF(scope, worldPos) {
|
|
1160
|
+
const levels = sceneSDFLevels.get(scope.$builder);
|
|
1161
|
+
if (!levels) {
|
|
1162
|
+
throw new Error('ShaderHelper.sampleSceneSDF(): the scene SDF is not bound in this program');
|
|
1163
|
+
}
|
|
1164
|
+
return sampleSceneSDF(scope, worldPos, levels);
|
|
1165
|
+
}
|
|
1166
|
+
static usesWaterCaustics(ctx) {
|
|
1157
1167
|
return !!ctx.waterCaustics && !!ctx.waterCausticLight && ctx.renderPass.type === RENDER_PASS_TYPE_LIGHT;
|
|
1158
1168
|
}
|
|
1159
1169
|
/**
|
|
@@ -1425,7 +1435,13 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1425
1435
|
// else in the column.
|
|
1426
1436
|
this.$l.defocus = pb.float(1);
|
|
1427
1437
|
}
|
|
1428
|
-
|
|
1438
|
+
// None in water shallower than the minimum depth, faded in across it:
|
|
1439
|
+
// where the water thins out on a beach the surface is too coarse to
|
|
1440
|
+
// say where the water ends, and the pattern there would come from
|
|
1441
|
+
// photons that never reached it
|
|
1442
|
+
this.$l.minDepth = this.cu.extinction.x;
|
|
1443
|
+
this.$l.shallow = pb.smoothStep(pb.mul(this.minDepth, 0.5), pb.add(pb.mul(this.minDepth, 1.5), 1e-4), this.depth);
|
|
1444
|
+
this.$l.weight = pb.mul(this.cu.params.x, this.defocus, this.edge, this.shallow);
|
|
1429
1445
|
this.$l.caustic = pb.add(1, pb.mul(pb.sub(this.pattern, 1), this.weight));
|
|
1430
1446
|
// Soften the waterline so the transmittance does not switch on abruptly.
|
|
1431
1447
|
this.$l.submerged = pb.smoothStep(0, 0.05, this.depth);
|
|
@@ -1625,11 +1641,12 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1625
1641
|
* would animate out of step with the surface they are refracted through.
|
|
1626
1642
|
*
|
|
1627
1643
|
* @param bindGroup - Bind group of the standalone program.
|
|
1628
|
-
* @param ctx - Current draw context
|
|
1644
|
+
* @param ctx - Current draw context; the current device when omitted, for
|
|
1645
|
+
* a program run outside drawing.
|
|
1629
1646
|
* @internal
|
|
1630
1647
|
*/ static setStandaloneCameraTime(bindGroup, ctx) {
|
|
1631
1648
|
bindGroup.setValue('camera', {
|
|
1632
|
-
elapsedTime: ctx
|
|
1649
|
+
elapsedTime: (ctx?.device ?? getDevice()).frameInfo.elapsedOverall * 0.001,
|
|
1633
1650
|
_pad0: 0,
|
|
1634
1651
|
_pad1: 0,
|
|
1635
1652
|
_pad2: 0
|
|
@@ -1698,6 +1715,20 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1698
1715
|
return scope.light.countParams;
|
|
1699
1716
|
}
|
|
1700
1717
|
/**
|
|
1718
|
+
* Buffer indices of the clustered lights every fragment shades regardless of its
|
|
1719
|
+
* cluster, zero-terminated.
|
|
1720
|
+
* @internal
|
|
1721
|
+
*/ static getGlobalLights(scope) {
|
|
1722
|
+
return scope.light.globalLights;
|
|
1723
|
+
}
|
|
1724
|
+
/**
|
|
1725
|
+
* Nonzero when the clusters were sliced for an orthographic camera: depth slices
|
|
1726
|
+
* are then linear in view depth rather than exponential.
|
|
1727
|
+
* @internal
|
|
1728
|
+
*/ static getClusterOrthographic(scope) {
|
|
1729
|
+
return scope.light.clusterOrtho;
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1701
1732
|
* Number of shadow-casting lights at the head of the clustered light buffer.
|
|
1702
1733
|
* Only defined on the screen-space shadow mask path (ctx.screenSpaceShadowMask);
|
|
1703
1734
|
* a clustered light whose buffer index is `<= N` samples the shadow mask.
|
|
@@ -1738,10 +1769,65 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1738
1769
|
}
|
|
1739
1770
|
return tex;
|
|
1740
1771
|
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Lazily-created 1x1x1 rgba8unorm array texture used as the transmission
|
|
1774
|
+
* thickness binding fallback.
|
|
1775
|
+
*
|
|
1776
|
+
* @remarks
|
|
1777
|
+
* Filled with 1, not left at the zero-initialised default. The thickness
|
|
1778
|
+
* channel encodes `1 - opticalDepth / 5`, so 0 is *maximum* optical depth —
|
|
1779
|
+
* the worst possible value to fall back to, and the opposite of what the real
|
|
1780
|
+
* pass clears its unused channels to. {@link ShaderHelper.getDummyShadowMask}
|
|
1781
|
+
* gets away with zeroes because 0 reads as "fully shadowed" there.
|
|
1782
|
+
*
|
|
1783
|
+
* On the default pipeline this is never sampled: `ctx.transmissionThickness`
|
|
1784
|
+
* and the thickness module's `enabled` are computed from the same condition.
|
|
1785
|
+
* A custom `camera.renderPipeline` that omits the module can break that tie,
|
|
1786
|
+
* and this fallback is what keeps that from turning into full-strength
|
|
1787
|
+
* transmission across the whole screen.
|
|
1788
|
+
* @internal
|
|
1789
|
+
*/ static getDummyTransmissionThickness(device) {
|
|
1790
|
+
let tex = this._dummyTransmissionThickness;
|
|
1791
|
+
if (!tex || tex.disposed) {
|
|
1792
|
+
tex = device.createTexture2DArray('rgba8unorm', 1, 1, 1, {
|
|
1793
|
+
mipmapping: false
|
|
1794
|
+
});
|
|
1795
|
+
tex.name = 'DummyTransmissionThickness';
|
|
1796
|
+
tex.update(new Uint8Array([
|
|
1797
|
+
255,
|
|
1798
|
+
255,
|
|
1799
|
+
255,
|
|
1800
|
+
255
|
|
1801
|
+
]), 0, 0, 0, 1, 1, 1);
|
|
1802
|
+
this._dummyTransmissionThickness = tex;
|
|
1803
|
+
}
|
|
1804
|
+
return tex;
|
|
1805
|
+
}
|
|
1741
1806
|
/** @internal */ static getClusteredLightIndexTexture(scope) {
|
|
1742
1807
|
return scope[UNIFORM_NAME_LIGHT_INDEX_TEXTURE];
|
|
1743
1808
|
}
|
|
1744
1809
|
/**
|
|
1810
|
+
* Whether clusters hold variable-length light lists in storage buffers (WebGPU),
|
|
1811
|
+
* rather than 16 byte-sized slots in a texture.
|
|
1812
|
+
* @internal
|
|
1813
|
+
*/ static usesClusterLightLists() {
|
|
1814
|
+
return getDevice().type === 'webgpu';
|
|
1815
|
+
}
|
|
1816
|
+
/**
|
|
1817
|
+
* Per cluster, the offset of its light list and the number of lights in it, two
|
|
1818
|
+
* uints each. Only on {@link ShaderHelper.usesClusterLightLists}.
|
|
1819
|
+
* @internal
|
|
1820
|
+
*/ static getClusterGrid(scope) {
|
|
1821
|
+
return scope[UNIFORM_NAME_CLUSTER_GRID];
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Light buffer indices of every cluster's lights, one list after another. Only on
|
|
1825
|
+
* {@link ShaderHelper.usesClusterLightLists}.
|
|
1826
|
+
* @internal
|
|
1827
|
+
*/ static getClusterLightList(scope) {
|
|
1828
|
+
return scope[UNIFORM_NAME_CLUSTER_LIGHT_LIST];
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1745
1831
|
* Clustered shadow factor for a light, in `[0,1]` (1 = fully lit).
|
|
1746
1832
|
*
|
|
1747
1833
|
* - Lights whose clustered buffer index is greater than `numShadowLights` are not
|
|
@@ -1784,6 +1870,30 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1784
1870
|
return pb.getGlobalScope()[funcName](lightIndex);
|
|
1785
1871
|
}
|
|
1786
1872
|
/**
|
|
1873
|
+
* Encoded light-space thickness for a light.
|
|
1874
|
+
*
|
|
1875
|
+
* @internal
|
|
1876
|
+
*/ static sampleTransmissionThickness(scope, lightIndex) {
|
|
1877
|
+
const pb = scope.$builder;
|
|
1878
|
+
const that = this;
|
|
1879
|
+
const funcName = 'Z_sampleTransmissionThickness';
|
|
1880
|
+
pb.func(funcName, [
|
|
1881
|
+
pb.int('lightIndex')
|
|
1882
|
+
], function() {
|
|
1883
|
+
this.$if(pb.greaterThan(this.lightIndex, that.getNumShadowLights(this)), function() {
|
|
1884
|
+
this.$return(pb.float(1));
|
|
1885
|
+
});
|
|
1886
|
+
this.$l.ordinal = pb.sub(this.lightIndex, 1);
|
|
1887
|
+
this.$l.layer = pb.div(this.ordinal, 4);
|
|
1888
|
+
this.$l.channel = pb.sub(this.ordinal, pb.mul(this.layer, 4));
|
|
1889
|
+
this.$l.uv = pb.div(pb.vec2(this.$builtins.fragCoord.xy), that.getRenderSize(this));
|
|
1890
|
+
this.$l.texel = pb.textureArraySampleLevel(this[UNIFORM_NAME_TRANSMISSION_THICKNESS], this.uv, this.layer, 0);
|
|
1891
|
+
this.$l.selector = pb.vec4(pb.float(pb.equal(this.channel, 0)), pb.float(pb.equal(this.channel, 1)), pb.float(pb.equal(this.channel, 2)), pb.float(pb.equal(this.channel, 3)));
|
|
1892
|
+
this.$return(pb.dot(this.texel, this.selector));
|
|
1893
|
+
});
|
|
1894
|
+
return pb.getGlobalScope()[funcName](lightIndex);
|
|
1895
|
+
}
|
|
1896
|
+
/**
|
|
1787
1897
|
* Gets the uniform variable that contains atmosphere parameters
|
|
1788
1898
|
* @param scope - Current shader scope
|
|
1789
1899
|
* @returns The atmosphere parameters
|
|
@@ -1906,16 +2016,21 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1906
2016
|
}
|
|
1907
2017
|
}
|
|
1908
2018
|
/** @internal */ static getLightPositionAndRange(scope, lightIndex) {
|
|
1909
|
-
return
|
|
2019
|
+
return this.getLightVector(scope, lightIndex, 0);
|
|
1910
2020
|
}
|
|
1911
2021
|
/** @internal */ static getLightDirectionAndCutoff(scope, lightIndex) {
|
|
1912
|
-
return
|
|
2022
|
+
return this.getLightVector(scope, lightIndex, 1);
|
|
1913
2023
|
}
|
|
1914
2024
|
/** @internal */ static getLightColorAndIntensity(scope, lightIndex) {
|
|
1915
|
-
return
|
|
2025
|
+
return this.getLightVector(scope, lightIndex, 2);
|
|
1916
2026
|
}
|
|
1917
2027
|
/** @internal */ static getLightExtra(scope, lightIndex) {
|
|
1918
|
-
return
|
|
2028
|
+
return this.getLightVector(scope, lightIndex, 3);
|
|
2029
|
+
}
|
|
2030
|
+
/** Vector `k` of the 4 of a clustered light, read from the light buffer. */ static getLightVector(scope, lightIndex, k) {
|
|
2031
|
+
const pb = scope.$builder;
|
|
2032
|
+
const buffer = scope[UNIFORM_NAME_LIGHT_BUFFER];
|
|
2033
|
+
return buffer.at(pb.add(pb.mul(lightIndex, 4), k));
|
|
1919
2034
|
}
|
|
1920
2035
|
/**
|
|
1921
2036
|
* Sets the clip space position in vertex shader
|
|
@@ -1997,6 +2112,36 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
1997
2112
|
return pb.add(worldPos, pb.mul(unitNormal, offset));
|
|
1998
2113
|
}
|
|
1999
2114
|
/**
|
|
2115
|
+
* How far a rect light's shadow lookup can be trusted at a receiver, as a
|
|
2116
|
+
* weight for `mix(1, shadow, weight)`.
|
|
2117
|
+
*
|
|
2118
|
+
* @remarks
|
|
2119
|
+
* A rect light's shadow is a cube map rendered from its centre, but its
|
|
2120
|
+
* lighting integrates the whole panel. Where the surface turns away from the
|
|
2121
|
+
* centre the panel's far edge still lights it, while the centre already sees
|
|
2122
|
+
* the receiver occlude itself - so the centre's shadow cuts a hard, texel
|
|
2123
|
+
* stepped terminator through lit surface. The weight fades that lookup out as
|
|
2124
|
+
* the centre sinks to the receiver's horizon.
|
|
2125
|
+
*
|
|
2126
|
+
* The band is a fixed, narrow cosine range rather than one scaled by the
|
|
2127
|
+
* panel's size: the stepped edge only lives where the centre grazes the
|
|
2128
|
+
* surface, and its width is set by shadow bias and texel footprint, not by
|
|
2129
|
+
* the panel. A band as wide as the panel's angular radius also caught flat
|
|
2130
|
+
* receivers - a floor seen low from a large upright panel - and faded their
|
|
2131
|
+
* cast shadows, which have no terminator to hide.
|
|
2132
|
+
*
|
|
2133
|
+
* @param worldNormal - Geometric normal; the terminator follows the surface,
|
|
2134
|
+
* not its normal map.
|
|
2135
|
+
* @param posRange - Light position (xyz).
|
|
2136
|
+
* @internal
|
|
2137
|
+
*/ static getRectLightShadowWeight(scope, worldPos, worldNormal, posRange) {
|
|
2138
|
+
const pb = scope.$builder;
|
|
2139
|
+
const toCenter = pb.sub(posRange.xyz, worldPos);
|
|
2140
|
+
const unitNormal = pb.mul(worldNormal, pb.div(1, pb.max(pb.length(worldNormal), 1e-6)));
|
|
2141
|
+
const cosCenter = pb.div(pb.dot(unitNormal, toCenter), pb.max(pb.length(toCenter), 1e-6));
|
|
2142
|
+
return pb.smoothStep(0, 0.01, cosCenter);
|
|
2143
|
+
}
|
|
2144
|
+
/**
|
|
2000
2145
|
* Calculates shadow of current fragment
|
|
2001
2146
|
*
|
|
2002
2147
|
* @param scope - Shader scope
|
|
@@ -2024,17 +2169,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
2024
2169
|
// would self-occlude it before projecting into shadow space. Scaled per
|
|
2025
2170
|
// cascade, because each cascade has its own texel world size.
|
|
2026
2171
|
this.$l.biasedPos = that.applyShadowNormalOffset(shadowMapParams.lightType, this, this.worldPos, this.worldNormal, this.NoL, that.getShadowCascadeBiasScale(this, this.split));
|
|
2027
|
-
|
|
2028
|
-
this.$l.shadowVertex = pb.vec4();
|
|
2029
|
-
this.$for(pb.int('cascade'), 0, 4, function() {
|
|
2030
|
-
this.$if(pb.equal(this.cascade, this.split), function() {
|
|
2031
|
-
this.shadowVertex = that.calculateShadowSpaceVertex(this, pb.vec4(this.biasedPos, 1), this.cascade);
|
|
2032
|
-
this.$break();
|
|
2033
|
-
});
|
|
2034
|
-
});
|
|
2035
|
-
} else {
|
|
2036
|
-
this.$l.shadowVertex = that.calculateShadowSpaceVertex(this, pb.vec4(this.biasedPos, 1), this.split);
|
|
2037
|
-
}
|
|
2172
|
+
this.$l.shadowVertex = that.calculateShadowSpaceVertex(this, pb.vec4(this.biasedPos, 1), this.split);
|
|
2038
2173
|
this.$l.shadow = shadowMapParams.impl.computeShadowCSM(shadowMapParams, this, this.shadowVertex, this.NoL, this.split);
|
|
2039
2174
|
this.shadow = pb.clamp(this.shadow, 0, 1);
|
|
2040
2175
|
this.$l.shadowDistance = that.getShadowCameraParams(scope).w;
|
|
@@ -2049,7 +2184,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
2049
2184
|
// Normal offset bias - see the cascaded branch above.
|
|
2050
2185
|
this.$l.biasedPos = that.applyShadowNormalOffset(shadowMapParams.lightType, this, this.worldPos, this.worldNormal, this.NoL);
|
|
2051
2186
|
this.$l.shadowVertex = that.calculateShadowSpaceVertex(this, pb.vec4(this.biasedPos, 1));
|
|
2052
|
-
this.$l.shadow = shadowMapParams.impl.computeShadow(shadowMapParams, this, this.shadowVertex, this.NoL);
|
|
2187
|
+
this.$l.shadow = shadowMapParams.impl.computeShadow(shadowMapParams, this, this.shadowVertex, this.NoL, this.worldNormal);
|
|
2053
2188
|
this.shadow = pb.clamp(this.shadow, 0, 1);
|
|
2054
2189
|
this.$l.shadowDistance = that.getShadowCameraParams(scope).w;
|
|
2055
2190
|
this.shadow = pb.mix(this.shadow, 1, pb.smoothStep(pb.mul(this.shadowDistance, 0.8), this.shadowDistance, pb.distance(that.getCameraPosition(this), this.worldPos)));
|
|
@@ -2060,24 +2195,22 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
2060
2195
|
});
|
|
2061
2196
|
return pb.getGlobalScope()[funcName](worldPos, worldNormal, NoL);
|
|
2062
2197
|
}
|
|
2063
|
-
static applyFog(scope, worldPos, color, ctx) {
|
|
2198
|
+
static applyFog(scope, worldPos, color, ctx, premultiplied = true) {
|
|
2064
2199
|
const pb = scope.$builder;
|
|
2065
2200
|
const that = this;
|
|
2066
2201
|
if (ctx.materialFlags & MaterialVaryingFlags.APPLY_FOG) {
|
|
2067
|
-
const funcName = 'Z_applyFog';
|
|
2202
|
+
const funcName = premultiplied ? 'Z_applyFog' : 'Z_applyFogStraight';
|
|
2068
2203
|
pb.func(funcName, [
|
|
2069
2204
|
pb.vec3('worldPos'),
|
|
2070
2205
|
pb.vec4('color').inout()
|
|
2071
2206
|
], function() {
|
|
2072
|
-
this.$if(pb.notEqual(this.fog.additive, 0), function() {
|
|
2073
|
-
this.$return();
|
|
2074
|
-
});
|
|
2075
2207
|
this.$l.uv = pb.div(pb.vec2(this.$builtins.fragCoord.xy), that.getRenderSize(this));
|
|
2076
|
-
this.$l.fogging = calculateFog(this, this.fog.withAerialPerspective, this.fog.fogType, this.fog.atmosphereParams, this.fog.heightFogParams, this.uv, false, that.getCameraPosition(this).xyz, this.worldPos, this.fog.additive, this[UNIFORM_NAME_AERIALPERSPECTIVE_LUT], this[UNIFORM_NAME_SKYDISTANTLIGHT_LUT]);
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2208
|
+
this.$l.fogging = calculateFog(this, this.fog.withAerialPerspective, this.fog.fogType, this.fog.atmosphereParams, this.fog.heightFogParams, this.uv, false, that.getCameraPosition(this).xyz, this.worldPos, this.fog.additive, this[UNIFORM_NAME_AERIALPERSPECTIVE_LUT], this[UNIFORM_NAME_SKYDISTANTLIGHT_LUT], this[UNIFORM_NAME_FOG_SKYLIGHT_CUBEMAP]);
|
|
2209
|
+
// Premultiplied color: attenuate by the fog transmittance and add the in-scattering weighted
|
|
2210
|
+
// by coverage. Additive light passes and additive blending (alpha 0) get attenuation only --
|
|
2211
|
+
// calculateFog already zeroes the in-scattering for the former. Straight (non-premultiplied)
|
|
2212
|
+
// color is scaled by coverage later, so the in-scattering is added unweighted.
|
|
2213
|
+
this.color = pb.vec4(pb.add(pb.mul(this.color.rgb, this.fogging.a), premultiplied ? pb.mul(this.fogging.rgb, this.color.a) : this.fogging.rgb), this.color.a);
|
|
2081
2214
|
});
|
|
2082
2215
|
scope[funcName](worldPos, color);
|
|
2083
2216
|
}
|
|
@@ -2210,7 +2343,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
2210
2343
|
*/ static sampleLinearDepth(scope, tex, uv, level) {
|
|
2211
2344
|
const pb = scope.$builder;
|
|
2212
2345
|
const depth = pb.textureSampleLevel(tex, uv, level);
|
|
2213
|
-
return
|
|
2346
|
+
return depth.r;
|
|
2214
2347
|
}
|
|
2215
2348
|
static samplePositionFromDepth(scope, depthTex, uv, mat, cameraNearFar) {
|
|
2216
2349
|
const pb = scope.$builder;
|
|
@@ -2261,8 +2394,17 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
|
|
|
2261
2394
|
});
|
|
2262
2395
|
return pb.getGlobalScope()[funcName](outputColor);
|
|
2263
2396
|
}
|
|
2264
|
-
/**
|
|
2265
|
-
|
|
2397
|
+
/**
|
|
2398
|
+
* Capacity of the clustered light buffer, excluding the unused slot 0.
|
|
2399
|
+
*
|
|
2400
|
+
* @remarks
|
|
2401
|
+
* On WebGPU the buffers are storage buffers grown to fit and light indices are 32
|
|
2402
|
+
* bits, so this only bounds the CPU-side work. On WebGL2 the buffer is 4 vec4 per
|
|
2403
|
+
* light in a uniform block, and 255 is the most a byte-sized cluster slot can address.
|
|
2404
|
+
* @internal
|
|
2405
|
+
*/ static getMaxClusterLights() {
|
|
2406
|
+
const device = getDevice();
|
|
2407
|
+
return device.type === 'webgpu' ? 65535 : 255;
|
|
2266
2408
|
}
|
|
2267
2409
|
}
|
|
2268
2410
|
|