@zephyr3d/scene 0.9.26 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -27
- package/dist/animation/animation_bank.js +634 -0
- package/dist/animation/animation_bank.js.map +1 -0
- package/dist/animation/animation_bank_gpu.js +256 -0
- package/dist/animation/animation_bank_gpu.js.map +1 -0
- package/dist/animation/animationset.js +146 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_component.js +406 -0
- package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
- package/dist/animation/cloth/gpu_cloth_system.js +332 -202
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/gpu_animation_driver.js +289 -0
- package/dist/animation/gpu_animation_driver.js.map +1 -0
- package/dist/animation/joint_dynamics/collision.js +112 -1
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +6 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +50 -12
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/skeleton.js +300 -56
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skin_palette_atlas.js +252 -0
- package/dist/animation/skin_palette_atlas.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +298 -38
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +2 -0
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +159 -21
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_solver.js +173 -0
- package/dist/animation/spring/spring_solver.js.map +1 -0
- package/dist/animation/spring/spring_system.js +249 -24
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +32 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/app.js +26 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +86 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/gamepad.js +191 -0
- package/dist/app/gamepad.js.map +1 -0
- package/dist/app/inputactions.js +271 -0
- package/dist/app/inputactions.js.map +1 -0
- package/dist/app/inputmgr.js +331 -22
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/loading.js +138 -0
- package/dist/app/loading.js.map +1 -0
- package/dist/app/pipelinecache.js +209 -0
- package/dist/app/pipelinecache.js.map +1 -0
- package/dist/app/runtimescript.js +25 -0
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/scriptingsystem.js +54 -0
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +7 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/asset_manifest.js +59 -0
- package/dist/asset/asset_manifest.js.map +1 -0
- package/dist/asset/asset_preload.js +258 -0
- package/dist/asset/asset_preload.js.map +1 -0
- package/dist/asset/assetmanager.js +117 -65
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/dist/asset/loaders/ktx2/basis_location.js +17 -0
- package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
- package/dist/asset/mesh_lod_builder.js +104 -0
- package/dist/asset/mesh_lod_builder.js.map +1 -0
- package/dist/asset/mesh_settings.js +111 -0
- package/dist/asset/mesh_settings.js.map +1 -0
- package/dist/asset/meshopt_decoder.js +18 -0
- package/dist/asset/meshopt_decoder.js.map +1 -0
- package/dist/asset/meshopt_simplifier.js +26 -0
- package/dist/asset/meshopt_simplifier.js.map +1 -0
- package/dist/asset/model.js +177 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/asset/texture_settings.js +231 -0
- package/dist/asset/texture_settings.js.map +1 -0
- package/dist/asset/zmsh_binary.js +131 -0
- package/dist/asset/zmsh_binary.js.map +1 -0
- package/dist/asset/zsdf_binary.js +111 -0
- package/dist/asset/zsdf_binary.js.map +1 -0
- package/dist/blitter/bilateralblur.js +1 -2
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/gaussianblur.js +1 -6
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +31 -10
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +178 -200
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/follow.js +342 -0
- package/dist/camera/follow.js.map +1 -0
- package/dist/camera/fps.js +9 -7
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +46 -19
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +30475 -19865
- package/dist/index.js +67 -12
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +3 -0
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/eye.js +1 -1
- package/dist/material/eye.js.map +1 -1
- package/dist/material/hair.js +2 -3
- package/dist/material/hair.js.map +1 -1
- package/dist/material/hairstrand.js +235 -235
- package/dist/material/hairstrand.js.map +1 -1
- package/dist/material/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +362 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +118 -45
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +223 -83
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +31 -206
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +1 -1
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrmr.js +3 -0
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +3 -0
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/sdf_debug.js +78 -0
- package/dist/material/sdf_debug.js.map +1 -0
- package/dist/material/shader/helper.js +733 -190
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +204 -43
- package/dist/material/shader/terrain_blend.js.map +1 -1
- package/dist/material/skin.js +331 -297
- package/dist/material/skin.js.map +1 -1
- package/dist/material/skinprofile.js +1058 -0
- package/dist/material/skinprofile.js.map +1 -0
- package/dist/material/sss.js +353 -0
- package/dist/material/sss.js.map +1 -0
- package/dist/material/sss_kernel.js +265 -0
- package/dist/material/sss_kernel.js.map +1 -0
- package/dist/material/sssprofile.js +879 -0
- package/dist/material/sssprofile.js.map +1 -0
- package/dist/material/subsurfaceprofile.js +4 -8
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/terrain-cm.js +464 -188
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js +3 -0
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js +2009 -201
- package/dist/material/water.js.map +1 -1
- package/dist/node_modules/meshoptimizer/LICENSE +21 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
- package/dist/physics/character.js +226 -0
- package/dist/physics/character.js.map +1 -0
- package/dist/physics/collider.js +209 -0
- package/dist/physics/collider.js.map +1 -0
- package/dist/physics/events.js +79 -0
- package/dist/physics/events.js.map +1 -0
- package/dist/physics/joint.js +272 -0
- package/dist/physics/joint.js.map +1 -0
- package/dist/physics/node_physics.js +234 -0
- package/dist/physics/node_physics.js.map +1 -0
- package/dist/physics/part.js +91 -0
- package/dist/physics/part.js.map +1 -0
- package/dist/physics/rigid_body.js +379 -0
- package/dist/physics/rigid_body.js.map +1 -0
- package/dist/physics/vehicle.js +335 -0
- package/dist/physics/vehicle.js.map +1 -0
- package/dist/physics/world.js +25 -0
- package/dist/physics/world.js.map +1 -0
- package/dist/posteffect/bloom.js +49 -14
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/motionblur.js +668 -63
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +12 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +48 -50
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +605 -355
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +91 -162
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -11
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +34 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +1 -0
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +40 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +328 -62
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +958 -224
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +26 -5
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/debug_views.js +37 -0
- package/dist/render/debug_views.js.map +1 -0
- package/dist/render/depthpass.js +5 -1
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +53 -6
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +53 -53
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +196 -113
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +8 -13
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +268 -136
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +113 -28
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/gi/probe_volume.js +1334 -0
- package/dist/render/gi/probe_volume.js.map +1 -0
- package/dist/render/gi/scene_gi.js +282 -0
- package/dist/render/gi/scene_gi.js.map +1 -0
- package/dist/render/gi/voxel_atlas.js +198 -0
- package/dist/render/gi/voxel_atlas.js.map +1 -0
- package/dist/render/gi/voxel_lighting.js +652 -0
- package/dist/render/gi/voxel_lighting.js.map +1 -0
- package/dist/render/gi/voxel_scene.js +642 -0
- package/dist/render/gi/voxel_scene.js.map +1 -0
- package/dist/render/gi/voxelize_pass.js +223 -0
- package/dist/render/gi/voxelize_pass.js.map +1 -0
- package/dist/render/globalbindgroup_allocator.js +3 -2
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/gpu_picking.js +9 -36
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +23 -9
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/lod.js +46 -0
- package/dist/render/lod.js.map +1 -0
- package/dist/render/oit.js +11 -11
- package/dist/render/oit.js.map +1 -1
- package/dist/render/primitive.js +301 -9
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/primitive_readback.js +209 -0
- package/dist/render/primitive_readback.js.map +1 -0
- package/dist/render/render_queue.js +198 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +14 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +15 -1
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/executor.js +136 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +585 -59
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +8 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +31 -2
- package/dist/render/rendergraph/scene_render_context.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +28 -5
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sdf/box_allocator.js +98 -0
- package/dist/render/sdf/box_allocator.js.map +1 -0
- package/dist/render/sdf/global_sdf.js +865 -0
- package/dist/render/sdf/global_sdf.js.map +1 -0
- package/dist/render/sdf/scene_sdf.js +562 -0
- package/dist/render/sdf/scene_sdf.js.map +1 -0
- package/dist/render/sdf/sdf_atlas.js +227 -0
- package/dist/render/sdf/sdf_atlas.js.map +1 -0
- package/dist/render/sdf/sdf_programs.js +42 -0
- package/dist/render/sdf/sdf_programs.js.map +1 -0
- package/dist/render/sdf/sdf_view.js +199 -0
- package/dist/render/sdf/sdf_view.js.map +1 -0
- package/dist/render/sdf/waterline.js +610 -0
- package/dist/render/sdf/waterline.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +142 -25
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/shore_wave_generator.js +1193 -0
- package/dist/render/shore_wave_generator.js.map +1 -0
- package/dist/render/sky.js +516 -86
- package/dist/render/sky.js.map +1 -1
- package/dist/render/transmission_thickness_pass.js +477 -0
- package/dist/render/transmission_thickness_pass.js.map +1 -0
- package/dist/render/underwater.js +524 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/virtualtexture/virtual_texture.js +1214 -0
- package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_common.js +472 -0
- package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
- package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
- package/dist/render/volumetric_cloud/debug_view.js +131 -0
- package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
- package/dist/render/volumetric_cloud/resources.js +380 -0
- package/dist/render/volumetric_cloud/resources.js.map +1 -0
- package/dist/render/volumetric_cloud/sky_cache.js +380 -0
- package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
- package/dist/render/water_caustics.js +1195 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/water_foam.js +627 -0
- package/dist/render/water_foam.js.map +1 -0
- package/dist/render/water_interaction.js +1795 -0
- package/dist/render/water_interaction.js.map +1 -0
- package/dist/render/weightedblended_oit.js +36 -36
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +9 -4
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +108 -12
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +28 -7
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/foliage.js +1020 -0
- package/dist/scene/foliage.js.map +1 -0
- package/dist/scene/foliage_buckets.js +147 -0
- package/dist/scene/foliage_buckets.js.map +1 -0
- package/dist/scene/foliage_mask.js +358 -0
- package/dist/scene/foliage_mask.js.map +1 -0
- package/dist/scene/hair.js +15 -4
- package/dist/scene/hair.js.map +1 -1
- package/dist/scene/light.js +179 -13
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +327 -45
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +9 -3
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +9 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +8 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/physics_settings.js +157 -0
- package/dist/scene/physics_settings.js.map +1 -0
- package/dist/scene/scene.js +190 -44
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +147 -6
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
- package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +881 -42
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grass_gpu.js +929 -0
- package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js +180 -9
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +465 -36
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
- package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
- package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
- package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
- package/dist/scene/update_queue.js +54 -0
- package/dist/scene/update_queue.js.map +1 -0
- package/dist/scene/water.js +997 -96
- package/dist/scene/water.js.map +1 -1
- package/dist/scene/water_surface_sampler.js +324 -0
- package/dist/scene/water_surface_sampler.js.map +1 -0
- package/dist/scene/wind.js +317 -0
- package/dist/scene/wind.js.map +1 -0
- package/dist/shaders/atmosphere.js +388 -166
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +100 -32
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/gi.js +365 -0
- package/dist/shaders/gi.js.map +1 -0
- package/dist/shaders/ltc_rect.js +202 -0
- package/dist/shaders/ltc_rect.js.map +1 -0
- package/dist/shaders/misc.js +1 -10
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +5 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/probes.js +309 -0
- package/dist/shaders/probes.js.map +1 -0
- package/dist/shaders/sdf.js +537 -0
- package/dist/shaders/sdf.js.map +1 -0
- package/dist/shaders/shadow.js +104 -70
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/skin_brdf.js +243 -0
- package/dist/shaders/skin_brdf.js.map +1 -0
- package/dist/shaders/ssr.js +6 -159
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js +38 -27
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +40 -87
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +42 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +110 -19
- package/dist/shadow/dom.js.map +1 -1
- package/dist/shadow/esm.js +3 -3
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -48
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -53
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +34 -9
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +3 -8
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +87 -49
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +93 -53
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +18 -72
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -3
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/shape.js +44 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/utility/buoyancy.js +287 -0
- package/dist/utility/buoyancy.js.map +1 -0
- package/dist/utility/physical.js +10 -1
- package/dist/utility/physical.js.map +1 -1
- package/dist/utility/pmrem.js +17 -43
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/sdf/bake.js +435 -0
- package/dist/utility/sdf/bake.js.map +1 -0
- package/dist/utility/sdf/bvh.js +576 -0
- package/dist/utility/sdf/bvh.js.map +1 -0
- package/dist/utility/serialization/manager.js +36 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +77 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +11 -4
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +140 -279
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth.js +25 -0
- package/dist/utility/serialization/scene/cloth.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +14 -6
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/foliage.js +821 -0
- package/dist/utility/serialization/scene/foliage.js.map +1 -0
- package/dist/utility/serialization/scene/hair.js +11 -4
- package/dist/utility/serialization/scene/hair.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +115 -7
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +388 -220
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +69 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +140 -5
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/node_physics.js +1318 -0
- package/dist/utility/serialization/scene/node_physics.js.map +1 -0
- package/dist/utility/serialization/scene/particle.js +11 -4
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/physics.js +120 -0
- package/dist/utility/serialization/scene/physics.js.map +1 -0
- package/dist/utility/serialization/scene/primitive.js +124 -10
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +1687 -51
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +11 -4
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +163 -33
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +11 -4
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +2473 -114
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +97 -109
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/foam.js +170 -0
- package/dist/utility/textures/foam.js.map +1 -0
- package/dist/utility/textures/ggxlut.js +17 -43
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +4 -4
- package/dist/utility/textures/ltcdata.js.map +1 -1
- package/dist/utility/textures/ltclut.js +16 -6
- package/dist/utility/textures/ltclut.js.map +1 -1
- package/dist/utility/unsupported.js +24 -0
- package/dist/utility/unsupported.js.map +1 -0
- package/dist/values.js +13 -1
- package/dist/values.js.map +1 -1
- package/package.json +25 -12
- package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/src/asset/meshoptimizer/LICENSE +21 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { getDevice } from '../../app/api.js';
|
|
2
|
+
import { VolumeBoxAllocator } from './box_allocator.js';
|
|
3
|
+
|
|
4
|
+
/** Allocation granularity of the atlas in voxels, per axis. */ const SDF_ATLAS_BLOCK = 8;
|
|
5
|
+
/**
|
|
6
|
+
* A 3D `r16f` texture shared by the resident mesh distance fields, each in a block-aligned region
|
|
7
|
+
* from a guillotine allocator. When an allocation no longer fits, everything is repacked on trial
|
|
8
|
+
* and committed only if all fit; uploads are deferred to {@link MeshSDFAtlas.flush} under a byte
|
|
9
|
+
* budget. Works on WebGL2 and WebGPU.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/ class MeshSDFAtlas {
|
|
13
|
+
size;
|
|
14
|
+
_texture;
|
|
15
|
+
_allocator;
|
|
16
|
+
_entries;
|
|
17
|
+
_usedVoxels;
|
|
18
|
+
_version;
|
|
19
|
+
constructor(size = [
|
|
20
|
+
256,
|
|
21
|
+
256,
|
|
22
|
+
256
|
|
23
|
+
]){
|
|
24
|
+
this.size = size.map((v)=>Math.max(SDF_ATLAS_BLOCK, Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK));
|
|
25
|
+
this._texture = null;
|
|
26
|
+
this._allocator = new VolumeBoxAllocator(this.size);
|
|
27
|
+
this._entries = new Map();
|
|
28
|
+
this._usedVoxels = 0;
|
|
29
|
+
this._version = 0;
|
|
30
|
+
}
|
|
31
|
+
/** The atlas texture, created on first use. */ get texture() {
|
|
32
|
+
if (!this._texture) {
|
|
33
|
+
const [w, h, d] = this.size;
|
|
34
|
+
this._texture = getDevice().createTexture3D('r16f', w, h, d, {
|
|
35
|
+
mipmapping: false
|
|
36
|
+
});
|
|
37
|
+
this._texture.name = '@MeshSDFAtlas';
|
|
38
|
+
// Earlier uploads had no texture; redo them
|
|
39
|
+
for (const entry of this._entries.values()){
|
|
40
|
+
entry.uploaded = false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return this._texture;
|
|
44
|
+
}
|
|
45
|
+
/** Fields resident in the atlas. */ get count() {
|
|
46
|
+
return this._entries.size;
|
|
47
|
+
}
|
|
48
|
+
/** Share of the atlas allocated to fields, 0 to 1. */ get occupancy() {
|
|
49
|
+
return this._usedVoxels / (this.size[0] * this.size[1] * this.size[2]);
|
|
50
|
+
}
|
|
51
|
+
/** Bumped whenever a slot moves or is removed, so users of slot offsets can refresh them. */ get version() {
|
|
52
|
+
return this._version;
|
|
53
|
+
}
|
|
54
|
+
/** Fields waiting to be uploaded. */ get pendingUploads() {
|
|
55
|
+
let n = 0;
|
|
56
|
+
for (const entry of this._entries.values()){
|
|
57
|
+
n += entry.uploaded ? 0 : 1;
|
|
58
|
+
}
|
|
59
|
+
return n;
|
|
60
|
+
}
|
|
61
|
+
/** The slot of a resident field, or null. */ getSlot(key) {
|
|
62
|
+
return this._entries.get(key)?.slot ?? null;
|
|
63
|
+
}
|
|
64
|
+
/** True when the field is resident and its voxels are on the GPU. */ isReady(key) {
|
|
65
|
+
return !!this._entries.get(key)?.uploaded;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Allocates a region for a field and queues its upload.
|
|
69
|
+
* @param key - Identity of the field, used to look it up and free it.
|
|
70
|
+
* @param resolution - Voxels per axis.
|
|
71
|
+
* @param voxels - Half floats, x fastest; kept by reference.
|
|
72
|
+
* @returns The slot, or null when the atlas is full.
|
|
73
|
+
*/ add(key, resolution, voxels) {
|
|
74
|
+
const existing = this._entries.get(key);
|
|
75
|
+
if (existing) {
|
|
76
|
+
return existing.slot;
|
|
77
|
+
}
|
|
78
|
+
const need = this.blockAligned(resolution);
|
|
79
|
+
if (need[0] > this.size[0] || need[1] > this.size[1] || need[2] > this.size[2]) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const box = this._allocator.allocate(need) ?? this.repack(need);
|
|
83
|
+
if (!box) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const entry = {
|
|
87
|
+
key,
|
|
88
|
+
slot: {
|
|
89
|
+
offset: [
|
|
90
|
+
box.x,
|
|
91
|
+
box.y,
|
|
92
|
+
box.z
|
|
93
|
+
],
|
|
94
|
+
resolution: [
|
|
95
|
+
...resolution
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
box,
|
|
99
|
+
voxels,
|
|
100
|
+
uploaded: false
|
|
101
|
+
};
|
|
102
|
+
this._entries.set(key, entry);
|
|
103
|
+
this._usedVoxels += box.w * box.h * box.d;
|
|
104
|
+
return entry.slot;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* True when a field of this resolution would fit alongside only the fields of `keep`, packed
|
|
108
|
+
* from scratch. Changes nothing; tells a caller whether evicting is worth it.
|
|
109
|
+
*/ fits(resolution, keep) {
|
|
110
|
+
const sizes = [
|
|
111
|
+
this.blockAligned(resolution)
|
|
112
|
+
];
|
|
113
|
+
for (const key of keep){
|
|
114
|
+
const box = this._entries.get(key)?.box;
|
|
115
|
+
if (box) {
|
|
116
|
+
sizes.push([
|
|
117
|
+
box.w,
|
|
118
|
+
box.h,
|
|
119
|
+
box.d
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
sizes.sort((a, b)=>b[0] * b[1] * b[2] - a[0] * a[1] * a[2]);
|
|
124
|
+
const allocator = new VolumeBoxAllocator(this.size);
|
|
125
|
+
return sizes.every((size)=>!!allocator.allocate(size));
|
|
126
|
+
}
|
|
127
|
+
/** Frees the region of a field. */ remove(key) {
|
|
128
|
+
const entry = this._entries.get(key);
|
|
129
|
+
if (entry) {
|
|
130
|
+
this._entries.delete(key);
|
|
131
|
+
this._allocator.free(entry.box);
|
|
132
|
+
this._usedVoxels -= entry.box.w * entry.box.h * entry.box.d;
|
|
133
|
+
this._version++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Uploads queued fields, nearest-first in the order they were added, until
|
|
138
|
+
* the byte budget is spent. At least one field is uploaded per call.
|
|
139
|
+
* @returns Keys of the fields that became ready.
|
|
140
|
+
*/ flush(byteBudget = 4 * 1024 * 1024) {
|
|
141
|
+
const ready = [];
|
|
142
|
+
let spent = 0;
|
|
143
|
+
for (const entry of this._entries.values()){
|
|
144
|
+
if (entry.uploaded) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const bytes = entry.voxels.byteLength;
|
|
148
|
+
if (ready.length > 0 && spent + bytes > byteBudget) {
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
const [x, y, z] = entry.slot.offset;
|
|
152
|
+
const [w, h, d] = entry.slot.resolution;
|
|
153
|
+
this.texture.update(entry.voxels, x, y, z, w, h, d);
|
|
154
|
+
entry.uploaded = true;
|
|
155
|
+
spent += bytes;
|
|
156
|
+
ready.push(entry.key);
|
|
157
|
+
}
|
|
158
|
+
return ready;
|
|
159
|
+
}
|
|
160
|
+
dispose() {
|
|
161
|
+
this._texture?.dispose();
|
|
162
|
+
this._texture = null;
|
|
163
|
+
this._entries.clear();
|
|
164
|
+
this._allocator.reset();
|
|
165
|
+
this._usedVoxels = 0;
|
|
166
|
+
this._version++;
|
|
167
|
+
}
|
|
168
|
+
/** @internal */ blockAligned(resolution) {
|
|
169
|
+
return resolution.map((v)=>Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Repacks the resident fields plus a new region from scratch, largest first, on a trial
|
|
173
|
+
* allocator; commits only when everything fits, re-uploading only fields that moved.
|
|
174
|
+
* @returns The box of the new region, or null with the atlas unchanged.
|
|
175
|
+
* @internal
|
|
176
|
+
*/ repack(need) {
|
|
177
|
+
const items = [
|
|
178
|
+
{
|
|
179
|
+
entry: null,
|
|
180
|
+
size: need
|
|
181
|
+
},
|
|
182
|
+
...[
|
|
183
|
+
...this._entries.values()
|
|
184
|
+
].map((entry)=>({
|
|
185
|
+
entry,
|
|
186
|
+
size: [
|
|
187
|
+
entry.box.w,
|
|
188
|
+
entry.box.h,
|
|
189
|
+
entry.box.d
|
|
190
|
+
]
|
|
191
|
+
}))
|
|
192
|
+
].sort((a, b)=>b.size[0] * b.size[1] * b.size[2] - a.size[0] * a.size[1] * a.size[2]);
|
|
193
|
+
const allocator = new VolumeBoxAllocator(this.size);
|
|
194
|
+
const boxes = [];
|
|
195
|
+
for (const item of items){
|
|
196
|
+
const box = allocator.allocate(item.size);
|
|
197
|
+
if (!box) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
boxes.push(box);
|
|
201
|
+
}
|
|
202
|
+
this._allocator = allocator;
|
|
203
|
+
this._version++;
|
|
204
|
+
let result = null;
|
|
205
|
+
for(let i = 0; i < items.length; i++){
|
|
206
|
+
const entry = items[i].entry;
|
|
207
|
+
const box = boxes[i];
|
|
208
|
+
if (!entry) {
|
|
209
|
+
result = box;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (entry.box.x !== box.x || entry.box.y !== box.y || entry.box.z !== box.z) {
|
|
213
|
+
entry.slot.offset = [
|
|
214
|
+
box.x,
|
|
215
|
+
box.y,
|
|
216
|
+
box.z
|
|
217
|
+
];
|
|
218
|
+
entry.uploaded = false;
|
|
219
|
+
}
|
|
220
|
+
entry.box = box;
|
|
221
|
+
}
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export { MeshSDFAtlas, SDF_ATLAS_BLOCK };
|
|
227
|
+
//# sourceMappingURL=sdf_atlas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdf_atlas.js","sources":["../../../src/render/sdf/sdf_atlas.ts"],"sourcesContent":["import type { Texture3D } from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { getDevice } from '../../app/api';\r\nimport { VolumeBoxAllocator } from './box_allocator';\r\nimport type { VolumeBox } from './box_allocator';\r\n\r\n/** Allocation granularity of the atlas in voxels, per axis. */\r\nexport const SDF_ATLAS_BLOCK = 8;\r\n\r\n/**\r\n * A region of the atlas holding one mesh field.\r\n * @public\r\n */\r\nexport interface MeshSDFAtlasSlot {\r\n /** Voxel offset of the region in the atlas. */\r\n offset: [number, number, number];\r\n /** Voxels of the field, at most the region size. */\r\n resolution: [number, number, number];\r\n}\r\n\r\ninterface Entry {\r\n key: object;\r\n slot: MeshSDFAtlasSlot;\r\n box: VolumeBox;\r\n voxels: Uint16Array<ArrayBuffer>;\r\n uploaded: boolean;\r\n}\r\n\r\n/**\r\n * A 3D `r16f` texture shared by the resident mesh distance fields, each in a block-aligned region\r\n * from a guillotine allocator. When an allocation no longer fits, everything is repacked on trial\r\n * and committed only if all fit; uploads are deferred to {@link MeshSDFAtlas.flush} under a byte\r\n * budget. Works on WebGL2 and WebGPU.\r\n *\r\n * @public\r\n */\r\nexport class MeshSDFAtlas {\r\n readonly size: [number, number, number];\r\n private _texture: Nullable<Texture3D>;\r\n private _allocator: VolumeBoxAllocator;\r\n private readonly _entries: Map<object, Entry>;\r\n private _usedVoxels: number;\r\n private _version: number;\r\n constructor(size: [number, number, number] = [256, 256, 256]) {\r\n this.size = size.map((v) =>\r\n Math.max(SDF_ATLAS_BLOCK, Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK)\r\n ) as [number, number, number];\r\n this._texture = null;\r\n this._allocator = new VolumeBoxAllocator(this.size);\r\n this._entries = new Map();\r\n this._usedVoxels = 0;\r\n this._version = 0;\r\n }\r\n /** The atlas texture, created on first use. */\r\n get texture() {\r\n if (!this._texture) {\r\n const [w, h, d] = this.size;\r\n this._texture = getDevice().createTexture3D('r16f', w, h, d, { mipmapping: false })!;\r\n this._texture.name = '@MeshSDFAtlas';\r\n // Earlier uploads had no texture; redo them\r\n for (const entry of this._entries.values()) {\r\n entry.uploaded = false;\r\n }\r\n }\r\n return this._texture;\r\n }\r\n /** Fields resident in the atlas. */\r\n get count() {\r\n return this._entries.size;\r\n }\r\n /** Share of the atlas allocated to fields, 0 to 1. */\r\n get occupancy() {\r\n return this._usedVoxels / (this.size[0] * this.size[1] * this.size[2]);\r\n }\r\n /** Bumped whenever a slot moves or is removed, so users of slot offsets can refresh them. */\r\n get version() {\r\n return this._version;\r\n }\r\n /** Fields waiting to be uploaded. */\r\n get pendingUploads() {\r\n let n = 0;\r\n for (const entry of this._entries.values()) {\r\n n += entry.uploaded ? 0 : 1;\r\n }\r\n return n;\r\n }\r\n /** The slot of a resident field, or null. */\r\n getSlot(key: object) {\r\n return this._entries.get(key)?.slot ?? null;\r\n }\r\n /** True when the field is resident and its voxels are on the GPU. */\r\n isReady(key: object) {\r\n return !!this._entries.get(key)?.uploaded;\r\n }\r\n /**\r\n * Allocates a region for a field and queues its upload.\r\n * @param key - Identity of the field, used to look it up and free it.\r\n * @param resolution - Voxels per axis.\r\n * @param voxels - Half floats, x fastest; kept by reference.\r\n * @returns The slot, or null when the atlas is full.\r\n */\r\n add(\r\n key: object,\r\n resolution: [number, number, number],\r\n voxels: Uint16Array<ArrayBuffer>\r\n ): Nullable<MeshSDFAtlasSlot> {\r\n const existing = this._entries.get(key);\r\n if (existing) {\r\n return existing.slot;\r\n }\r\n const need = this.blockAligned(resolution);\r\n if (need[0] > this.size[0] || need[1] > this.size[1] || need[2] > this.size[2]) {\r\n return null;\r\n }\r\n const box = this._allocator.allocate(need) ?? this.repack(need);\r\n if (!box) {\r\n return null;\r\n }\r\n const entry: Entry = {\r\n key,\r\n slot: { offset: [box.x, box.y, box.z], resolution: [...resolution] },\r\n box,\r\n voxels,\r\n uploaded: false\r\n };\r\n this._entries.set(key, entry);\r\n this._usedVoxels += box.w * box.h * box.d;\r\n return entry.slot;\r\n }\r\n /**\r\n * True when a field of this resolution would fit alongside only the fields of `keep`, packed\r\n * from scratch. Changes nothing; tells a caller whether evicting is worth it.\r\n */\r\n fits(resolution: [number, number, number], keep: Iterable<object>) {\r\n const sizes: [number, number, number][] = [this.blockAligned(resolution)];\r\n for (const key of keep) {\r\n const box = this._entries.get(key)?.box;\r\n if (box) {\r\n sizes.push([box.w, box.h, box.d]);\r\n }\r\n }\r\n sizes.sort((a, b) => b[0] * b[1] * b[2] - a[0] * a[1] * a[2]);\r\n const allocator = new VolumeBoxAllocator(this.size);\r\n return sizes.every((size) => !!allocator.allocate(size));\r\n }\r\n /** Frees the region of a field. */\r\n remove(key: object) {\r\n const entry = this._entries.get(key);\r\n if (entry) {\r\n this._entries.delete(key);\r\n this._allocator.free(entry.box);\r\n this._usedVoxels -= entry.box.w * entry.box.h * entry.box.d;\r\n this._version++;\r\n }\r\n }\r\n /**\r\n * Uploads queued fields, nearest-first in the order they were added, until\r\n * the byte budget is spent. At least one field is uploaded per call.\r\n * @returns Keys of the fields that became ready.\r\n */\r\n flush(byteBudget = 4 * 1024 * 1024) {\r\n const ready: object[] = [];\r\n let spent = 0;\r\n for (const entry of this._entries.values()) {\r\n if (entry.uploaded) {\r\n continue;\r\n }\r\n const bytes = entry.voxels.byteLength;\r\n if (ready.length > 0 && spent + bytes > byteBudget) {\r\n break;\r\n }\r\n const [x, y, z] = entry.slot.offset;\r\n const [w, h, d] = entry.slot.resolution;\r\n this.texture.update(entry.voxels, x, y, z, w, h, d);\r\n entry.uploaded = true;\r\n spent += bytes;\r\n ready.push(entry.key);\r\n }\r\n return ready;\r\n }\r\n dispose() {\r\n this._texture?.dispose();\r\n this._texture = null;\r\n this._entries.clear();\r\n this._allocator.reset();\r\n this._usedVoxels = 0;\r\n this._version++;\r\n }\r\n /** @internal */\r\n private blockAligned(resolution: [number, number, number]) {\r\n return resolution.map((v) => Math.ceil(v / SDF_ATLAS_BLOCK) * SDF_ATLAS_BLOCK) as [\r\n number,\r\n number,\r\n number\r\n ];\r\n }\r\n /**\r\n * Repacks the resident fields plus a new region from scratch, largest first, on a trial\r\n * allocator; commits only when everything fits, re-uploading only fields that moved.\r\n * @returns The box of the new region, or null with the atlas unchanged.\r\n * @internal\r\n */\r\n private repack(need: [number, number, number]): Nullable<VolumeBox> {\r\n const items: { entry: Nullable<Entry>; size: [number, number, number] }[] = [\r\n { entry: null, size: need },\r\n ...[...this._entries.values()].map((entry) => ({\r\n entry,\r\n size: [entry.box.w, entry.box.h, entry.box.d] as [number, number, number]\r\n }))\r\n ].sort((a, b) => b.size[0] * b.size[1] * b.size[2] - a.size[0] * a.size[1] * a.size[2]);\r\n const allocator = new VolumeBoxAllocator(this.size);\r\n const boxes: VolumeBox[] = [];\r\n for (const item of items) {\r\n const box = allocator.allocate(item.size);\r\n if (!box) {\r\n return null;\r\n }\r\n boxes.push(box);\r\n }\r\n this._allocator = allocator;\r\n this._version++;\r\n let result: Nullable<VolumeBox> = null;\r\n for (let i = 0; i < items.length; i++) {\r\n const entry = items[i].entry;\r\n const box = boxes[i];\r\n if (!entry) {\r\n result = box;\r\n continue;\r\n }\r\n if (entry.box.x !== box.x || entry.box.y !== box.y || entry.box.z !== box.z) {\r\n entry.slot.offset = [box.x, box.y, box.z];\r\n entry.uploaded = false;\r\n }\r\n entry.box = box;\r\n }\r\n return result;\r\n }\r\n}\r\n"],"names":["SDF_ATLAS_BLOCK","MeshSDFAtlas","size","_texture","_allocator","_entries","_usedVoxels","_version","map","v","Math","max","ceil","VolumeBoxAllocator","Map","texture","w","h","d","getDevice","createTexture3D","mipmapping","name","entry","values","uploaded","count","occupancy","version","pendingUploads","n","getSlot","key","get","slot","isReady","add","resolution","voxels","existing","need","blockAligned","box","allocate","repack","offset","x","y","z","set","fits","keep","sizes","push","sort","a","b","allocator","every","remove","delete","free","flush","byteBudget","ready","spent","bytes","byteLength","length","update","dispose","clear","reset","items","boxes","item","result","i"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getDevice } from '../../app/api.js';
|
|
2
|
+
|
|
3
|
+
/** Programs of the SDF system by label, with the error that stopped one, if any. */ const programs = new Map();
|
|
4
|
+
const buildErrors = new Map();
|
|
5
|
+
/**
|
|
6
|
+
* Builds a program of the SDF system and records the outcome under its label. Throws on a shader
|
|
7
|
+
* builder error (which the device reports only as a null program) so the message is kept.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/ function buildSDFProgram(options) {
|
|
11
|
+
const device = getDevice();
|
|
12
|
+
const label = options.label ?? 'SDF';
|
|
13
|
+
const program = 'compute' in options ? device.buildComputeProgram(options) : device.buildRenderProgram(options);
|
|
14
|
+
programs.set(label, program);
|
|
15
|
+
if (!program) {
|
|
16
|
+
const err = device.programBuilder.lastError || 'unknown shader builder error';
|
|
17
|
+
buildErrors.set(label, err);
|
|
18
|
+
throw new Error(`${label}: ${err}`);
|
|
19
|
+
}
|
|
20
|
+
buildErrors.delete(label);
|
|
21
|
+
return program;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Errors of the SDF system's programs by label: shader builder errors and
|
|
25
|
+
* WGSL compile errors. Empty when everything built.
|
|
26
|
+
* @public
|
|
27
|
+
*/ function getSDFProgramErrors() {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const [label, err] of buildErrors){
|
|
30
|
+
out[label] = err;
|
|
31
|
+
}
|
|
32
|
+
for (const [label, program] of programs){
|
|
33
|
+
const err = program?.getCompileError();
|
|
34
|
+
if (err) {
|
|
35
|
+
out[label] = err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { buildSDFProgram, getSDFProgramErrors };
|
|
42
|
+
//# sourceMappingURL=sdf_programs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdf_programs.js","sources":["../../../src/render/sdf/sdf_programs.ts"],"sourcesContent":["import type { GPUProgram, PBComputeOptions, PBRenderOptions } from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { getDevice } from '../../app/api';\r\n\r\n/** Programs of the SDF system by label, with the error that stopped one, if any. */\r\nconst programs = new Map<string, Nullable<GPUProgram>>();\r\nconst buildErrors = new Map<string, string>();\r\n\r\n/**\r\n * Builds a program of the SDF system and records the outcome under its label. Throws on a shader\r\n * builder error (which the device reports only as a null program) so the message is kept.\r\n *\r\n * @internal\r\n */\r\nexport function buildSDFProgram(options: PBComputeOptions | PBRenderOptions): GPUProgram {\r\n const device = getDevice();\r\n const label = options.label ?? 'SDF';\r\n const program =\r\n 'compute' in options\r\n ? device.buildComputeProgram(options as PBComputeOptions)\r\n : device.buildRenderProgram(options as PBRenderOptions);\r\n programs.set(label, program);\r\n if (!program) {\r\n const err = device.programBuilder.lastError || 'unknown shader builder error';\r\n buildErrors.set(label, err);\r\n throw new Error(`${label}: ${err}`);\r\n }\r\n buildErrors.delete(label);\r\n return program;\r\n}\r\n\r\n/**\r\n * Errors of the SDF system's programs by label: shader builder errors and\r\n * WGSL compile errors. Empty when everything built.\r\n * @public\r\n */\r\nexport function getSDFProgramErrors(): Record<string, string> {\r\n const out: Record<string, string> = {};\r\n for (const [label, err] of buildErrors) {\r\n out[label] = err;\r\n }\r\n for (const [label, program] of programs) {\r\n const err = program?.getCompileError();\r\n if (err) {\r\n out[label] = err;\r\n }\r\n }\r\n return out;\r\n}\r\n"],"names":["programs","Map","buildErrors","buildSDFProgram","options","device","getDevice","label","program","buildComputeProgram","buildRenderProgram","set","err","programBuilder","lastError","Error","delete","getSDFProgramErrors","out","getCompileError"],"mappings":";;AAIA,qFACA,MAAMA,QAAAA,GAAW,IAAIC,GAAAA,EAAAA;AACrB,MAAMC,cAAc,IAAID,GAAAA,EAAAA;AAExB;;;;;IAMO,SAASE,eAAAA,CAAgBC,OAA2C,EAAA;AACzE,IAAA,MAAMC,MAASC,GAAAA,SAAAA,EAAAA;IACf,MAAMC,KAAAA,GAAQH,OAAQG,CAAAA,KAAK,IAAI,KAAA;IAC/B,MAAMC,OAAAA,GACJ,aAAaJ,OACTC,GAAAA,MAAAA,CAAOI,mBAAmB,CAACL,OAAAA,CAAAA,GAC3BC,MAAOK,CAAAA,kBAAkB,CAACN,OAAAA,CAAAA;IAChCJ,QAASW,CAAAA,GAAG,CAACJ,KAAOC,EAAAA,OAAAA,CAAAA;AACpB,IAAA,IAAI,CAACA,OAAS,EAAA;AACZ,QAAA,MAAMI,GAAMP,GAAAA,MAAAA,CAAOQ,cAAc,CAACC,SAAS,IAAI,8BAAA;QAC/CZ,WAAYS,CAAAA,GAAG,CAACJ,KAAOK,EAAAA,GAAAA,CAAAA;AACvB,QAAA,MAAM,IAAIG,KAAM,CAAA,CAAA,EAAGR,KAAM,CAAA,EAAE,EAAEK,GAAK,CAAA,CAAA,CAAA;AACpC;AACAV,IAAAA,WAAAA,CAAYc,MAAM,CAACT,KAAAA,CAAAA;IACnB,OAAOC,OAAAA;AACT;AAEA;;;;AAIC,IACM,SAASS,mBAAAA,GAAAA;AACd,IAAA,MAAMC,MAA8B,EAAC;AACrC,IAAA,KAAK,MAAM,CAACX,KAAOK,EAAAA,GAAAA,CAAI,IAAIV,WAAa,CAAA;QACtCgB,GAAG,CAACX,MAAM,GAAGK,GAAAA;AACf;AACA,IAAA,KAAK,MAAM,CAACL,KAAOC,EAAAA,OAAAA,CAAQ,IAAIR,QAAU,CAAA;AACvC,QAAA,MAAMY,MAAMJ,OAASW,EAAAA,eAAAA,EAAAA;AACrB,QAAA,IAAIP,GAAK,EAAA;YACPM,GAAG,CAACX,MAAM,GAAGK,GAAAA;AACf;AACF;IACA,OAAOM,GAAAA;AACT;;;;"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { Vector3, Vector4 } from '@zephyr3d/base';
|
|
2
|
+
import { getDevice } from '../../app/api.js';
|
|
3
|
+
import { drawFullscreenQuad } from '../fullscreenquad.js';
|
|
4
|
+
import { declareGlobalSDFUniforms, declareDynamicSDFUniforms, sampleSceneSDFHinted, sdfSurfaceExpand, sdfRefineHit, sampleSceneSDF, sampleGlobalSDF } from '../../shaders/sdf.js';
|
|
5
|
+
import { VOXEL_SCENE_ALBEDO, VOXEL_SCENE_EMISSIVE, VOXEL_SCENE_RADIANCE, VOXEL_SCENE_ANISO0, VOXEL_SCENE_ANISO1, declareVoxelSceneUniforms, voxelSceneTexel, loadVoxelSceneAlbedo, loadVoxelSceneEmissive, sampleVoxelSceneRadiance } from '../../shaders/gi.js';
|
|
6
|
+
import { buildSDFProgram } from './sdf_programs.js';
|
|
7
|
+
import { fetchSampler } from '../../utility/misc.js';
|
|
8
|
+
import { declareProbeUniforms, sampleProbeIrradiance } from '../../shaders/probes.js';
|
|
9
|
+
import { getActiveProbeVolume } from '../gi/probe_volume.js';
|
|
10
|
+
|
|
11
|
+
/** True for the modes that read the probe volume rather than the voxel scene. */ function readsProbes(mode) {
|
|
12
|
+
return mode === 'skyVisibility' || mode === 'irradiance';
|
|
13
|
+
}
|
|
14
|
+
/** Sphere tracing steps per pixel. */ const MAX_STEPS = 128;
|
|
15
|
+
const programs = new Map();
|
|
16
|
+
let renderStates = null;
|
|
17
|
+
function getProgram(levels, mode) {
|
|
18
|
+
const key = `${levels}:${mode}`;
|
|
19
|
+
let entry = programs.get(key);
|
|
20
|
+
if (!entry) {
|
|
21
|
+
const device = getDevice();
|
|
22
|
+
const program = buildSDFProgram({
|
|
23
|
+
label: `SceneSDFView:${mode}`,
|
|
24
|
+
vertex (pb) {
|
|
25
|
+
this.$inputs.pos = pb.vec2().attrib('position');
|
|
26
|
+
this.$outputs.uv = pb.vec2();
|
|
27
|
+
pb.main(function() {
|
|
28
|
+
this.$builtins.position = pb.vec4(this.$inputs.pos, 0, 1);
|
|
29
|
+
this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
fragment (pb) {
|
|
33
|
+
this.$outputs.color = pb.vec4();
|
|
34
|
+
this.invViewProj = pb.mat4().uniform(0);
|
|
35
|
+
// (camera position, trace distance)
|
|
36
|
+
this.cameraInfo = pb.vec4().uniform(0);
|
|
37
|
+
// (exposure of the radiance and irradiance views, 0, 0, 0)
|
|
38
|
+
this.viewInfo = pb.vec4().uniform(0);
|
|
39
|
+
declareGlobalSDFUniforms(this, 0, levels);
|
|
40
|
+
declareDynamicSDFUniforms(this, 0);
|
|
41
|
+
if (readsProbes(mode)) {
|
|
42
|
+
declareProbeUniforms(this, 0);
|
|
43
|
+
} else if (mode !== 'distance') {
|
|
44
|
+
declareVoxelSceneUniforms(this, 0);
|
|
45
|
+
}
|
|
46
|
+
pb.main(function() {
|
|
47
|
+
// A point on the pixel's ray; clip z 0.5 lies in front on either depth convention
|
|
48
|
+
this.$l.h = pb.mul(this.invViewProj, pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), 0.5, 1));
|
|
49
|
+
this.$l.dir = pb.normalize(pb.sub(pb.div(this.h.xyz, this.h.w), this.cameraInfo.xyz));
|
|
50
|
+
this.$l.t = pb.float(0);
|
|
51
|
+
this.$l.steps = pb.float(0);
|
|
52
|
+
this.$l.hit = false;
|
|
53
|
+
this.$l.prevD = pb.float(0);
|
|
54
|
+
this.$l.hitT = pb.float(0);
|
|
55
|
+
this.$for(pb.int('i'), 0, MAX_STEPS, function() {
|
|
56
|
+
this.$l.sp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));
|
|
57
|
+
this.$l.s = sampleSceneSDFHinted(this, this.sp, this.prevD, levels);
|
|
58
|
+
this.$l.d = this.s.x;
|
|
59
|
+
this.prevD = this.d;
|
|
60
|
+
this.steps = pb.add(this.steps, 1);
|
|
61
|
+
// Same hit test as GI rays (surfaces swollen by a voxel). Probe views read at the
|
|
62
|
+
// refined surface; voxel views read where the trace stopped, since the voxel nearest
|
|
63
|
+
// the surface often lies inside geometry and holds no light
|
|
64
|
+
this.$l.expand = sdfSurfaceExpand(this, this.sp, this.s, this.t, levels);
|
|
65
|
+
this.$if(pb.lessThan(this.d, this.expand), function() {
|
|
66
|
+
this.hitT = sdfRefineHit(this, this.cameraInfo.xyz, this.dir, this.t, this.d, this.s.y, pb.int(0), levels);
|
|
67
|
+
this.hit = true;
|
|
68
|
+
this.$break();
|
|
69
|
+
});
|
|
70
|
+
this.t = pb.add(this.t, pb.max(this.d, 0.02));
|
|
71
|
+
this.$if(pb.greaterThan(this.t, this.cameraInfo.w), function() {
|
|
72
|
+
this.$break();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
// Brightness from step count, so grazing silhouettes glow
|
|
76
|
+
this.$l.k = pb.sqrt(pb.div(this.steps, MAX_STEPS));
|
|
77
|
+
this.$l.miss = pb.vec4(pb.mix(pb.vec3(0.12, 0.12, 0.55), pb.vec3(0.85), this.k), 1);
|
|
78
|
+
if (mode === 'distance') {
|
|
79
|
+
this.$outputs.color = this.$choice(this.hit, pb.vec4(pb.vec3(pb.mix(0.08, 1, this.k)), 1), this.miss);
|
|
80
|
+
} else if (readsProbes(mode)) {
|
|
81
|
+
this.$outputs.color = this.miss;
|
|
82
|
+
this.$if(this.hit, function() {
|
|
83
|
+
// On the field's own surface, where the depth buffer would put a fragment
|
|
84
|
+
this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.hitT));
|
|
85
|
+
this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);
|
|
86
|
+
this.$l.n = pb.normalize(pb.vec3(pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels))));
|
|
87
|
+
if (mode === 'skyVisibility') {
|
|
88
|
+
// Unshaded: white sees the whole sky, black none; magenta where no probe covers
|
|
89
|
+
this.$l.sv = sampleProbeIrradiance(this, this.hp, this.n, pb.sub(this.cameraInfo.xyz, this.hp), 'sky');
|
|
90
|
+
this.$outputs.color = this.$choice(pb.greaterThan(this.sv.a, 0), pb.vec4(this.sv.rgb, 1), pb.vec4(1, 0, 1, 1));
|
|
91
|
+
} else {
|
|
92
|
+
// Irradiance (E/pi) at the view's exposure, unshaded; magenta where no probe covers
|
|
93
|
+
this.$l.irr = sampleProbeIrradiance(this, this.hp, this.n, pb.sub(this.cameraInfo.xyz, this.hp));
|
|
94
|
+
this.$l.ev = pb.mul(this.irr.rgb, this.viewInfo.x);
|
|
95
|
+
this.$outputs.color = this.$choice(pb.greaterThan(this.irr.a, 0), pb.vec4(pb.div(this.ev, pb.add(this.ev, pb.vec3(1))), 1), pb.vec4(1, 0, 1, 1));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
this.$outputs.color = this.miss;
|
|
100
|
+
this.$if(this.hit, function() {
|
|
101
|
+
this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));
|
|
102
|
+
this.$l.texel = voxelSceneTexel(this, this.hp, levels);
|
|
103
|
+
if (mode === 'albedo') {
|
|
104
|
+
// Lit by a head light from the field's gradient, so shape reads
|
|
105
|
+
this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);
|
|
106
|
+
this.$l.n = pb.normalize(pb.vec3(pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels))));
|
|
107
|
+
this.$l.a = loadVoxelSceneAlbedo(this, this.texel);
|
|
108
|
+
this.$l.shade = pb.add(0.25, pb.mul(0.75, pb.max(pb.dot(this.n, pb.neg(this.dir)), 0)));
|
|
109
|
+
// No material: magenta outside every current window, orange for a dynamic
|
|
110
|
+
// instance (not voxelized), else cyan/yellow/white by clipmap level 0/1/2+
|
|
111
|
+
this.$l.staticD = sampleGlobalSDF(this, this.hp, levels);
|
|
112
|
+
this.$l.dynamicHit = pb.greaterThan(this.staticD, pb.add(0.05, pb.mul(this.t, 0.004)));
|
|
113
|
+
this.$l.flag = this.$choice(pb.lessThan(this.texel.w, 0), pb.vec3(1, 0, 1), this.$choice(this.dynamicHit, pb.vec3(1, 0.5, 0), this.$choice(pb.equal(this.texel.w, 0), pb.vec3(0, 1, 1), this.$choice(pb.equal(this.texel.w, 1), pb.vec3(1, 1, 0), pb.vec3(1)))));
|
|
114
|
+
this.$outputs.color = this.$choice(pb.greaterThan(this.a.a, 0), pb.vec4(pb.mul(this.a.rgb, this.shade), 1), pb.vec4(pb.mul(this.flag, this.shade), 1));
|
|
115
|
+
} else if (mode === 'emissive') {
|
|
116
|
+
this.$l.em = loadVoxelSceneEmissive(this, this.texel);
|
|
117
|
+
this.$outputs.color = pb.vec4(pb.div(this.em, pb.add(this.em, pb.vec3(1))), 1);
|
|
118
|
+
} else {
|
|
119
|
+
// The radiance toward the side the view ray hit, as a probe ray reads it
|
|
120
|
+
this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);
|
|
121
|
+
this.$l.n = pb.normalize(pb.vec3(pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)), pb.sub(sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels), sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels))));
|
|
122
|
+
this.$l.rad = pb.mul(sampleVoxelSceneRadiance(this, this.hp, this.n, levels), this.viewInfo.x);
|
|
123
|
+
this.$outputs.color = pb.vec4(pb.div(this.rad, pb.add(this.rad, pb.vec3(1))), 1);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
program.name = `@SceneSDFView_${mode}`;
|
|
131
|
+
entry = {
|
|
132
|
+
program,
|
|
133
|
+
bindGroup: device.createBindGroup(program.bindGroupLayouts[0])
|
|
134
|
+
};
|
|
135
|
+
programs.set(key, entry);
|
|
136
|
+
}
|
|
137
|
+
return entry;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Debug-draws the scene's signed distance field from a camera over the current framebuffer:
|
|
141
|
+
* each pixel sphere traces the field and is shaded by step count, or by the voxel scene /
|
|
142
|
+
* probe volume at the hit for other modes (falling back to `distance` when unavailable).
|
|
143
|
+
* `exposure` scales `radiance` and `irradiance`; magenta marks uncovered points. Call after the
|
|
144
|
+
* camera has rendered; does nothing without a field (disabled or WebGL2).
|
|
145
|
+
*
|
|
146
|
+
* @returns Whether it drew.
|
|
147
|
+
* @public
|
|
148
|
+
*/ function renderSceneSDFView(scene, camera, mode = 'distance', exposure = 1) {
|
|
149
|
+
const sdf = scene.sdf.enabled ? scene.sdf.global : null;
|
|
150
|
+
if (!sdf) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
const probes = readsProbes(mode) && scene.gi.enabled ? getActiveProbeVolume(scene) : null;
|
|
154
|
+
const voxels = mode !== 'distance' && !readsProbes(mode) && scene.gi.enabled ? scene.gi.voxels : null;
|
|
155
|
+
if (readsProbes(mode) ? !probes : !voxels?.ready || mode === 'radiance' && !voxels.lit) {
|
|
156
|
+
mode = 'distance';
|
|
157
|
+
}
|
|
158
|
+
const device = getDevice();
|
|
159
|
+
const { program, bindGroup } = getProgram(sdf.levels, mode);
|
|
160
|
+
if (!renderStates) {
|
|
161
|
+
renderStates = device.createRenderStateSet();
|
|
162
|
+
renderStates.useDepthState().enableTest(false).enableWrite(false);
|
|
163
|
+
renderStates.useRasterizerState().setCullMode('none');
|
|
164
|
+
}
|
|
165
|
+
const pos = camera.getWorldPosition(new Vector3());
|
|
166
|
+
bindGroup.setValue('invViewProj', camera.invViewProjectionMatrix);
|
|
167
|
+
// As far as the coarsest level reaches from the camera
|
|
168
|
+
bindGroup.setValue('cameraInfo', new Vector4(pos.x, pos.y, pos.z, sdf.resolution * sdf.voxelSize(sdf.levels - 1)));
|
|
169
|
+
bindGroup.setValue('viewInfo', new Vector4(exposure, 0, 0, 0));
|
|
170
|
+
sdf.applyBindGroup(bindGroup);
|
|
171
|
+
if (probes && readsProbes(mode)) {
|
|
172
|
+
probes.applyBindGroup(bindGroup);
|
|
173
|
+
}
|
|
174
|
+
if (voxels && mode !== 'distance' && !readsProbes(mode)) {
|
|
175
|
+
bindGroup.setTexture(VOXEL_SCENE_ALBEDO, voxels.albedo, fetchSampler('clamp_nearest_nomip'));
|
|
176
|
+
bindGroup.setTexture(VOXEL_SCENE_EMISSIVE, voxels.emissive, fetchSampler('clamp_nearest_nomip'));
|
|
177
|
+
// The layout declares all three; before the first lighting pass stand-ins are bound
|
|
178
|
+
bindGroup.setTexture(VOXEL_SCENE_RADIANCE, voxels.lit ? voxels.radiance : voxels.emissive, fetchSampler('clamp_nearest_nomip'));
|
|
179
|
+
bindGroup.setTexture(VOXEL_SCENE_ANISO0, voxels.lit ? voxels.radianceAniso0 : voxels.albedo, fetchSampler('clamp_nearest_nomip'));
|
|
180
|
+
bindGroup.setTexture(VOXEL_SCENE_ANISO1, voxels.lit ? voxels.radianceAniso1 : voxels.albedo, fetchSampler('clamp_nearest_nomip'));
|
|
181
|
+
}
|
|
182
|
+
device.pushDeviceStates();
|
|
183
|
+
try {
|
|
184
|
+
const vp = camera.viewport;
|
|
185
|
+
if (vp) {
|
|
186
|
+
device.setViewport(vp);
|
|
187
|
+
device.setScissor(vp);
|
|
188
|
+
}
|
|
189
|
+
device.setProgram(program);
|
|
190
|
+
device.setBindGroup(0, bindGroup);
|
|
191
|
+
drawFullscreenQuad(renderStates);
|
|
192
|
+
} finally{
|
|
193
|
+
device.popDeviceStates();
|
|
194
|
+
}
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export { renderSceneSDFView };
|
|
199
|
+
//# sourceMappingURL=sdf_view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdf_view.js","sources":["../../../src/render/sdf/sdf_view.ts"],"sourcesContent":["import type { BindGroup, GPUProgram, RenderStateSet } from '@zephyr3d/device';\r\nimport { Vector3, Vector4 } from '@zephyr3d/base';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { getDevice } from '../../app/api';\r\nimport type { Camera } from '../../camera/camera';\r\nimport type { Scene } from '../../scene/scene';\r\nimport { drawFullscreenQuad } from '../fullscreenquad';\r\nimport {\r\n declareDynamicSDFUniforms,\r\n declareGlobalSDFUniforms,\r\n sampleGlobalSDF,\r\n sampleSceneSDF,\r\n sampleSceneSDFHinted,\r\n sdfRefineHit,\r\n sdfSurfaceExpand\r\n} from '../../shaders/sdf';\r\nimport {\r\n declareVoxelSceneUniforms,\r\n loadVoxelSceneAlbedo,\r\n loadVoxelSceneEmissive,\r\n sampleVoxelSceneRadiance,\r\n VOXEL_SCENE_ALBEDO,\r\n VOXEL_SCENE_EMISSIVE,\r\n VOXEL_SCENE_RADIANCE,\r\n VOXEL_SCENE_ANISO0,\r\n VOXEL_SCENE_ANISO1,\r\n voxelSceneTexel\r\n} from '../../shaders/gi';\r\nimport { buildSDFProgram } from './sdf_programs';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { declareProbeUniforms, sampleProbeIrradiance } from '../../shaders/probes';\r\nimport { getActiveProbeVolume } from '../gi/probe_volume';\r\n\r\n/**\r\n * What {@link renderSceneSDFView} shows: step count, voxel scene albedo/emissive/radiance at the\r\n * hit, or probe sky visibility/irradiance there.\r\n * @public\r\n */\r\nexport type SceneSDFViewMode =\r\n | 'distance'\r\n | 'albedo'\r\n | 'emissive'\r\n | 'radiance'\r\n | 'skyVisibility'\r\n | 'irradiance';\r\n\r\n/** True for the modes that read the probe volume rather than the voxel scene. */\r\nfunction readsProbes(mode: SceneSDFViewMode) {\r\n return mode === 'skyVisibility' || mode === 'irradiance';\r\n}\r\n\r\n/** Sphere tracing steps per pixel. */\r\nconst MAX_STEPS = 128;\r\n\r\nconst programs = new Map<string, { program: GPUProgram; bindGroup: BindGroup }>();\r\nlet renderStates: Nullable<RenderStateSet> = null;\r\n\r\nfunction getProgram(levels: number, mode: SceneSDFViewMode) {\r\n const key = `${levels}:${mode}`;\r\n let entry = programs.get(key);\r\n if (!entry) {\r\n const device = getDevice();\r\n const program = buildSDFProgram({\r\n label: `SceneSDFView:${mode}`,\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$outputs.uv = pb.vec2();\r\n pb.main(function () {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, 0, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n this.invViewProj = pb.mat4().uniform(0);\r\n // (camera position, trace distance)\r\n this.cameraInfo = pb.vec4().uniform(0);\r\n // (exposure of the radiance and irradiance views, 0, 0, 0)\r\n this.viewInfo = pb.vec4().uniform(0);\r\n declareGlobalSDFUniforms(this, 0, levels);\r\n declareDynamicSDFUniforms(this, 0);\r\n if (readsProbes(mode)) {\r\n declareProbeUniforms(this, 0);\r\n } else if (mode !== 'distance') {\r\n declareVoxelSceneUniforms(this, 0);\r\n }\r\n pb.main(function () {\r\n // A point on the pixel's ray; clip z 0.5 lies in front on either depth convention\r\n this.$l.h = pb.mul(\r\n this.invViewProj,\r\n pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), 0.5, 1)\r\n );\r\n this.$l.dir = pb.normalize(pb.sub(pb.div(this.h.xyz, this.h.w), this.cameraInfo.xyz));\r\n this.$l.t = pb.float(0);\r\n this.$l.steps = pb.float(0);\r\n this.$l.hit = false;\r\n this.$l.prevD = pb.float(0);\r\n this.$l.hitT = pb.float(0);\r\n this.$for(pb.int('i'), 0, MAX_STEPS, function () {\r\n this.$l.sp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));\r\n this.$l.s = sampleSceneSDFHinted(this, this.sp, this.prevD, levels);\r\n this.$l.d = this.s.x;\r\n this.prevD = this.d;\r\n this.steps = pb.add(this.steps, 1);\r\n // Same hit test as GI rays (surfaces swollen by a voxel). Probe views read at the\r\n // refined surface; voxel views read where the trace stopped, since the voxel nearest\r\n // the surface often lies inside geometry and holds no light\r\n this.$l.expand = sdfSurfaceExpand(this, this.sp, this.s, this.t, levels);\r\n this.$if(pb.lessThan(this.d, this.expand), function () {\r\n this.hitT = sdfRefineHit(\r\n this,\r\n this.cameraInfo.xyz,\r\n this.dir,\r\n this.t,\r\n this.d,\r\n this.s.y,\r\n pb.int(0),\r\n levels\r\n );\r\n this.hit = true;\r\n this.$break();\r\n });\r\n this.t = pb.add(this.t, pb.max(this.d, 0.02));\r\n this.$if(pb.greaterThan(this.t, this.cameraInfo.w), function () {\r\n this.$break();\r\n });\r\n });\r\n // Brightness from step count, so grazing silhouettes glow\r\n this.$l.k = pb.sqrt(pb.div(this.steps, MAX_STEPS));\r\n this.$l.miss = pb.vec4(pb.mix(pb.vec3(0.12, 0.12, 0.55), pb.vec3(0.85), this.k), 1);\r\n if (mode === 'distance') {\r\n this.$outputs.color = this.$choice(\r\n this.hit,\r\n pb.vec4(pb.vec3(pb.mix(0.08, 1, this.k)), 1),\r\n this.miss\r\n );\r\n } else if (readsProbes(mode)) {\r\n this.$outputs.color = this.miss;\r\n this.$if(this.hit, function () {\r\n // On the field's own surface, where the depth buffer would put a fragment\r\n this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.hitT));\r\n this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);\r\n this.$l.n = pb.normalize(\r\n pb.vec3(\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels)\r\n )\r\n )\r\n );\r\n if (mode === 'skyVisibility') {\r\n // Unshaded: white sees the whole sky, black none; magenta where no probe covers\r\n this.$l.sv = sampleProbeIrradiance(\r\n this,\r\n this.hp,\r\n this.n,\r\n pb.sub(this.cameraInfo.xyz, this.hp),\r\n 'sky'\r\n );\r\n this.$outputs.color = this.$choice(\r\n pb.greaterThan(this.sv.a, 0),\r\n pb.vec4(this.sv.rgb, 1),\r\n pb.vec4(1, 0, 1, 1)\r\n );\r\n } else {\r\n // Irradiance (E/pi) at the view's exposure, unshaded; magenta where no probe covers\r\n this.$l.irr = sampleProbeIrradiance(\r\n this,\r\n this.hp,\r\n this.n,\r\n pb.sub(this.cameraInfo.xyz, this.hp)\r\n );\r\n this.$l.ev = pb.mul(this.irr.rgb, this.viewInfo.x);\r\n this.$outputs.color = this.$choice(\r\n pb.greaterThan(this.irr.a, 0),\r\n pb.vec4(pb.div(this.ev, pb.add(this.ev, pb.vec3(1))), 1),\r\n pb.vec4(1, 0, 1, 1)\r\n );\r\n }\r\n });\r\n } else {\r\n this.$outputs.color = this.miss;\r\n this.$if(this.hit, function () {\r\n this.$l.hp = pb.add(this.cameraInfo.xyz, pb.mul(this.dir, this.t));\r\n this.$l.texel = voxelSceneTexel(this, this.hp, levels);\r\n if (mode === 'albedo') {\r\n // Lit by a head light from the field's gradient, so shape reads\r\n this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);\r\n this.$l.n = pb.normalize(\r\n pb.vec3(\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels)\r\n )\r\n )\r\n );\r\n this.$l.a = loadVoxelSceneAlbedo(this, this.texel);\r\n this.$l.shade = pb.add(0.25, pb.mul(0.75, pb.max(pb.dot(this.n, pb.neg(this.dir)), 0)));\r\n // No material: magenta outside every current window, orange for a dynamic\r\n // instance (not voxelized), else cyan/yellow/white by clipmap level 0/1/2+\r\n this.$l.staticD = sampleGlobalSDF(this, this.hp, levels);\r\n this.$l.dynamicHit = pb.greaterThan(this.staticD, pb.add(0.05, pb.mul(this.t, 0.004)));\r\n this.$l.flag = this.$choice(\r\n pb.lessThan(this.texel.w, 0),\r\n pb.vec3(1, 0, 1),\r\n this.$choice(\r\n this.dynamicHit,\r\n pb.vec3(1, 0.5, 0),\r\n this.$choice(\r\n pb.equal(this.texel.w, 0),\r\n pb.vec3(0, 1, 1),\r\n this.$choice(pb.equal(this.texel.w, 1), pb.vec3(1, 1, 0), pb.vec3(1))\r\n )\r\n )\r\n );\r\n this.$outputs.color = this.$choice(\r\n pb.greaterThan(this.a.a, 0),\r\n pb.vec4(pb.mul(this.a.rgb, this.shade), 1),\r\n pb.vec4(pb.mul(this.flag, this.shade), 1)\r\n );\r\n } else if (mode === 'emissive') {\r\n this.$l.em = loadVoxelSceneEmissive(this, this.texel);\r\n this.$outputs.color = pb.vec4(pb.div(this.em, pb.add(this.em, pb.vec3(1))), 1);\r\n } else {\r\n // The radiance toward the side the view ray hit, as a probe ray reads it\r\n this.$l.e = pb.mul(this.cameraInfo.w, 0.0005);\r\n this.$l.n = pb.normalize(\r\n pb.vec3(\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(this.e, 0, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(this.e, 0, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, this.e, 0)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, this.e, 0)), levels)\r\n ),\r\n pb.sub(\r\n sampleSceneSDF(this, pb.add(this.hp, pb.vec3(0, 0, this.e)), levels),\r\n sampleSceneSDF(this, pb.sub(this.hp, pb.vec3(0, 0, this.e)), levels)\r\n )\r\n )\r\n );\r\n this.$l.rad = pb.mul(\r\n sampleVoxelSceneRadiance(this, this.hp, this.n, levels),\r\n this.viewInfo.x\r\n );\r\n this.$outputs.color = pb.vec4(pb.div(this.rad, pb.add(this.rad, pb.vec3(1))), 1);\r\n }\r\n });\r\n }\r\n });\r\n }\r\n })!;\r\n program.name = `@SceneSDFView_${mode}`;\r\n entry = { program, bindGroup: device.createBindGroup(program.bindGroupLayouts[0]) };\r\n programs.set(key, entry);\r\n }\r\n return entry;\r\n}\r\n\r\n/**\r\n * Debug-draws the scene's signed distance field from a camera over the current framebuffer:\r\n * each pixel sphere traces the field and is shaded by step count, or by the voxel scene /\r\n * probe volume at the hit for other modes (falling back to `distance` when unavailable).\r\n * `exposure` scales `radiance` and `irradiance`; magenta marks uncovered points. Call after the\r\n * camera has rendered; does nothing without a field (disabled or WebGL2).\r\n *\r\n * @returns Whether it drew.\r\n * @public\r\n */\r\nexport function renderSceneSDFView(\r\n scene: Scene,\r\n camera: Camera,\r\n mode: SceneSDFViewMode = 'distance',\r\n exposure = 1\r\n) {\r\n const sdf = scene.sdf.enabled ? scene.sdf.global : null;\r\n if (!sdf) {\r\n return false;\r\n }\r\n const probes = readsProbes(mode) && scene.gi.enabled ? getActiveProbeVolume(scene) : null;\r\n const voxels = mode !== 'distance' && !readsProbes(mode) && scene.gi.enabled ? scene.gi.voxels : null;\r\n if (readsProbes(mode) ? !probes : !voxels?.ready || (mode === 'radiance' && !voxels.lit)) {\r\n mode = 'distance';\r\n }\r\n const device = getDevice();\r\n const { program, bindGroup } = getProgram(sdf.levels, mode);\r\n if (!renderStates) {\r\n renderStates = device.createRenderStateSet();\r\n renderStates.useDepthState().enableTest(false).enableWrite(false);\r\n renderStates.useRasterizerState().setCullMode('none');\r\n }\r\n const pos = camera.getWorldPosition(new Vector3());\r\n bindGroup.setValue('invViewProj', camera.invViewProjectionMatrix);\r\n // As far as the coarsest level reaches from the camera\r\n bindGroup.setValue(\r\n 'cameraInfo',\r\n new Vector4(pos.x, pos.y, pos.z, sdf.resolution * sdf.voxelSize(sdf.levels - 1))\r\n );\r\n bindGroup.setValue('viewInfo', new Vector4(exposure, 0, 0, 0));\r\n sdf.applyBindGroup(bindGroup);\r\n if (probes && readsProbes(mode)) {\r\n probes.applyBindGroup(bindGroup);\r\n }\r\n if (voxels && mode !== 'distance' && !readsProbes(mode)) {\r\n bindGroup.setTexture(VOXEL_SCENE_ALBEDO, voxels.albedo, fetchSampler('clamp_nearest_nomip'));\r\n bindGroup.setTexture(VOXEL_SCENE_EMISSIVE, voxels.emissive, fetchSampler('clamp_nearest_nomip'));\r\n // The layout declares all three; before the first lighting pass stand-ins are bound\r\n bindGroup.setTexture(\r\n VOXEL_SCENE_RADIANCE,\r\n voxels.lit ? voxels.radiance : voxels.emissive,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n bindGroup.setTexture(\r\n VOXEL_SCENE_ANISO0,\r\n voxels.lit ? voxels.radianceAniso0 : voxels.albedo,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n bindGroup.setTexture(\r\n VOXEL_SCENE_ANISO1,\r\n voxels.lit ? voxels.radianceAniso1 : voxels.albedo,\r\n fetchSampler('clamp_nearest_nomip')\r\n );\r\n }\r\n device.pushDeviceStates();\r\n try {\r\n const vp = camera.viewport;\r\n if (vp) {\r\n device.setViewport(vp as number[]);\r\n device.setScissor(vp as number[]);\r\n }\r\n device.setProgram(program);\r\n device.setBindGroup(0, bindGroup);\r\n drawFullscreenQuad(renderStates);\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n return true;\r\n}\r\n"],"names":["readsProbes","mode","MAX_STEPS","programs","Map","renderStates","getProgram","levels","key","entry","get","device","getDevice","program","buildSDFProgram","label","vertex","pb","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","add","mul","xy","fragment","color","invViewProj","mat4","uniform","cameraInfo","viewInfo","declareGlobalSDFUniforms","declareDynamicSDFUniforms","declareProbeUniforms","declareVoxelSceneUniforms","$l","h","sub","dir","normalize","div","xyz","w","t","float","steps","hit","prevD","hitT","$for","int","sp","s","sampleSceneSDFHinted","d","x","expand","sdfSurfaceExpand","$if","lessThan","sdfRefineHit","y","$break","max","greaterThan","k","sqrt","miss","mix","vec3","$choice","hp","e","n","sampleSceneSDF","sv","sampleProbeIrradiance","a","rgb","irr","ev","texel","voxelSceneTexel","loadVoxelSceneAlbedo","shade","dot","neg","staticD","sampleGlobalSDF","dynamicHit","flag","equal","em","loadVoxelSceneEmissive","rad","sampleVoxelSceneRadiance","name","bindGroup","createBindGroup","bindGroupLayouts","set","renderSceneSDFView","scene","camera","exposure","sdf","enabled","global","probes","gi","getActiveProbeVolume","voxels","ready","lit","createRenderStateSet","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode","getWorldPosition","Vector3","setValue","invViewProjectionMatrix","Vector4","z","resolution","voxelSize","applyBindGroup","setTexture","VOXEL_SCENE_ALBEDO","albedo","fetchSampler","VOXEL_SCENE_EMISSIVE","emissive","VOXEL_SCENE_RADIANCE","radiance","VOXEL_SCENE_ANISO0","radianceAniso0","VOXEL_SCENE_ANISO1","radianceAniso1","pushDeviceStates","vp","viewport","setViewport","setScissor","setProgram","setBindGroup","drawFullscreenQuad","popDeviceStates"],"mappings":"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"}
|