@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
|
@@ -5,6 +5,7 @@ import { ShadowMapPass } from '../shadowmap_pass.js';
|
|
|
5
5
|
import { DepthPass } from '../depthpass.js';
|
|
6
6
|
import { ClusteredLight } from '../cluster_light.js';
|
|
7
7
|
import { ShadowMaskRenderer } from '../shadow_mask_pass.js';
|
|
8
|
+
import { TransmissionThicknessRenderer } from '../transmission_thickness_pass.js';
|
|
8
9
|
import { getHiZFormat, buildHiZ } from '../hzb.js';
|
|
9
10
|
import '../primitive.js';
|
|
10
11
|
import '@zephyr3d/device';
|
|
@@ -25,6 +26,7 @@ import { OrderingScope } from './render_context.js';
|
|
|
25
26
|
import { RenderPipeline } from './render_pipeline.js';
|
|
26
27
|
import { mergeFrameResourceRequirements } from './frame_resource_requirements.js';
|
|
27
28
|
import { renderObjectColors } from '../gpu_picking.js';
|
|
29
|
+
import '../../node_modules/meshoptimizer/meshopt_simplifier.js';
|
|
28
30
|
import { BoxShape } from '../../shapes/box.js';
|
|
29
31
|
import '../../shapes/capsule.js';
|
|
30
32
|
import '../../shapes/cylinder.js';
|
|
@@ -38,11 +40,18 @@ import { UnderwaterRenderer, selectUnderwaterSource } from '../underwater.js';
|
|
|
38
40
|
const _scenePass = new LightPass();
|
|
39
41
|
const _depthPass = new DepthPass();
|
|
40
42
|
const _shadowMapPass = new ShadowMapPass();
|
|
41
|
-
const _clusters = [];
|
|
42
43
|
const _shadowMaskRenderer = new ShadowMaskRenderer();
|
|
44
|
+
const _transmissionThicknessRenderer = new TransmissionThicknessRenderer();
|
|
43
45
|
const _waterCausticsRenderer = new WaterCausticsRenderer();
|
|
44
46
|
const _underwaterRenderer = new UnderwaterRenderer();
|
|
45
47
|
const _devicePoolAllocator = new DevicePoolAllocator();
|
|
48
|
+
/**
|
|
49
|
+
* Clear value for the depth prepass's skin profile id target.
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* 0 is "not skin". It has to differ from the depth target's clear, which is the
|
|
53
|
+
* far plane rather than an id.
|
|
54
|
+
*/ const SKIN_PROFILE_ID_CLEAR = new Vector4(0, 0, 0, 0);
|
|
46
55
|
const _textureAffinityCaches = new WeakMap();
|
|
47
56
|
function getTextureAffinityCache(camera, device) {
|
|
48
57
|
const current = _textureAffinityCaches.get(camera);
|
|
@@ -59,20 +68,14 @@ function getTextureAffinityCache(camera, device) {
|
|
|
59
68
|
let _backDepthColorState = null;
|
|
60
69
|
let _frontDepthColorState = null;
|
|
61
70
|
const SURFACE_MRT_FLAGS = MaterialVaryingFlags.SCENE_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SCENE_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION | MaterialVaryingFlags.SKIN_SSS_STORE;
|
|
62
|
-
function getClusteredLight() {
|
|
63
|
-
return _clusters.length > 0 ? _clusters.pop() : new ClusteredLight();
|
|
64
|
-
}
|
|
65
|
-
function freeClusteredLight(cl) {
|
|
66
|
-
_clusters.push(cl);
|
|
67
|
-
}
|
|
68
71
|
function getCoreMaterial(material) {
|
|
69
72
|
return material?.coreMaterial ?? material ?? null;
|
|
70
73
|
}
|
|
71
74
|
function hasSSSMaterialCore(material) {
|
|
72
75
|
return !!getCoreMaterial(material)?.subsurfaceProfile;
|
|
73
76
|
}
|
|
74
|
-
function
|
|
75
|
-
return !!getCoreMaterial(material)?.
|
|
77
|
+
function hasPostSSSMaterialCore(material) {
|
|
78
|
+
return !!getCoreMaterial(material)?.postSSS;
|
|
76
79
|
}
|
|
77
80
|
function renderQueueHasActiveSSS(renderQueue) {
|
|
78
81
|
const itemList = renderQueue.itemList;
|
|
@@ -92,7 +95,7 @@ function renderQueueHasActiveSSS(renderQueue) {
|
|
|
92
95
|
}
|
|
93
96
|
return false;
|
|
94
97
|
}
|
|
95
|
-
function
|
|
98
|
+
function renderQueueHasActivePostSSS(renderQueue) {
|
|
96
99
|
const itemList = renderQueue.itemList;
|
|
97
100
|
if (!itemList) {
|
|
98
101
|
return false;
|
|
@@ -103,7 +106,7 @@ function renderQueueHasActiveSkinSSS(renderQueue) {
|
|
|
103
106
|
];
|
|
104
107
|
for (const list of lists){
|
|
105
108
|
for (const material of list.materialList){
|
|
106
|
-
if (
|
|
109
|
+
if (hasPostSSSMaterialCore(material)) {
|
|
107
110
|
return true;
|
|
108
111
|
}
|
|
109
112
|
}
|
|
@@ -129,8 +132,10 @@ function cloneActualSSSListInfo(source, _targetQueue) {
|
|
|
129
132
|
morphItemList: filterActualSSSItemList(source.morphItemList),
|
|
130
133
|
skinAndMorphItemList: filterActualSSSItemList(source.skinAndMorphItemList),
|
|
131
134
|
instanceItemList: filterActualSSSItemList(source.instanceItemList),
|
|
135
|
+
skinInstanceItemList: filterActualSSSItemList(source.skinInstanceItemList),
|
|
132
136
|
materialList: filterActualSSSMaterialList(source.materialList),
|
|
133
137
|
instanceList: {},
|
|
138
|
+
instanceLods: {},
|
|
134
139
|
renderQueue: source.renderQueue
|
|
135
140
|
};
|
|
136
141
|
}
|
|
@@ -141,7 +146,7 @@ function cloneActualSSSBundle(source, targetQueue) {
|
|
|
141
146
|
};
|
|
142
147
|
}
|
|
143
148
|
function hasAnyActualSSSItems(renderItems) {
|
|
144
|
-
return renderItems.some((info)=>info.itemList.length > 0 || info.skinItemList.length > 0 || info.morphItemList.length > 0 || info.skinAndMorphItemList.length > 0 || info.instanceItemList.length > 0);
|
|
149
|
+
return renderItems.some((info)=>info.itemList.length > 0 || info.skinItemList.length > 0 || info.morphItemList.length > 0 || info.skinAndMorphItemList.length > 0 || info.instanceItemList.length > 0 || info.skinInstanceItemList.length > 0);
|
|
145
150
|
}
|
|
146
151
|
function createActualSSSRenderQueue(renderQueue) {
|
|
147
152
|
const itemList = renderQueue.itemList;
|
|
@@ -253,22 +258,22 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
|
|
|
253
258
|
attachments.push(ctx.SSSTransmissionTexture);
|
|
254
259
|
}
|
|
255
260
|
if (ctx.materialFlags & MaterialVaryingFlags.SKIN_SSS_STORE) {
|
|
256
|
-
attachments.push(ctx.
|
|
261
|
+
attachments.push(ctx.SSSMaskTexture);
|
|
257
262
|
}
|
|
258
263
|
return attachments.length === 1 ? attachments[0] : attachments;
|
|
259
264
|
}
|
|
260
|
-
/** Derive Forward+ options from scene and camera state. @internal */ function deriveForwardPlusOptions(scene, camera,
|
|
265
|
+
/** Derive Forward+ options from scene and camera state. @internal */ function deriveForwardPlusOptions(scene, camera, _deviceType, renderQueue) {
|
|
261
266
|
const ssr = camera.SSR && scene.env.light.envLight && scene.env.light.envLight.hasRadiance();
|
|
262
267
|
const ssgi = camera.SSGI && camera.HDR && camera.ssgiIntensity > 0 && scene.env.light.type === 'ibl' && !!scene.env.light.envLight?.hasRadiance() && !!scene.env.light.envLight?.hasIrradiance();
|
|
263
268
|
const sss = camera.SSS && renderQueueHasActiveSSS(renderQueue);
|
|
264
|
-
|
|
269
|
+
// No camera switch for this one: a skin material always wants its diffusion,
|
|
270
|
+
// and the queue already says whether the frame draws any.
|
|
271
|
+
const postSSS = renderQueueHasActivePostSSS(renderQueue);
|
|
265
272
|
const needSceneColor = renderQueue.needSceneColor();
|
|
266
273
|
const needSceneColorWithDepth = renderQueue.needSceneColorWithDepth();
|
|
267
274
|
// Requested by materials rather than by a post effect, so it is resolved here
|
|
268
|
-
// instead of in resolveFrameResourceRequirements.
|
|
269
|
-
|
|
270
|
-
// thrown frame; the material is expected to shade without it.
|
|
271
|
-
const needHiZNearest = (renderQueue.needHiZNearest() || camera.HiZNearest) && deviceType !== 'webgl';
|
|
275
|
+
// instead of in resolveFrameResourceRequirements.
|
|
276
|
+
const needHiZNearest = renderQueue.needHiZNearest() || camera.HiZNearest;
|
|
272
277
|
return {
|
|
273
278
|
depthPrepass: true,
|
|
274
279
|
motionVectors: false,
|
|
@@ -285,12 +290,14 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
|
|
|
285
290
|
needSceneColorWithDepth,
|
|
286
291
|
needsTransmissionDepthForSSR: !!ssr && needSceneColor && !needSceneColorWithDepth,
|
|
287
292
|
sss: !!sss,
|
|
288
|
-
|
|
293
|
+
postSSS: !!postSSS,
|
|
294
|
+
// Driven entirely by postSSS: the id exists to serve the diffusion and the
|
|
295
|
+
// transmission thickness pass, and both are gated on the same condition.
|
|
296
|
+
sssProfileId: !!postSSS,
|
|
289
297
|
fogPresents: !!scene.env.sky?.fogPresents
|
|
290
298
|
};
|
|
291
299
|
}
|
|
292
300
|
function resolveFrameResourceRequirements(ctx, options, requirements) {
|
|
293
|
-
const deviceType = ctx.device.type;
|
|
294
301
|
options.motionVectors ||= !!requirements.motionVector;
|
|
295
302
|
options.hiZNearest ||= !!requirements.hiZNearest;
|
|
296
303
|
// The nearest channel lives on the same pyramid, so asking for it is asking
|
|
@@ -299,15 +306,6 @@ function resolveFrameResourceRequirements(ctx, options, requirements) {
|
|
|
299
306
|
options.sceneNormal ||= !!requirements.sceneNormal;
|
|
300
307
|
options.sceneRoughness ||= !!requirements.sceneRoughness;
|
|
301
308
|
options.shadowMask ||= !!requirements.shadowMask;
|
|
302
|
-
if (options.motionVectors && deviceType === 'webgl') {
|
|
303
|
-
throw new Error('Forward+: MotionVector was requested but is not supported by the WebGL backend.');
|
|
304
|
-
}
|
|
305
|
-
if (options.hiZ && deviceType === 'webgl') {
|
|
306
|
-
throw new Error('Forward+: HiZ was requested but is not supported by the WebGL backend.');
|
|
307
|
-
}
|
|
308
|
-
if (options.shadowMask && deviceType === 'webgl') {
|
|
309
|
-
throw new Error('Forward+: ShadowMask was requested but is not supported by the WebGL backend.');
|
|
310
|
-
}
|
|
311
309
|
const surfaceAttachmentCount = Number(options.sceneNormal) + Number(options.sceneRoughness);
|
|
312
310
|
if (surfaceAttachmentCount > 0) {
|
|
313
311
|
const caps = ctx.device.getDeviceCaps();
|
|
@@ -321,6 +319,7 @@ function resolveFrameResourceRequirements(ctx, options, requirements) {
|
|
|
321
319
|
}
|
|
322
320
|
}
|
|
323
321
|
ctx.motionVectors = options.motionVectors;
|
|
322
|
+
ctx.sssProfileId = options.sssProfileId;
|
|
324
323
|
ctx.HiZ = options.hiZ;
|
|
325
324
|
ctx.SSGI = options.ssgi;
|
|
326
325
|
ctx.screenSpaceShadowMask = options.shadowMask;
|
|
@@ -388,8 +387,9 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
388
387
|
ordering.emit(builder, 'ClusterLightsDone');
|
|
389
388
|
builder.sideEffect();
|
|
390
389
|
builder.setExecute(()=>{
|
|
391
|
-
ctx.clusteredLight =
|
|
392
|
-
|
|
390
|
+
ctx.clusteredLight = ClusteredLight.acquire(ctx.renderWidth, ctx.renderHeight);
|
|
391
|
+
// The light passes draw into targets of the render size (see renderOpaqueScenePass).
|
|
392
|
+
ctx.clusteredLight.calculateLightIndex(ctx.camera, renderQueue, ctx.renderWidth, ctx.renderHeight, ctx.screenSpaceShadowMask, ShaderHelper.getPreExposure(ctx));
|
|
393
393
|
});
|
|
394
394
|
});
|
|
395
395
|
}
|
|
@@ -439,7 +439,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
439
439
|
* most likely to be looking through.
|
|
440
440
|
* @internal
|
|
441
441
|
*/ function selectWaterCausticSource(ctx, renderQueue) {
|
|
442
|
-
if (
|
|
442
|
+
if (renderQueue.waters.length === 0) {
|
|
443
443
|
return null;
|
|
444
444
|
}
|
|
445
445
|
// The caustic light must own an additive shadow pass, because that is the pass
|
|
@@ -581,7 +581,8 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
581
581
|
writes: [
|
|
582
582
|
FrameResources.LinearDepth,
|
|
583
583
|
FrameResources.MotionVector,
|
|
584
|
-
FrameResources.SceneDepthAttachment
|
|
584
|
+
FrameResources.SceneDepthAttachment,
|
|
585
|
+
FrameResources.SSSProfileId
|
|
585
586
|
],
|
|
586
587
|
prepare: ()=>({
|
|
587
588
|
enabled: true
|
|
@@ -590,7 +591,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
590
591
|
const { graph, ctx, frame, ordering, blackboard, options } = fg;
|
|
591
592
|
const result = graph.addPass('DepthPrepass', (builder)=>{
|
|
592
593
|
ordering.chainInto(builder);
|
|
593
|
-
const format = ctx.
|
|
594
|
+
const format = ctx.SSRCalcThickness ? 'rg32f' : 'r32f';
|
|
594
595
|
const mvFormat = 'rgba16f';
|
|
595
596
|
const depthHandle = builder.createTexture({
|
|
596
597
|
format,
|
|
@@ -602,6 +603,14 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
602
603
|
label: 'motionVector',
|
|
603
604
|
allocationKey: 'ForwardPlus.MotionVector'
|
|
604
605
|
}) : undefined;
|
|
606
|
+
// r8unorm is exact for this: the material writes `SSSProfile.encodedId`,
|
|
607
|
+
// i.e. `id / 255`, and the table holds 256 rows, so every representable id
|
|
608
|
+
// survives the round trip. 0 means "not skin".
|
|
609
|
+
const sssProfileIdHandle = options.sssProfileId ? builder.createTexture({
|
|
610
|
+
format: 'r8unorm',
|
|
611
|
+
label: 'sssProfileId',
|
|
612
|
+
allocationKey: 'ForwardPlus.SSSProfileId'
|
|
613
|
+
}) : undefined;
|
|
605
614
|
const finalDepthAttachment = ctx.finalFramebuffer?.getDepthAttachment();
|
|
606
615
|
const externalDepthAttachment = finalDepthAttachment?.isTexture2D() ? finalDepthAttachment : null;
|
|
607
616
|
const externalDepthAttachmentHandle = externalDepthAttachment ? graph.importTexture('externalSceneDepth') : undefined;
|
|
@@ -611,14 +620,23 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
611
620
|
allocationKey: 'ForwardPlus.SceneDepth'
|
|
612
621
|
});
|
|
613
622
|
const depthAttachmentOrFormat = externalDepthAttachmentHandle ?? graphDepthAttachmentHandle ?? ctx.depthFormat;
|
|
623
|
+
// Order matters and has to agree with the fragment output declaration
|
|
624
|
+
// order in MeshMaterial._createProgram: linear depth, then the motion
|
|
625
|
+
// vector, then the profile id.
|
|
626
|
+
const prepassColorAttachments = [
|
|
627
|
+
depthHandle
|
|
628
|
+
];
|
|
629
|
+
if (motionVectorHandle) {
|
|
630
|
+
prepassColorAttachments.push(motionVectorHandle);
|
|
631
|
+
}
|
|
632
|
+
if (sssProfileIdHandle) {
|
|
633
|
+
prepassColorAttachments.push(sssProfileIdHandle);
|
|
634
|
+
}
|
|
614
635
|
const depthFramebufferHandle = builder.createFramebuffer({
|
|
615
636
|
label: 'DepthPrepassFramebuffer',
|
|
616
637
|
width: ctx.renderWidth,
|
|
617
638
|
height: ctx.renderHeight,
|
|
618
|
-
colorAttachments:
|
|
619
|
-
depthHandle,
|
|
620
|
-
motionVectorHandle
|
|
621
|
-
] : depthHandle,
|
|
639
|
+
colorAttachments: prepassColorAttachments.length === 1 ? depthHandle : prepassColorAttachments,
|
|
622
640
|
depthAttachment: depthAttachmentOrFormat,
|
|
623
641
|
ignoreDepthStencil: false
|
|
624
642
|
});
|
|
@@ -646,6 +664,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
646
664
|
return {
|
|
647
665
|
depthHandle,
|
|
648
666
|
motionVectorHandle,
|
|
667
|
+
sssProfileIdHandle: sssProfileIdHandle,
|
|
649
668
|
graphDepthAttachmentHandle,
|
|
650
669
|
externalDepthAttachmentHandle,
|
|
651
670
|
externalDepthAttachment,
|
|
@@ -658,6 +677,9 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
658
677
|
if (result.motionVectorHandle) {
|
|
659
678
|
blackboard.set(FrameResources.MotionVector, result.motionVectorHandle);
|
|
660
679
|
}
|
|
680
|
+
if (result.sssProfileIdHandle) {
|
|
681
|
+
blackboard.set(FrameResources.SSSProfileId, result.sssProfileIdHandle);
|
|
682
|
+
}
|
|
661
683
|
blackboard.set(FrameResources.SceneDepthAttachment, result.graphDepthAttachmentHandle ?? result.externalDepthAttachmentHandle);
|
|
662
684
|
// Later modules share this attachment without owning it.
|
|
663
685
|
fg.state.renderDepthAttachment = result.graphDepthAttachmentHandle ?? result.externalDepthAttachmentHandle ?? null;
|
|
@@ -675,7 +697,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
675
697
|
prepare: ({ ctx, options, renderQueue })=>({
|
|
676
698
|
enabled: options.shadowMask && renderQueue.shadowedLights.length > 0,
|
|
677
699
|
requirements: {
|
|
678
|
-
shadowMask: ctx.
|
|
700
|
+
shadowMask: ctx.camera.screenSpaceShadowMask && renderQueue.shadowedLights.length > 0
|
|
679
701
|
}
|
|
680
702
|
}),
|
|
681
703
|
setup (fg) {
|
|
@@ -714,6 +736,107 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
714
736
|
blackboard.set(FrameResources.ShadowMask, maskPassResult.maskHandle);
|
|
715
737
|
}
|
|
716
738
|
};
|
|
739
|
+
/** Orders a pass drawing scene materials after this camera's virtual texture update. @internal */ function readVirtualTextureToken(builder, blackboard) {
|
|
740
|
+
const token = blackboard.get(FrameResources.VirtualTexture);
|
|
741
|
+
if (token) {
|
|
742
|
+
builder.read(token);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
/** Scene virtual texture clients active for this camera's frame. @internal */ function activeVirtualTextureClients(ctx, renderQueue) {
|
|
746
|
+
if (ctx.device.type !== 'webgpu') {
|
|
747
|
+
return [];
|
|
748
|
+
}
|
|
749
|
+
return ctx.scene.virtualTextureClients.filter((c)=>c.isActive?.(ctx, renderQueue) ?? true);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Updates the scene's virtual textures for this camera: mark from the depth prepass, map, fill.
|
|
753
|
+
*/ const VirtualTextureModule = {
|
|
754
|
+
type: 'VirtualTextureUpdate',
|
|
755
|
+
reads: [
|
|
756
|
+
{
|
|
757
|
+
resource: FrameResources.LinearDepth
|
|
758
|
+
}
|
|
759
|
+
],
|
|
760
|
+
writes: [
|
|
761
|
+
FrameResources.VirtualTexture
|
|
762
|
+
],
|
|
763
|
+
prepare: ({ ctx, renderQueue })=>({
|
|
764
|
+
enabled: activeVirtualTextureClients(ctx, renderQueue).length > 0
|
|
765
|
+
}),
|
|
766
|
+
setup (fg) {
|
|
767
|
+
const { graph, ctx, renderQueue, blackboard } = fg;
|
|
768
|
+
const clients = activeVirtualTextureClients(ctx, renderQueue);
|
|
769
|
+
const token = graph.addPass('VirtualTextureUpdate', (builder)=>{
|
|
770
|
+
const depthHandle = blackboard.expect(FrameResources.LinearDepth);
|
|
771
|
+
builder.read(depthHandle);
|
|
772
|
+
// Page tables and pools are scene state the graph does not track
|
|
773
|
+
builder.sideEffect();
|
|
774
|
+
const token = builder.createToken('VirtualTextureDone');
|
|
775
|
+
builder.setExecute((rgCtx)=>{
|
|
776
|
+
const depthTex = rgCtx.getTexture(depthHandle);
|
|
777
|
+
const stamp = ctx.device.frameInfo.frameCounter;
|
|
778
|
+
for (const client of clients){
|
|
779
|
+
client.markFromDepth?.(ctx, depthTex);
|
|
780
|
+
}
|
|
781
|
+
for (const client of clients){
|
|
782
|
+
client.virtualTexture.update(stamp);
|
|
783
|
+
client.fill(ctx);
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
return token;
|
|
787
|
+
});
|
|
788
|
+
blackboard.set(FrameResources.VirtualTexture, token);
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
/** @internal */ const TransmissionThicknessModule = {
|
|
792
|
+
type: 'TransmissionThicknessPass',
|
|
793
|
+
writes: [
|
|
794
|
+
FrameResources.TransmissionThickness
|
|
795
|
+
],
|
|
796
|
+
prepare: ({ options, renderQueue })=>({
|
|
797
|
+
// Not gated on the device: transmission lights the subject directly in the
|
|
798
|
+
// base pass, so it does not depend on the WebGPU-only PostSSS diffusion.
|
|
799
|
+
enabled: options.postSSS && renderQueue.shadowedLights.some((light)=>light.transmission)
|
|
800
|
+
}),
|
|
801
|
+
setup (fg) {
|
|
802
|
+
const { graph, ctx, renderQueue, blackboard } = fg;
|
|
803
|
+
const depthPassResult = requireBuildState(fg, 'depth', 'DepthPrepass', 'TransmissionThicknessPass');
|
|
804
|
+
// The ordinal space is shared with the shadow mask so that a light's
|
|
805
|
+
// thickness and its shadow factor are found with the same arithmetic; that
|
|
806
|
+
// means the layer count follows the shadow light count, not the (smaller)
|
|
807
|
+
// transmission light count.
|
|
808
|
+
const numShadowLights = renderQueue.shadowedLights.length;
|
|
809
|
+
const numLayers = ShadowMaskRenderer.getLayerCount(numShadowLights);
|
|
810
|
+
const passResult = graph.addPass('TransmissionThicknessPass', (builder)=>{
|
|
811
|
+
const depthHandle = blackboard.expect(FrameResources.LinearDepth);
|
|
812
|
+
const sssProfileIdHandle = blackboard.expect(FrameResources.SSSProfileId);
|
|
813
|
+
builder.read(depthHandle);
|
|
814
|
+
builder.read(sssProfileIdHandle);
|
|
815
|
+
builder.read(depthPassResult.depthFramebufferHandle);
|
|
816
|
+
const thicknessHandle = builder.createTexture({
|
|
817
|
+
format: 'rgba8unorm',
|
|
818
|
+
label: 'transmissionThickness',
|
|
819
|
+
arrayLayers: numLayers,
|
|
820
|
+
allocationKey: 'ForwardPlus.TransmissionThickness'
|
|
821
|
+
});
|
|
822
|
+
builder.setExecute((rgCtx)=>{
|
|
823
|
+
const depthTex = rgCtx.getTexture(depthHandle);
|
|
824
|
+
const thicknessTex = rgCtx.getTexture(thicknessHandle);
|
|
825
|
+
_transmissionThicknessRenderer.render(ctx, depthTex, rgCtx.getTexture(sssProfileIdHandle), renderQueue.shadowedLights, (layer)=>rgCtx.createFramebuffer({
|
|
826
|
+
width: thicknessTex.width,
|
|
827
|
+
height: thicknessTex.height,
|
|
828
|
+
colorAttachments: thicknessTex,
|
|
829
|
+
depthAttachment: null,
|
|
830
|
+
attachmentLayer: layer
|
|
831
|
+
}));
|
|
832
|
+
});
|
|
833
|
+
return {
|
|
834
|
+
thicknessHandle
|
|
835
|
+
};
|
|
836
|
+
});
|
|
837
|
+
blackboard.set(FrameResources.TransmissionThickness, passResult.thicknessHandle);
|
|
838
|
+
}
|
|
839
|
+
};
|
|
717
840
|
/** @internal */ const TransmissionDepthForSSRModule = {
|
|
718
841
|
type: 'TransmissionDepthForSSR',
|
|
719
842
|
writes: [
|
|
@@ -811,10 +934,12 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
811
934
|
const depthPassResult = requireBuildState(fg, 'depth', 'DepthPrepass', 'SSSProfile');
|
|
812
935
|
const preLightTransmissionDepthToken = fg.state.preLightTransmissionDepthToken;
|
|
813
936
|
const shadowMaskHandle = blackboard.get(FrameResources.ShadowMask);
|
|
937
|
+
const thicknessHandle = blackboard.get(FrameResources.TransmissionThickness);
|
|
814
938
|
const waterCausticsHandle = blackboard.get(FrameResources.WaterCaustics);
|
|
815
939
|
const renderDepthAttachment = fg.state.renderDepthAttachment;
|
|
816
940
|
const sssProfileResult = graph.addPass('SSSProfile', (builder)=>{
|
|
817
941
|
builder.read(blackboard.expect(FrameResources.LinearDepth));
|
|
942
|
+
readVirtualTextureToken(builder, blackboard);
|
|
818
943
|
builder.read(depthPassResult.depthFramebufferHandle);
|
|
819
944
|
if (preLightTransmissionDepthToken) {
|
|
820
945
|
builder.read(preLightTransmissionDepthToken);
|
|
@@ -822,6 +947,9 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
822
947
|
if (shadowMaskHandle) {
|
|
823
948
|
builder.read(shadowMaskHandle);
|
|
824
949
|
}
|
|
950
|
+
if (thicknessHandle) {
|
|
951
|
+
builder.read(thicknessHandle);
|
|
952
|
+
}
|
|
825
953
|
if (waterCausticsHandle) {
|
|
826
954
|
// Same reason as the shadow mask: the map reaches the shader through
|
|
827
955
|
// ctx.waterCausticTexture, so only a declared read stops the executor
|
|
@@ -853,6 +981,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
853
981
|
});
|
|
854
982
|
builder.setExecute((rgCtx)=>{
|
|
855
983
|
ctx.shadowMaskTexture = shadowMaskHandle ? rgCtx.getTexture(shadowMaskHandle) : null;
|
|
984
|
+
ctx.transmissionThicknessTexture = thicknessHandle ? rgCtx.getTexture(thicknessHandle) : null;
|
|
856
985
|
renderForwardSSSProfile(frame, rgCtx.getFramebuffer(framebufferHandle), rgCtx.getTexture(profileHandle), rgCtx.getTexture(paramHandle), null);
|
|
857
986
|
});
|
|
858
987
|
return {
|
|
@@ -876,10 +1005,12 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
876
1005
|
const depthPassResult = requireBuildState(fg, 'depth', 'DepthPrepass', 'SceneColorGrab');
|
|
877
1006
|
const preLightTransmissionDepthToken = fg.state.preLightTransmissionDepthToken;
|
|
878
1007
|
const shadowMaskHandle = blackboard.get(FrameResources.ShadowMask);
|
|
1008
|
+
const thicknessHandle = blackboard.get(FrameResources.TransmissionThickness);
|
|
879
1009
|
const waterCausticsHandle = blackboard.get(FrameResources.WaterCaustics);
|
|
880
1010
|
const renderDepthAttachment = fg.state.renderDepthAttachment;
|
|
881
1011
|
const grabResult = graph.addPass('SceneColorGrab', (builder)=>{
|
|
882
1012
|
builder.read(blackboard.expect(FrameResources.LinearDepth));
|
|
1013
|
+
readVirtualTextureToken(builder, blackboard);
|
|
883
1014
|
builder.read(depthPassResult.depthFramebufferHandle);
|
|
884
1015
|
if (preLightTransmissionDepthToken) {
|
|
885
1016
|
builder.read(preLightTransmissionDepthToken);
|
|
@@ -887,6 +1018,9 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
887
1018
|
if (shadowMaskHandle) {
|
|
888
1019
|
builder.read(shadowMaskHandle);
|
|
889
1020
|
}
|
|
1021
|
+
if (thicknessHandle) {
|
|
1022
|
+
builder.read(thicknessHandle);
|
|
1023
|
+
}
|
|
890
1024
|
if (waterCausticsHandle) {
|
|
891
1025
|
// Same reason as the shadow mask: the map reaches the shader through
|
|
892
1026
|
// ctx.waterCausticTexture, so only a declared read stops the executor
|
|
@@ -928,6 +1062,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
928
1062
|
}) : undefined;
|
|
929
1063
|
builder.setExecute((rgCtx)=>{
|
|
930
1064
|
ctx.shadowMaskTexture = shadowMaskHandle ? rgCtx.getTexture(shadowMaskHandle) : null;
|
|
1065
|
+
ctx.transmissionThicknessTexture = thicknessHandle ? rgCtx.getTexture(thicknessHandle) : null;
|
|
931
1066
|
renderSceneColorGrab(frame, rgCtx, copyHandle, copyFramebufferHandle);
|
|
932
1067
|
});
|
|
933
1068
|
return {
|
|
@@ -946,7 +1081,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
946
1081
|
FrameResources.SceneNormal,
|
|
947
1082
|
FrameResources.SSSDiffuse,
|
|
948
1083
|
FrameResources.SSSTransmission,
|
|
949
|
-
FrameResources.
|
|
1084
|
+
FrameResources.PostSSS
|
|
950
1085
|
],
|
|
951
1086
|
prepare: ()=>({
|
|
952
1087
|
enabled: true
|
|
@@ -955,11 +1090,13 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
955
1090
|
const { graph, ctx, frame, blackboard, options, backbuffer } = fg;
|
|
956
1091
|
const depthPassResult = requireBuildState(fg, 'depth', 'DepthPrepass', 'LightPass');
|
|
957
1092
|
const shadowMaskHandle = blackboard.get(FrameResources.ShadowMask);
|
|
1093
|
+
const thicknessHandle = blackboard.get(FrameResources.TransmissionThickness);
|
|
958
1094
|
const waterCausticsHandle = blackboard.get(FrameResources.WaterCaustics);
|
|
959
1095
|
const preLightTransmissionDepthToken = fg.state.preLightTransmissionDepthToken;
|
|
960
1096
|
const hiZHandle = blackboard.get(FrameResources.HiZ);
|
|
961
1097
|
const sssProfileHandle = blackboard.get(FrameResources.SSSProfile);
|
|
962
1098
|
const sssParamHandle = blackboard.get(FrameResources.SSSParam);
|
|
1099
|
+
const sssProfileIdHandle = blackboard.get(FrameResources.SSSProfileId);
|
|
963
1100
|
const sceneColorCopyHandle = blackboard.get(FrameResources.SceneColorCopy);
|
|
964
1101
|
const useFinalFramebufferAsIntermediate = fg.state.useFinalFramebufferAsIntermediate;
|
|
965
1102
|
const renderDepthAttachment = fg.state.renderDepthAttachment;
|
|
@@ -1022,10 +1159,14 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1022
1159
|
}
|
|
1023
1160
|
const opaquePassResult = graph.addPass('LightPass', (builder)=>{
|
|
1024
1161
|
builder.read(blackboard.expect(FrameResources.LinearDepth));
|
|
1162
|
+
readVirtualTextureToken(builder, blackboard);
|
|
1025
1163
|
builder.read(depthPassResult.depthFramebufferHandle);
|
|
1026
1164
|
if (shadowMaskHandle) {
|
|
1027
1165
|
builder.read(shadowMaskHandle);
|
|
1028
1166
|
}
|
|
1167
|
+
if (thicknessHandle) {
|
|
1168
|
+
builder.read(thicknessHandle);
|
|
1169
|
+
}
|
|
1029
1170
|
if (waterCausticsHandle) {
|
|
1030
1171
|
// Same reason as the shadow mask: the map reaches the shader through
|
|
1031
1172
|
// ctx.waterCausticTexture, so only a declared read stops the executor
|
|
@@ -1056,6 +1197,11 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1056
1197
|
if (sssParamHandle) {
|
|
1057
1198
|
builder.read(sssParamHandle);
|
|
1058
1199
|
}
|
|
1200
|
+
// Reached through ctx.SSSProfileIdTexture, so the read must be declared or
|
|
1201
|
+
// the executor may recycle the prepass target before the effect samples it.
|
|
1202
|
+
if (sssProfileIdHandle) {
|
|
1203
|
+
builder.read(sssProfileIdHandle);
|
|
1204
|
+
}
|
|
1059
1205
|
const surfaceAttachmentCount = Number(options.sceneRoughness) + Number(options.sceneNormal);
|
|
1060
1206
|
// Surface MRT products are exposed through blackboard handles.
|
|
1061
1207
|
const sceneRoughnessHandle = options.sceneRoughness ? builder.createTexture({
|
|
@@ -1073,8 +1219,8 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1073
1219
|
if (writeSSSDiffuse && writeSSSTransmission && surfaceAttachmentCount > 0 && getSSSLightingTextureFormat(ctx, 2, surfaceAttachmentCount) !== ctx.colorFormat) {
|
|
1074
1220
|
writeSSSTransmission = false;
|
|
1075
1221
|
}
|
|
1076
|
-
const
|
|
1077
|
-
const sssLightingAttachmentCount = (writeSSSDiffuse ? 1 : 0) + (writeSSSTransmission ? 1 : 0) + (
|
|
1222
|
+
const writePostSSS = options.postSSS;
|
|
1223
|
+
const sssLightingAttachmentCount = (writeSSSDiffuse ? 1 : 0) + (writeSSSTransmission ? 1 : 0) + (writePostSSS ? 1 : 0);
|
|
1078
1224
|
const sssLightingFormat = getSSSLightingTextureFormat(ctx, sssLightingAttachmentCount, surfaceAttachmentCount);
|
|
1079
1225
|
const sssDiffuseHandle = writeSSSDiffuse ? builder.createTexture({
|
|
1080
1226
|
format: sssLightingFormat,
|
|
@@ -1086,10 +1232,10 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1086
1232
|
label: 'sssTransmission',
|
|
1087
1233
|
allocationKey: 'ForwardPlus.SSSTransmission'
|
|
1088
1234
|
}) : undefined;
|
|
1089
|
-
const
|
|
1235
|
+
const postSSSHandle = writePostSSS ? builder.createTexture({
|
|
1090
1236
|
format: sssLightingFormat,
|
|
1091
|
-
label: '
|
|
1092
|
-
allocationKey: 'ForwardPlus.
|
|
1237
|
+
label: 'postSSS',
|
|
1238
|
+
allocationKey: 'ForwardPlus.PostSSS'
|
|
1093
1239
|
}) : undefined;
|
|
1094
1240
|
const sceneColorFramebufferHandle = useFinalFramebufferAsIntermediate ? undefined : builder.createFramebuffer({
|
|
1095
1241
|
label: 'SceneColorFramebuffer',
|
|
@@ -1103,6 +1249,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1103
1249
|
const sceneColorCopyTex = sceneColorCopyHandle ? rgCtx.getTexture(sceneColorCopyHandle) : null;
|
|
1104
1250
|
// Legacy effects still read resolved MRT textures from DrawContext.
|
|
1105
1251
|
ctx.shadowMaskTexture = shadowMaskHandle ? rgCtx.getTexture(shadowMaskHandle) : null;
|
|
1252
|
+
ctx.transmissionThicknessTexture = thicknessHandle ? rgCtx.getTexture(thicknessHandle) : null;
|
|
1106
1253
|
ctx.HiZTexture = hiZHandle ? rgCtx.getTexture(hiZHandle) : null;
|
|
1107
1254
|
ctx.SceneRoughnessTexture = sceneRoughnessHandle ? rgCtx.getTexture(sceneRoughnessHandle) : null;
|
|
1108
1255
|
ctx.SceneNormalTexture = sceneNormalHandle ? rgCtx.getTexture(sceneNormalHandle) : null;
|
|
@@ -1110,7 +1257,8 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1110
1257
|
ctx.SSSParamTexture = sssParamHandle ? rgCtx.getTexture(sssParamHandle) : null;
|
|
1111
1258
|
ctx.SSSDiffuseTexture = sssDiffuseHandle ? rgCtx.getTexture(sssDiffuseHandle) : null;
|
|
1112
1259
|
ctx.SSSTransmissionTexture = sssTransmissionHandle ? rgCtx.getTexture(sssTransmissionHandle) : null;
|
|
1113
|
-
ctx.
|
|
1260
|
+
ctx.SSSMaskTexture = postSSSHandle ? rgCtx.getTexture(postSSSHandle) : null;
|
|
1261
|
+
ctx.SSSProfileIdTexture = sssProfileIdHandle ? rgCtx.getTexture(sssProfileIdHandle) : null;
|
|
1114
1262
|
const renderLightPass = ()=>renderOpaqueScenePass(frame, sceneColorTex, sceneColorCopyTex, rgCtx, sceneColorFramebufferHandle);
|
|
1115
1263
|
if (historyManager && lightHistoryReadBindings.length > 0) {
|
|
1116
1264
|
const ssgiIrradianceBinding = lightHistoryReadBindings.find((binding)=>binding.name === RGHistoryResources.SSGI_IRRADIANCE);
|
|
@@ -1139,7 +1287,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1139
1287
|
sceneNormalHandle,
|
|
1140
1288
|
sssDiffuseHandle,
|
|
1141
1289
|
sssTransmissionHandle,
|
|
1142
|
-
|
|
1290
|
+
postSSSHandle: postSSSHandle
|
|
1143
1291
|
};
|
|
1144
1292
|
});
|
|
1145
1293
|
const lightPassResult = opaquePassResult;
|
|
@@ -1157,8 +1305,8 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1157
1305
|
if (lightPassResult.sssTransmissionHandle) {
|
|
1158
1306
|
blackboard.set(FrameResources.SSSTransmission, lightPassResult.sssTransmissionHandle);
|
|
1159
1307
|
}
|
|
1160
|
-
if (lightPassResult.
|
|
1161
|
-
blackboard.set(FrameResources.
|
|
1308
|
+
if (lightPassResult.postSSSHandle) {
|
|
1309
|
+
blackboard.set(FrameResources.PostSSS, lightPassResult.postSSSHandle);
|
|
1162
1310
|
}
|
|
1163
1311
|
}
|
|
1164
1312
|
};
|
|
@@ -1297,6 +1445,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1297
1445
|
const hiZHandle = blackboard.get(FrameResources.HiZ);
|
|
1298
1446
|
const sceneColorCopyHandle = blackboard.get(FrameResources.SceneColorCopy);
|
|
1299
1447
|
const shadowMaskHandle = blackboard.get(FrameResources.ShadowMask);
|
|
1448
|
+
const thicknessHandle = blackboard.get(FrameResources.TransmissionThickness);
|
|
1300
1449
|
const waterCausticsHandle = blackboard.get(FrameResources.WaterCaustics);
|
|
1301
1450
|
const lightPassResult = requireBuildState(fg, 'lightPass', 'LightPass', 'CompositeTail');
|
|
1302
1451
|
const renderDepthAttachment = fg.state.renderDepthAttachment;
|
|
@@ -1325,7 +1474,10 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1325
1474
|
blackboard.get(FrameResources.SceneNormal),
|
|
1326
1475
|
blackboard.get(FrameResources.SSSDiffuse),
|
|
1327
1476
|
blackboard.get(FrameResources.SSSTransmission),
|
|
1328
|
-
blackboard.get(FrameResources.
|
|
1477
|
+
blackboard.get(FrameResources.PostSSS),
|
|
1478
|
+
// Reached through ctx.SSSProfileIdTexture: without the dependency the
|
|
1479
|
+
// allocator may hand the prepass target to a later pass.
|
|
1480
|
+
blackboard.get(FrameResources.SSSProfileId)
|
|
1329
1481
|
]){
|
|
1330
1482
|
if (handle) {
|
|
1331
1483
|
opaqueChainDeps.push(handle);
|
|
@@ -1350,6 +1502,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1350
1502
|
// Transparent geometry writes a new version of the opaque-chain output.
|
|
1351
1503
|
const sceneColorHandle = graph.addPass('TransparentPass', (builder)=>{
|
|
1352
1504
|
builder.read(blackboard.expect(FrameResources.LinearDepth));
|
|
1505
|
+
readVirtualTextureToken(builder, blackboard);
|
|
1353
1506
|
builder.read(depthPassResult.depthFramebufferHandle);
|
|
1354
1507
|
if (hiZHandle) {
|
|
1355
1508
|
// Transparent materials may ray-march HiZ.
|
|
@@ -1371,6 +1524,12 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1371
1524
|
// after LightPass while this pass is still sampling it.
|
|
1372
1525
|
builder.read(shadowMaskHandle);
|
|
1373
1526
|
}
|
|
1527
|
+
if (thicknessHandle) {
|
|
1528
|
+
// Same reasoning as the shadow mask above: the thickness texture is
|
|
1529
|
+
// bound by the shared clustered-light bind group, so its lifetime has to
|
|
1530
|
+
// reach this pass too.
|
|
1531
|
+
builder.read(thicknessHandle);
|
|
1532
|
+
}
|
|
1374
1533
|
if (waterCausticsHandle) {
|
|
1375
1534
|
// Same lifetime argument as the shadow mask above.
|
|
1376
1535
|
builder.read(waterCausticsHandle);
|
|
@@ -1382,6 +1541,7 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1382
1541
|
// is the same, but relying on the leftover would make this pass depend
|
|
1383
1542
|
// on execution order instead of on its own declared inputs.
|
|
1384
1543
|
ctx.shadowMaskTexture = shadowMaskHandle ? rgCtx.getTexture(shadowMaskHandle) : null;
|
|
1544
|
+
ctx.transmissionThicknessTexture = thicknessHandle ? rgCtx.getTexture(thicknessHandle) : null;
|
|
1385
1545
|
renderTransparentScenePass(frame, rgCtx, opaqueChainRan ? opaqueChainResult.color : null, lightPassResult.sceneColorFramebufferHandle);
|
|
1386
1546
|
});
|
|
1387
1547
|
return out;
|
|
@@ -1480,6 +1640,28 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1480
1640
|
return outputBackbuffer;
|
|
1481
1641
|
});
|
|
1482
1642
|
}
|
|
1643
|
+
// Debug views of raw data go on the presented image, past tone mapping and exposure
|
|
1644
|
+
const sky = ctx.scene.env.sky;
|
|
1645
|
+
if (sky.cloudDebugViewActive) {
|
|
1646
|
+
const presentedBeforeDebug = presentedBackbuffer;
|
|
1647
|
+
presentedBackbuffer = graph.addPass('VolumetricCloudDebug', (builder)=>{
|
|
1648
|
+
const out = builder.write(presentedBeforeDebug);
|
|
1649
|
+
builder.sideEffect();
|
|
1650
|
+
builder.setExecute(()=>{
|
|
1651
|
+
const device = ctx.device;
|
|
1652
|
+
device.pushDeviceStates();
|
|
1653
|
+
try {
|
|
1654
|
+
device.setFramebuffer(ctx.finalFramebuffer ?? null);
|
|
1655
|
+
device.setViewport(null);
|
|
1656
|
+
device.setScissor(null);
|
|
1657
|
+
sky.drawCloudDebugView();
|
|
1658
|
+
} finally{
|
|
1659
|
+
device.popDeviceStates();
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
return out;
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1483
1665
|
fg.state.presentedBackbuffer = presentedBackbuffer;
|
|
1484
1666
|
// Downstream modules may replace this sink registration.
|
|
1485
1667
|
blackboard.set(FrameResources.PresentedColor, presentedBackbuffer);
|
|
@@ -1492,7 +1674,9 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1492
1674
|
ShadowMaps: ShadowMapsModule,
|
|
1493
1675
|
WaterCaustics: WaterCausticsModule,
|
|
1494
1676
|
DepthPrepass: DepthPrepassModule,
|
|
1677
|
+
VirtualTextureUpdate: VirtualTextureModule,
|
|
1495
1678
|
ShadowMask: ShadowMaskModule,
|
|
1679
|
+
TransmissionThickness: TransmissionThicknessModule,
|
|
1496
1680
|
TransmissionDepthForSSR: TransmissionDepthForSSRModule,
|
|
1497
1681
|
HiZ: HiZModule,
|
|
1498
1682
|
SSSProfile: SSSProfileModule,
|
|
@@ -1509,7 +1693,9 @@ function validateProducedFrameResources(blackboard, options, renderQueue) {
|
|
|
1509
1693
|
ShadowMapsModule,
|
|
1510
1694
|
WaterCausticsModule,
|
|
1511
1695
|
DepthPrepassModule,
|
|
1696
|
+
VirtualTextureModule,
|
|
1512
1697
|
ShadowMaskModule,
|
|
1698
|
+
TransmissionThicknessModule,
|
|
1513
1699
|
TransmissionDepthForSSRModule,
|
|
1514
1700
|
HiZModule,
|
|
1515
1701
|
SSSProfileModule,
|
|
@@ -1539,11 +1725,17 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
|
|
|
1539
1725
|
options.ssgi &&= supportsSSGIRenderTargets(ctx);
|
|
1540
1726
|
ctx.SSS = !!options.sss;
|
|
1541
1727
|
ctx.SSGI = !!options.ssgi;
|
|
1728
|
+
ctx.postSSS = !!options.postSSS;
|
|
1729
|
+
// Before the compositor is consulted below: it collects requirements from,
|
|
1730
|
+
// and builds passes for, only the effects that are enabled at that moment.
|
|
1731
|
+
ctx.camera?.setPostSSSActive(ctx.postSSS);
|
|
1542
1732
|
ctx.SSGIIrradianceHistoryTexture = null;
|
|
1543
1733
|
ctx.SSGISurfaceHistoryTexture = null;
|
|
1544
|
-
ctx.
|
|
1734
|
+
ctx.SSSMaskTexture = null;
|
|
1735
|
+
ctx.SSSProfileIdTexture = null;
|
|
1545
1736
|
// ShadowMask sets this only when it produces a texture.
|
|
1546
1737
|
ctx.shadowMaskTexture = null;
|
|
1738
|
+
ctx.transmissionThicknessTexture = null;
|
|
1547
1739
|
// WaterCaustics turns these on together once it has produced a map; they are
|
|
1548
1740
|
// read by every light pass, so they must start cleared each frame.
|
|
1549
1741
|
ctx.waterCaustics = false;
|
|
@@ -1584,6 +1776,10 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
|
|
|
1584
1776
|
const requirements = ctx.compositor?.collectRequirements(ctx) ?? {};
|
|
1585
1777
|
mergeFrameResourceRequirements(requirements, pipeline.collectRequirements(fg));
|
|
1586
1778
|
resolveFrameResourceRequirements(ctx, options, requirements);
|
|
1779
|
+
// Must agree with TransmissionThicknessModule.prepare: the flag decides
|
|
1780
|
+
// whether the light pass declares and binds the thickness texture, so a
|
|
1781
|
+
// mismatch would leave the shader layout disagreeing with the bind group.
|
|
1782
|
+
ctx.transmissionThickness = options.postSSS && renderQueue.shadowedLights.some((light)=>light.transmission);
|
|
1587
1783
|
pipeline.build(fg);
|
|
1588
1784
|
validateProducedFrameResources(blackboard, options, renderQueue);
|
|
1589
1785
|
const presented = blackboard.get(FrameResources.PresentedColor) ?? fg.state.presentedBackbuffer;
|
|
@@ -1680,7 +1876,7 @@ function disposeRenderQueue(frame) {
|
|
|
1680
1876
|
}
|
|
1681
1877
|
function releaseClusteredLight(frame) {
|
|
1682
1878
|
if (!frame.clusteredLightReleased && frame.ctx.clusteredLight) {
|
|
1683
|
-
|
|
1879
|
+
ClusteredLight.release(frame.ctx.clusteredLight);
|
|
1684
1880
|
frame.ctx.clusteredLight = undefined;
|
|
1685
1881
|
frame.clusteredLightReleased = true;
|
|
1686
1882
|
}
|
|
@@ -1714,7 +1910,7 @@ function cleanupFrame(frame) {
|
|
|
1714
1910
|
console.assert(!!existingDepthFb, 'renderSceneDepth: called without an existing depth framebuffer; the ' + 'self-allocating fallback path is untested in the forward+ pipeline.');
|
|
1715
1911
|
if (!depthFramebuffer) {
|
|
1716
1912
|
{
|
|
1717
|
-
const format = ctx.
|
|
1913
|
+
const format = ctx.SSRCalcThickness ? 'rg32f' : 'r32f';
|
|
1718
1914
|
const mvFormat = 'rgba16f';
|
|
1719
1915
|
if (!ctx.finalFramebuffer) {
|
|
1720
1916
|
depthFramebuffer = rgCtx.createFramebuffer({
|
|
@@ -1763,6 +1959,27 @@ function cleanupFrame(frame) {
|
|
|
1763
1959
|
ctx.device.setFramebuffer(depthFramebuffer);
|
|
1764
1960
|
_depthPass.encodeDepth = depthFramebuffer.getColorAttachments()[0].format === 'rgba8unorm';
|
|
1765
1961
|
_depthPass.clearColor = transmission ? null : _depthPass.encodeDepth ? new Vector4(0, 0, 0, 1) : new Vector4(1, 1, 1, 1);
|
|
1962
|
+
// That clear value is chosen for the linear depth target, where 1 is the far
|
|
1963
|
+
// plane. The profile id target needs the opposite: 0 means "not skin", and
|
|
1964
|
+
// every other value addresses a real row of the profile table. Clearing it
|
|
1965
|
+
// alongside the depth made each background texel read as profile 255, so a
|
|
1966
|
+
// sampling disc wide enough to reach past the silhouette accepted those taps
|
|
1967
|
+
// and averaged the background into the skin instead of rejecting it — as
|
|
1968
|
+
// dark speckle, since only the pixels whose sequence happened to draw a
|
|
1969
|
+
// long radius reached that far.
|
|
1970
|
+
//
|
|
1971
|
+
// Assigning clearColor above resets the per-target list, so this has to come
|
|
1972
|
+
// after it; that also means a frame without the target cannot inherit a
|
|
1973
|
+
// stale list.
|
|
1974
|
+
if (!transmission && ctx.sssProfileId) {
|
|
1975
|
+
const attachmentCount = depthFramebuffer.getColorAttachments().length;
|
|
1976
|
+
if (attachmentCount > 1) {
|
|
1977
|
+
// The id is appended last; see DepthPrepassModule.
|
|
1978
|
+
const clearColors = new Array(attachmentCount).fill(_depthPass.clearColor);
|
|
1979
|
+
clearColors[attachmentCount - 1] = SKIN_PROFILE_ID_CLEAR;
|
|
1980
|
+
_depthPass.clearColors = clearColors;
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1766
1983
|
_depthPass.clearDepth = transmission ? null : DEPTH_CLEAR_VALUE;
|
|
1767
1984
|
_depthPass.clearStencil = null;
|
|
1768
1985
|
_depthPass.transmission = transmission;
|
|
@@ -1970,7 +2187,7 @@ function blitToCurrentColorAttachment(ctx, source) {
|
|
|
1970
2187
|
ctx.materialFlags |= MaterialVaryingFlags.SSS_STORE_TRANSMISSION;
|
|
1971
2188
|
}
|
|
1972
2189
|
}
|
|
1973
|
-
if (ctx.
|
|
2190
|
+
if (ctx.SSSMaskTexture) {
|
|
1974
2191
|
ctx.materialFlags |= MaterialVaryingFlags.SKIN_SSS_STORE;
|
|
1975
2192
|
}
|
|
1976
2193
|
// Prefer the graph framebuffer; final-target mode has no graph framebuffer.
|