@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
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { GlobalSDF } from '../sdf/global_sdf.js';
|
|
2
|
+
import { VoxelScene } from './voxel_scene.js';
|
|
3
|
+
import { ProbeVolume } from './probe_volume.js';
|
|
4
|
+
import { PROBE_MAX_LEVELS } from '../../shaders/probes.js';
|
|
5
|
+
import { RenderGraphExecutor } from '../rendergraph/executor.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Probe-based global illumination of a scene, at `scene.gi`. Off by default.
|
|
9
|
+
*
|
|
10
|
+
* Built on the scene's signed distance field (enabling it turns the field on) plus
|
|
11
|
+
* a {@link VoxelScene} giving the field's surfaces albedo and emissive. WebGPU only.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/ class SceneGI {
|
|
15
|
+
_scene;
|
|
16
|
+
_enabled;
|
|
17
|
+
_voxels;
|
|
18
|
+
_atlasSize;
|
|
19
|
+
_voxelizeBudget;
|
|
20
|
+
_lighting;
|
|
21
|
+
_probeOptions;
|
|
22
|
+
_probes;
|
|
23
|
+
_updateMode;
|
|
24
|
+
_warned;
|
|
25
|
+
constructor(scene){
|
|
26
|
+
this._scene = scene;
|
|
27
|
+
this._enabled = false;
|
|
28
|
+
this._voxels = null;
|
|
29
|
+
this._atlasSize = 256;
|
|
30
|
+
this._voxelizeBudget = 8;
|
|
31
|
+
this._lighting = {
|
|
32
|
+
sunShadowConeAngle: 0.5357,
|
|
33
|
+
slicesPerFrame: 8,
|
|
34
|
+
localLightShadows: true
|
|
35
|
+
};
|
|
36
|
+
this._probeOptions = {
|
|
37
|
+
grid: [
|
|
38
|
+
32,
|
|
39
|
+
16,
|
|
40
|
+
32
|
|
41
|
+
],
|
|
42
|
+
spacing: 1,
|
|
43
|
+
levels: 4,
|
|
44
|
+
levelScale: 2,
|
|
45
|
+
raysPerProbe: 128,
|
|
46
|
+
budget: 4096,
|
|
47
|
+
hysteresis: 0.97,
|
|
48
|
+
// Lumen's irradiance field gather: (0.2 N + 0.8 V) * 0.75 * cell * 0.8
|
|
49
|
+
normalBias: 0.12,
|
|
50
|
+
viewBias: 0.48,
|
|
51
|
+
intensity: 1,
|
|
52
|
+
maxRayDistance: 48
|
|
53
|
+
};
|
|
54
|
+
this._probes = null;
|
|
55
|
+
this._updateMode = 'continuous';
|
|
56
|
+
this._warned = false;
|
|
57
|
+
}
|
|
58
|
+
/** True on a device that can build it. */ static isSupported() {
|
|
59
|
+
return GlobalSDF.isSupported();
|
|
60
|
+
}
|
|
61
|
+
get enabled() {
|
|
62
|
+
return this._enabled;
|
|
63
|
+
}
|
|
64
|
+
set enabled(val) {
|
|
65
|
+
val = !!val;
|
|
66
|
+
if (val === this._enabled) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this._enabled = val;
|
|
70
|
+
if (val) {
|
|
71
|
+
// The voxel scene extends the field; turning the field off afterwards idles this
|
|
72
|
+
this._scene.sdf.enabled = true;
|
|
73
|
+
} else {
|
|
74
|
+
this._voxels?.detach(this._scene.sdf);
|
|
75
|
+
this._voxels?.dispose();
|
|
76
|
+
this._voxels = null;
|
|
77
|
+
this._probes?.dispose();
|
|
78
|
+
this._probes = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** The probe volume, once built. */ get probes() {
|
|
82
|
+
return this._probes;
|
|
83
|
+
}
|
|
84
|
+
/** Distance between probes in world units; applied when the volume is next built. */ get probeSpacing() {
|
|
85
|
+
return this._probeOptions.spacing;
|
|
86
|
+
}
|
|
87
|
+
set probeSpacing(val) {
|
|
88
|
+
val = Math.max(0.1, val);
|
|
89
|
+
if (val !== this._probeOptions.spacing) {
|
|
90
|
+
this._probeOptions.spacing = val;
|
|
91
|
+
this.rebuildProbes();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Probes along x, y and z; applied when the volume is next built. */ get probeGrid() {
|
|
95
|
+
return [
|
|
96
|
+
...this._probeOptions.grid
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
set probeGrid(val) {
|
|
100
|
+
const grid = val.map((v)=>Math.max(2, Math.floor(v)));
|
|
101
|
+
const cur = this._probeOptions.grid;
|
|
102
|
+
if (grid[0] !== cur[0] || grid[1] !== cur[1] || grid[2] !== cur[2]) {
|
|
103
|
+
this._probeOptions.grid = grid;
|
|
104
|
+
this.rebuildProbes();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Clipmap levels of the probe volume, each twice the spacing of the one inside it; applied when the volume is next built. */ get probeLevels() {
|
|
108
|
+
return this._probeOptions.levels;
|
|
109
|
+
}
|
|
110
|
+
set probeLevels(val) {
|
|
111
|
+
val = Math.max(1, Math.min(PROBE_MAX_LEVELS, Math.floor(val)));
|
|
112
|
+
if (val !== this._probeOptions.levels) {
|
|
113
|
+
this._probeOptions.levels = val;
|
|
114
|
+
this.rebuildProbes();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Whether the indirect lighting keeps updating. `frozen` stops voxel lighting and
|
|
119
|
+
* probe updates (including the probe windows following the camera).
|
|
120
|
+
*/ get updateMode() {
|
|
121
|
+
return this._updateMode;
|
|
122
|
+
}
|
|
123
|
+
set updateMode(val) {
|
|
124
|
+
this._updateMode = val === 'frozen' ? 'frozen' : 'continuous';
|
|
125
|
+
}
|
|
126
|
+
/** Saves the probe volume's state, see {@link ProbeVolume.exportState}. */ exportProbeState() {
|
|
127
|
+
if (!this._probes?.ready) {
|
|
128
|
+
throw new Error('SceneGI.exportProbeState(): the probes are not built yet');
|
|
129
|
+
}
|
|
130
|
+
return this._probes.exportState();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Restores a probe state saved by {@link SceneGI.exportProbeState} into a
|
|
134
|
+
* volume built with the current settings, and freezes the lighting.
|
|
135
|
+
*/ importProbeState(buffer) {
|
|
136
|
+
if (!this._probes) {
|
|
137
|
+
this._probes = new ProbeVolume(this._scene, this._probeOptions);
|
|
138
|
+
}
|
|
139
|
+
this._probes.importState(buffer);
|
|
140
|
+
this._updateMode = 'frozen';
|
|
141
|
+
}
|
|
142
|
+
/** Rays traced per probe per update; applied when the volume is next built. */ get probeRays() {
|
|
143
|
+
return this._probeOptions.raysPerProbe;
|
|
144
|
+
}
|
|
145
|
+
set probeRays(val) {
|
|
146
|
+
val = Math.max(16, Math.min(1024, Math.floor(val)));
|
|
147
|
+
if (val !== this._probeOptions.raysPerProbe) {
|
|
148
|
+
this._probeOptions.raysPerProbe = val;
|
|
149
|
+
this.rebuildProbes();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Probes updated per frame; applied when the volume is next built. */ get probeBudget() {
|
|
153
|
+
return this._probeOptions.budget;
|
|
154
|
+
}
|
|
155
|
+
set probeBudget(val) {
|
|
156
|
+
val = Math.max(1, Math.floor(val));
|
|
157
|
+
if (val !== this._probeOptions.budget) {
|
|
158
|
+
this._probeOptions.budget = val;
|
|
159
|
+
this.rebuildProbes();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Share of a probe's previous value kept per update, 0 to 1. */ get probeHysteresis() {
|
|
163
|
+
return this._probeOptions.hysteresis;
|
|
164
|
+
}
|
|
165
|
+
set probeHysteresis(val) {
|
|
166
|
+
this._probeOptions.hysteresis = Math.max(0, Math.min(0.999, val));
|
|
167
|
+
}
|
|
168
|
+
/** Multiplier on the indirect light the probes give. */ get intensity() {
|
|
169
|
+
return this._probeOptions.intensity;
|
|
170
|
+
}
|
|
171
|
+
set intensity(val) {
|
|
172
|
+
this._probeOptions.intensity = Math.max(0, val);
|
|
173
|
+
}
|
|
174
|
+
/** Surface offset along the normal when sampling the probes, in probe spacings of the level read. */ get probeNormalBias() {
|
|
175
|
+
return this._probeOptions.normalBias;
|
|
176
|
+
}
|
|
177
|
+
set probeNormalBias(val) {
|
|
178
|
+
this._probeOptions.normalBias = Math.max(0, val);
|
|
179
|
+
}
|
|
180
|
+
/** Surface offset towards the viewer when sampling the probes, in probe spacings of the level read. */ get probeViewBias() {
|
|
181
|
+
return this._probeOptions.viewBias;
|
|
182
|
+
}
|
|
183
|
+
set probeViewBias(val) {
|
|
184
|
+
this._probeOptions.viewBias = Math.max(0, val);
|
|
185
|
+
}
|
|
186
|
+
/** @internal */ rebuildProbes() {
|
|
187
|
+
this._probes?.dispose();
|
|
188
|
+
this._probes = null;
|
|
189
|
+
}
|
|
190
|
+
/** Meshes voxelized per frame. */ get voxelizeBudget() {
|
|
191
|
+
return this._voxelizeBudget;
|
|
192
|
+
}
|
|
193
|
+
set voxelizeBudget(val) {
|
|
194
|
+
this._voxelizeBudget = Math.max(1, Math.floor(val));
|
|
195
|
+
}
|
|
196
|
+
/** Voxels per axis of the material atlas; applied when the voxel scene is next built. */ get atlasSize() {
|
|
197
|
+
return this._atlasSize;
|
|
198
|
+
}
|
|
199
|
+
set atlasSize(val) {
|
|
200
|
+
val = Math.max(16, Math.floor(val));
|
|
201
|
+
if (val !== this._atlasSize) {
|
|
202
|
+
this._atlasSize = val;
|
|
203
|
+
this._voxels?.detach(this._scene.sdf);
|
|
204
|
+
this._voxels?.dispose();
|
|
205
|
+
this._voxels = null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** Half angle of the sun shadow cone in the voxel lighting, in degrees; wider is softer. */ get sunShadowConeAngle() {
|
|
209
|
+
return this._lighting.sunShadowConeAngle;
|
|
210
|
+
}
|
|
211
|
+
set sunShadowConeAngle(val) {
|
|
212
|
+
this._lighting.sunShadowConeAngle = Math.max(0.1, Math.min(45, val));
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Whether point, spot and rect lights that cast shadows also cast them in the bounced light,
|
|
216
|
+
* traced through the global distance field for the nearest eight such lights. Default true.
|
|
217
|
+
*/ get localLightShadows() {
|
|
218
|
+
return this._lighting.localLightShadows;
|
|
219
|
+
}
|
|
220
|
+
set localLightShadows(val) {
|
|
221
|
+
this._lighting.localLightShadows = !!val;
|
|
222
|
+
}
|
|
223
|
+
/** Z slices of every clipmap level lit per frame; the voxel lighting is refreshed every `64 / slices` frames. */ get lightingSlicesPerFrame() {
|
|
224
|
+
return this._lighting.slicesPerFrame;
|
|
225
|
+
}
|
|
226
|
+
set lightingSlicesPerFrame(val) {
|
|
227
|
+
this._lighting.slicesPerFrame = Math.max(1, Math.floor(val));
|
|
228
|
+
}
|
|
229
|
+
/** The voxel scene, once built. */ get voxels() {
|
|
230
|
+
return this._voxels;
|
|
231
|
+
}
|
|
232
|
+
getStats() {
|
|
233
|
+
return {
|
|
234
|
+
enabled: this._enabled,
|
|
235
|
+
supported: SceneGI.isSupported(),
|
|
236
|
+
voxels: this._voxels?.getStats() ?? null,
|
|
237
|
+
probes: this._probes?.getStats() ?? null
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/** Called by the scene once a frame, before the scene field's update. */ update(cameraPos, deltaSeconds) {
|
|
241
|
+
if (!this._enabled || !this._scene.sdf.enabled) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (!SceneGI.isSupported()) {
|
|
245
|
+
if (!this._warned) {
|
|
246
|
+
this._warned = true;
|
|
247
|
+
console.warn('SceneGI: global illumination needs WebGPU; nothing is built on this device');
|
|
248
|
+
}
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (!this._voxels) {
|
|
252
|
+
this._voxels = new VoxelScene(this._scene, this._atlasSize);
|
|
253
|
+
}
|
|
254
|
+
this._voxels.voxelizeBudget = this._voxelizeBudget;
|
|
255
|
+
this._voxels.update(this._scene.sdf, cameraPos, deltaSeconds);
|
|
256
|
+
}
|
|
257
|
+
/** Called by the scene once a frame, after the scene field's update. */ updateLighting(camera) {
|
|
258
|
+
if (!this._enabled || !this._voxels || !this._scene.sdf.enabled) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// The probes are read at the camera's exposure even while frozen
|
|
262
|
+
this._probes?.setReadExposure(camera);
|
|
263
|
+
if (this._updateMode === 'frozen') {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
RenderGraphExecutor.profileScope('VoxelLighting', ()=>this._voxels.updateLighting(this._scene.sdf, camera, this._lighting));
|
|
267
|
+
if (!this._voxels.lit) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (!this._probes) {
|
|
271
|
+
this._probes = new ProbeVolume(this._scene, this._probeOptions);
|
|
272
|
+
}
|
|
273
|
+
this._probes.setReadExposure(camera);
|
|
274
|
+
RenderGraphExecutor.profileScope('ProbeUpdate', ()=>this._probes.update(this._scene.sdf, this._voxels, camera));
|
|
275
|
+
}
|
|
276
|
+
dispose() {
|
|
277
|
+
this.enabled = false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export { SceneGI };
|
|
282
|
+
//# sourceMappingURL=scene_gi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene_gi.js","sources":["../../../src/render/gi/scene_gi.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport type { Vector3 } from '@zephyr3d/base';\r\nimport type { Scene } from '../../scene/scene';\r\nimport type { Camera } from '../../camera/camera';\r\nimport { GlobalSDF } from '../sdf/global_sdf';\r\nimport { VoxelScene } from './voxel_scene';\r\nimport type { VoxelSceneStats } from './voxel_scene';\r\nimport type { VoxelLightingOptions } from './voxel_lighting';\r\nimport { ProbeVolume } from './probe_volume';\r\nimport { PROBE_MAX_LEVELS } from '../../shaders/probes';\r\nimport type { ProbeVolumeOptions, ProbeVolumeStats } from './probe_volume';\r\nimport { RenderGraphExecutor } from '../rendergraph/executor';\r\n\r\n/**\r\n * Whether the indirect lighting keeps updating, see {@link SceneGI.updateMode}.\r\n * @public\r\n */\r\nexport type GIUpdateMode = 'continuous' | 'frozen';\r\n\r\n/**\r\n * Counters of a {@link SceneGI}.\r\n * @public\r\n */\r\nexport interface SceneGIStats {\r\n enabled: boolean;\r\n /** False on a device that cannot build it (WebGL2). */\r\n supported: boolean;\r\n voxels: Nullable<VoxelSceneStats>;\r\n probes: Nullable<ProbeVolumeStats>;\r\n}\r\n\r\n/**\r\n * Probe-based global illumination of a scene, at `scene.gi`. Off by default.\r\n *\r\n * Built on the scene's signed distance field (enabling it turns the field on) plus\r\n * a {@link VoxelScene} giving the field's surfaces albedo and emissive. WebGPU only.\r\n *\r\n * @public\r\n */\r\nexport class SceneGI {\r\n private readonly _scene: Scene;\r\n private _enabled: boolean;\r\n private _voxels: Nullable<VoxelScene>;\r\n private _atlasSize: number;\r\n private _voxelizeBudget: number;\r\n private readonly _lighting: VoxelLightingOptions;\r\n private readonly _probeOptions: ProbeVolumeOptions;\r\n private _probes: Nullable<ProbeVolume>;\r\n private _updateMode: GIUpdateMode;\r\n private _warned: boolean;\r\n constructor(scene: Scene) {\r\n this._scene = scene;\r\n this._enabled = false;\r\n this._voxels = null;\r\n this._atlasSize = 256;\r\n this._voxelizeBudget = 8;\r\n this._lighting = { sunShadowConeAngle: 0.5357, slicesPerFrame: 8, localLightShadows: true };\r\n this._probeOptions = {\r\n grid: [32, 16, 32],\r\n spacing: 1,\r\n levels: 4,\r\n levelScale: 2,\r\n raysPerProbe: 128,\r\n budget: 4096,\r\n hysteresis: 0.97,\r\n // Lumen's irradiance field gather: (0.2 N + 0.8 V) * 0.75 * cell * 0.8\r\n normalBias: 0.12,\r\n viewBias: 0.48,\r\n intensity: 1,\r\n maxRayDistance: 48\r\n };\r\n this._probes = null;\r\n this._updateMode = 'continuous';\r\n this._warned = false;\r\n }\r\n /** True on a device that can build it. */\r\n static isSupported() {\r\n return GlobalSDF.isSupported();\r\n }\r\n get enabled() {\r\n return this._enabled;\r\n }\r\n set enabled(val: boolean) {\r\n val = !!val;\r\n if (val === this._enabled) {\r\n return;\r\n }\r\n this._enabled = val;\r\n if (val) {\r\n // The voxel scene extends the field; turning the field off afterwards idles this\r\n this._scene.sdf.enabled = true;\r\n } else {\r\n this._voxels?.detach(this._scene.sdf);\r\n this._voxels?.dispose();\r\n this._voxels = null;\r\n this._probes?.dispose();\r\n this._probes = null;\r\n }\r\n }\r\n /** The probe volume, once built. */\r\n get probes() {\r\n return this._probes;\r\n }\r\n /** Distance between probes in world units; applied when the volume is next built. */\r\n get probeSpacing() {\r\n return this._probeOptions.spacing;\r\n }\r\n set probeSpacing(val: number) {\r\n val = Math.max(0.1, val);\r\n if (val !== this._probeOptions.spacing) {\r\n this._probeOptions.spacing = val;\r\n this.rebuildProbes();\r\n }\r\n }\r\n /** Probes along x, y and z; applied when the volume is next built. */\r\n get probeGrid(): [number, number, number] {\r\n return [...this._probeOptions.grid];\r\n }\r\n set probeGrid(val: [number, number, number]) {\r\n const grid = val.map((v) => Math.max(2, Math.floor(v))) as [number, number, number];\r\n const cur = this._probeOptions.grid;\r\n if (grid[0] !== cur[0] || grid[1] !== cur[1] || grid[2] !== cur[2]) {\r\n this._probeOptions.grid = grid;\r\n this.rebuildProbes();\r\n }\r\n }\r\n /** Clipmap levels of the probe volume, each twice the spacing of the one inside it; applied when the volume is next built. */\r\n get probeLevels() {\r\n return this._probeOptions.levels;\r\n }\r\n set probeLevels(val: number) {\r\n val = Math.max(1, Math.min(PROBE_MAX_LEVELS, Math.floor(val)));\r\n if (val !== this._probeOptions.levels) {\r\n this._probeOptions.levels = val;\r\n this.rebuildProbes();\r\n }\r\n }\r\n /**\r\n * Whether the indirect lighting keeps updating. `frozen` stops voxel lighting and\r\n * probe updates (including the probe windows following the camera).\r\n */\r\n get updateMode() {\r\n return this._updateMode;\r\n }\r\n set updateMode(val: GIUpdateMode) {\r\n this._updateMode = val === 'frozen' ? 'frozen' : 'continuous';\r\n }\r\n /** Saves the probe volume's state, see {@link ProbeVolume.exportState}. */\r\n exportProbeState() {\r\n if (!this._probes?.ready) {\r\n throw new Error('SceneGI.exportProbeState(): the probes are not built yet');\r\n }\r\n return this._probes.exportState();\r\n }\r\n /**\r\n * Restores a probe state saved by {@link SceneGI.exportProbeState} into a\r\n * volume built with the current settings, and freezes the lighting.\r\n */\r\n importProbeState(buffer: ArrayBuffer) {\r\n if (!this._probes) {\r\n this._probes = new ProbeVolume(this._scene, this._probeOptions);\r\n }\r\n this._probes.importState(buffer);\r\n this._updateMode = 'frozen';\r\n }\r\n /** Rays traced per probe per update; applied when the volume is next built. */\r\n get probeRays() {\r\n return this._probeOptions.raysPerProbe;\r\n }\r\n set probeRays(val: number) {\r\n val = Math.max(16, Math.min(1024, Math.floor(val)));\r\n if (val !== this._probeOptions.raysPerProbe) {\r\n this._probeOptions.raysPerProbe = val;\r\n this.rebuildProbes();\r\n }\r\n }\r\n /** Probes updated per frame; applied when the volume is next built. */\r\n get probeBudget() {\r\n return this._probeOptions.budget;\r\n }\r\n set probeBudget(val: number) {\r\n val = Math.max(1, Math.floor(val));\r\n if (val !== this._probeOptions.budget) {\r\n this._probeOptions.budget = val;\r\n this.rebuildProbes();\r\n }\r\n }\r\n /** Share of a probe's previous value kept per update, 0 to 1. */\r\n get probeHysteresis() {\r\n return this._probeOptions.hysteresis;\r\n }\r\n set probeHysteresis(val: number) {\r\n this._probeOptions.hysteresis = Math.max(0, Math.min(0.999, val));\r\n }\r\n /** Multiplier on the indirect light the probes give. */\r\n get intensity() {\r\n return this._probeOptions.intensity;\r\n }\r\n set intensity(val: number) {\r\n this._probeOptions.intensity = Math.max(0, val);\r\n }\r\n /** Surface offset along the normal when sampling the probes, in probe spacings of the level read. */\r\n get probeNormalBias() {\r\n return this._probeOptions.normalBias;\r\n }\r\n set probeNormalBias(val: number) {\r\n this._probeOptions.normalBias = Math.max(0, val);\r\n }\r\n /** Surface offset towards the viewer when sampling the probes, in probe spacings of the level read. */\r\n get probeViewBias() {\r\n return this._probeOptions.viewBias;\r\n }\r\n set probeViewBias(val: number) {\r\n this._probeOptions.viewBias = Math.max(0, val);\r\n }\r\n /** @internal */\r\n private rebuildProbes() {\r\n this._probes?.dispose();\r\n this._probes = null;\r\n }\r\n /** Meshes voxelized per frame. */\r\n get voxelizeBudget() {\r\n return this._voxelizeBudget;\r\n }\r\n set voxelizeBudget(val: number) {\r\n this._voxelizeBudget = Math.max(1, Math.floor(val));\r\n }\r\n /** Voxels per axis of the material atlas; applied when the voxel scene is next built. */\r\n get atlasSize() {\r\n return this._atlasSize;\r\n }\r\n set atlasSize(val: number) {\r\n val = Math.max(16, Math.floor(val));\r\n if (val !== this._atlasSize) {\r\n this._atlasSize = val;\r\n this._voxels?.detach(this._scene.sdf);\r\n this._voxels?.dispose();\r\n this._voxels = null;\r\n }\r\n }\r\n /** Half angle of the sun shadow cone in the voxel lighting, in degrees; wider is softer. */\r\n get sunShadowConeAngle() {\r\n return this._lighting.sunShadowConeAngle;\r\n }\r\n set sunShadowConeAngle(val: number) {\r\n this._lighting.sunShadowConeAngle = Math.max(0.1, Math.min(45, val));\r\n }\r\n /**\r\n * Whether point, spot and rect lights that cast shadows also cast them in the bounced light,\r\n * traced through the global distance field for the nearest eight such lights. Default true.\r\n */\r\n get localLightShadows() {\r\n return this._lighting.localLightShadows;\r\n }\r\n set localLightShadows(val: boolean) {\r\n this._lighting.localLightShadows = !!val;\r\n }\r\n /** Z slices of every clipmap level lit per frame; the voxel lighting is refreshed every `64 / slices` frames. */\r\n get lightingSlicesPerFrame() {\r\n return this._lighting.slicesPerFrame;\r\n }\r\n set lightingSlicesPerFrame(val: number) {\r\n this._lighting.slicesPerFrame = Math.max(1, Math.floor(val));\r\n }\r\n /** The voxel scene, once built. */\r\n get voxels() {\r\n return this._voxels;\r\n }\r\n getStats(): SceneGIStats {\r\n return {\r\n enabled: this._enabled,\r\n supported: SceneGI.isSupported(),\r\n voxels: this._voxels?.getStats() ?? null,\r\n probes: this._probes?.getStats() ?? null\r\n };\r\n }\r\n /** Called by the scene once a frame, before the scene field's update. */\r\n update(cameraPos: Vector3, deltaSeconds: number) {\r\n if (!this._enabled || !this._scene.sdf.enabled) {\r\n return;\r\n }\r\n if (!SceneGI.isSupported()) {\r\n if (!this._warned) {\r\n this._warned = true;\r\n console.warn('SceneGI: global illumination needs WebGPU; nothing is built on this device');\r\n }\r\n return;\r\n }\r\n if (!this._voxels) {\r\n this._voxels = new VoxelScene(this._scene, this._atlasSize);\r\n }\r\n this._voxels.voxelizeBudget = this._voxelizeBudget;\r\n this._voxels.update(this._scene.sdf, cameraPos, deltaSeconds);\r\n }\r\n /** Called by the scene once a frame, after the scene field's update. */\r\n updateLighting(camera: Camera) {\r\n if (!this._enabled || !this._voxels || !this._scene.sdf.enabled) {\r\n return;\r\n }\r\n // The probes are read at the camera's exposure even while frozen\r\n this._probes?.setReadExposure(camera);\r\n if (this._updateMode === 'frozen') {\r\n return;\r\n }\r\n RenderGraphExecutor.profileScope('VoxelLighting', () =>\r\n this._voxels!.updateLighting(this._scene.sdf, camera, this._lighting)\r\n );\r\n if (!this._voxels.lit) {\r\n return;\r\n }\r\n if (!this._probes) {\r\n this._probes = new ProbeVolume(this._scene, this._probeOptions);\r\n }\r\n this._probes.setReadExposure(camera);\r\n RenderGraphExecutor.profileScope('ProbeUpdate', () =>\r\n this._probes!.update(this._scene.sdf, this._voxels!, camera)\r\n );\r\n }\r\n dispose() {\r\n this.enabled = false;\r\n }\r\n}\r\n"],"names":["SceneGI","_scene","_enabled","_voxels","_atlasSize","_voxelizeBudget","_lighting","_probeOptions","_probes","_updateMode","_warned","scene","sunShadowConeAngle","slicesPerFrame","localLightShadows","grid","spacing","levels","levelScale","raysPerProbe","budget","hysteresis","normalBias","viewBias","intensity","maxRayDistance","isSupported","GlobalSDF","enabled","val","sdf","detach","dispose","probes","probeSpacing","Math","max","rebuildProbes","probeGrid","map","v","floor","cur","probeLevels","min","PROBE_MAX_LEVELS","updateMode","exportProbeState","ready","Error","exportState","importProbeState","buffer","ProbeVolume","importState","probeRays","probeBudget","probeHysteresis","probeNormalBias","probeViewBias","voxelizeBudget","atlasSize","lightingSlicesPerFrame","voxels","getStats","supported","update","cameraPos","deltaSeconds","console","warn","VoxelScene","updateLighting","camera","setReadExposure","RenderGraphExecutor","profileScope","lit"],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { getDevice } from '../../app/api.js';
|
|
2
|
+
import { VolumeBoxAllocator } from '../sdf/box_allocator.js';
|
|
3
|
+
|
|
4
|
+
/** Allocation granularity of the atlas in voxels, per axis. */ const VOXEL_ATLAS_BLOCK = 4;
|
|
5
|
+
/**
|
|
6
|
+
* Material atlases of the voxel scene: two same-layout 3D textures, albedo
|
|
7
|
+
* (rgba8unorm, a = 1 where a surface was rasterized) and emissive (rgba8unorm as RGBE),
|
|
8
|
+
* one block-aligned region per voxelized mesh. GPU-written only, so evicted regions are
|
|
9
|
+
* re-rasterized and a fragmented atlas is cleared and refilled rather than repacked.
|
|
10
|
+
* WebGPU only.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/ class VoxelMaterialAtlas {
|
|
14
|
+
size;
|
|
15
|
+
_albedo;
|
|
16
|
+
_emissive;
|
|
17
|
+
_allocator;
|
|
18
|
+
_entries;
|
|
19
|
+
_usedVoxels;
|
|
20
|
+
_version;
|
|
21
|
+
constructor(size = [
|
|
22
|
+
256,
|
|
23
|
+
256,
|
|
24
|
+
256
|
|
25
|
+
]){
|
|
26
|
+
this.size = size.map((v)=>Math.max(VOXEL_ATLAS_BLOCK, Math.ceil(v / VOXEL_ATLAS_BLOCK) * VOXEL_ATLAS_BLOCK));
|
|
27
|
+
this._albedo = null;
|
|
28
|
+
this._emissive = null;
|
|
29
|
+
this._allocator = new VolumeBoxAllocator(this.size);
|
|
30
|
+
this._entries = new Map();
|
|
31
|
+
this._usedVoxels = 0;
|
|
32
|
+
this._version = 0;
|
|
33
|
+
}
|
|
34
|
+
/** The albedo atlas, created on first use. */ get albedo() {
|
|
35
|
+
if (!this._albedo) {
|
|
36
|
+
this._albedo = this.createTexture('@VoxelAlbedoAtlas');
|
|
37
|
+
}
|
|
38
|
+
return this._albedo;
|
|
39
|
+
}
|
|
40
|
+
/** The emissive atlas (RGBE), created on first use. */ get emissive() {
|
|
41
|
+
if (!this._emissive) {
|
|
42
|
+
this._emissive = this.createTexture('@VoxelEmissiveAtlas');
|
|
43
|
+
}
|
|
44
|
+
return this._emissive;
|
|
45
|
+
}
|
|
46
|
+
/** Meshes resident in the atlas. */ get count() {
|
|
47
|
+
return this._entries.size;
|
|
48
|
+
}
|
|
49
|
+
/** Share of the atlas allocated, 0 to 1. */ get occupancy() {
|
|
50
|
+
return this._usedVoxels / (this.size[0] * this.size[1] * this.size[2]);
|
|
51
|
+
}
|
|
52
|
+
/** Bumped whenever a slot is removed, so users of slot offsets can refresh them. */ get version() {
|
|
53
|
+
return this._version;
|
|
54
|
+
}
|
|
55
|
+
/** The slot of a resident mesh, or null. */ getSlot(key) {
|
|
56
|
+
return this._entries.get(key)?.slot ?? null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Allocates a region for a mesh.
|
|
60
|
+
* @param key - Identity of the mesh, used to look it up and free it.
|
|
61
|
+
* @param resolution - Voxels per axis.
|
|
62
|
+
* @returns The slot, or null when nothing fits.
|
|
63
|
+
*/ add(key, resolution) {
|
|
64
|
+
const existing = this._entries.get(key);
|
|
65
|
+
if (existing) {
|
|
66
|
+
return existing.slot;
|
|
67
|
+
}
|
|
68
|
+
const need = this.blockAligned(resolution);
|
|
69
|
+
if (need[0] > this.size[0] || need[1] > this.size[1] || need[2] > this.size[2]) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const box = this._allocator.allocate(need);
|
|
73
|
+
if (!box) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const entry = {
|
|
77
|
+
slot: {
|
|
78
|
+
offset: [
|
|
79
|
+
box.x,
|
|
80
|
+
box.y,
|
|
81
|
+
box.z
|
|
82
|
+
],
|
|
83
|
+
resolution: [
|
|
84
|
+
...resolution
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
box
|
|
88
|
+
};
|
|
89
|
+
this._entries.set(key, entry);
|
|
90
|
+
this._usedVoxels += box.w * box.h * box.d;
|
|
91
|
+
return entry.slot;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* True when meshes of the given resolutions would fit an empty atlas, packed
|
|
95
|
+
* in {@link VoxelMaterialAtlas.packOrder}. Changes nothing.
|
|
96
|
+
*/ fits(resolutions) {
|
|
97
|
+
const allocator = new VolumeBoxAllocator(this.size);
|
|
98
|
+
return VoxelMaterialAtlas.packOrder(resolutions).every((r)=>!!allocator.allocate(this.blockAligned(r)));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The order an atlas cleared for a set of meshes adds them in, largest
|
|
102
|
+
* first, for which {@link VoxelMaterialAtlas.fits} answers.
|
|
103
|
+
*/ static packOrder(items) {
|
|
104
|
+
const volume = (item)=>{
|
|
105
|
+
const r = Array.isArray(item) ? item : item.resolution;
|
|
106
|
+
return r[0] * r[1] * r[2];
|
|
107
|
+
};
|
|
108
|
+
return [
|
|
109
|
+
...items
|
|
110
|
+
].sort((a, b)=>volume(b) - volume(a));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Packs the given meshes from an empty atlas in
|
|
114
|
+
* {@link VoxelMaterialAtlas.packOrder}, freeing every other region. Fails,
|
|
115
|
+
* changing nothing, when they do not all fit (see {@link VoxelMaterialAtlas.fits}).
|
|
116
|
+
* @returns The keys whose region moved, whose content is lost, or null.
|
|
117
|
+
*/ repack(items) {
|
|
118
|
+
const allocator = new VolumeBoxAllocator(this.size);
|
|
119
|
+
const placed = [];
|
|
120
|
+
for (const item of VoxelMaterialAtlas.packOrder(items)){
|
|
121
|
+
const box = allocator.allocate(this.blockAligned(item.resolution));
|
|
122
|
+
if (!box) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
placed.push({
|
|
126
|
+
...item,
|
|
127
|
+
box
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
const moved = new Set();
|
|
131
|
+
const entries = new Map();
|
|
132
|
+
this._usedVoxels = 0;
|
|
133
|
+
for (const { key, resolution, box } of placed){
|
|
134
|
+
const old = this._entries.get(key)?.box;
|
|
135
|
+
if (!old || old.x !== box.x || old.y !== box.y || old.z !== box.z) {
|
|
136
|
+
moved.add(key);
|
|
137
|
+
}
|
|
138
|
+
entries.set(key, {
|
|
139
|
+
slot: {
|
|
140
|
+
offset: [
|
|
141
|
+
box.x,
|
|
142
|
+
box.y,
|
|
143
|
+
box.z
|
|
144
|
+
],
|
|
145
|
+
resolution: [
|
|
146
|
+
...resolution
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
box
|
|
150
|
+
});
|
|
151
|
+
this._usedVoxels += box.w * box.h * box.d;
|
|
152
|
+
}
|
|
153
|
+
this._entries.clear();
|
|
154
|
+
for (const [key, entry] of entries){
|
|
155
|
+
this._entries.set(key, entry);
|
|
156
|
+
}
|
|
157
|
+
this._allocator = allocator;
|
|
158
|
+
this._version++;
|
|
159
|
+
return moved;
|
|
160
|
+
}
|
|
161
|
+
/** Frees the region of a mesh. */ remove(key) {
|
|
162
|
+
const entry = this._entries.get(key);
|
|
163
|
+
if (entry) {
|
|
164
|
+
this._entries.delete(key);
|
|
165
|
+
this._allocator.free(entry.box);
|
|
166
|
+
this._usedVoxels -= entry.box.w * entry.box.h * entry.box.d;
|
|
167
|
+
this._version++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Frees every region; the textures keep their content until written again. */ clear() {
|
|
171
|
+
this._entries.clear();
|
|
172
|
+
this._allocator.reset();
|
|
173
|
+
this._usedVoxels = 0;
|
|
174
|
+
this._version++;
|
|
175
|
+
}
|
|
176
|
+
dispose() {
|
|
177
|
+
this._albedo?.dispose();
|
|
178
|
+
this._emissive?.dispose();
|
|
179
|
+
this._albedo = null;
|
|
180
|
+
this._emissive = null;
|
|
181
|
+
this.clear();
|
|
182
|
+
}
|
|
183
|
+
/** @internal */ blockAligned(resolution) {
|
|
184
|
+
return resolution.map((v)=>Math.ceil(v / VOXEL_ATLAS_BLOCK) * VOXEL_ATLAS_BLOCK);
|
|
185
|
+
}
|
|
186
|
+
/** @internal */ createTexture(name) {
|
|
187
|
+
const [w, h, d] = this.size;
|
|
188
|
+
const tex = getDevice().createTexture3D('rgba8unorm', w, h, d, {
|
|
189
|
+
mipmapping: false,
|
|
190
|
+
writable: true
|
|
191
|
+
});
|
|
192
|
+
tex.name = name;
|
|
193
|
+
return tex;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { VOXEL_ATLAS_BLOCK, VoxelMaterialAtlas };
|
|
198
|
+
//# sourceMappingURL=voxel_atlas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voxel_atlas.js","sources":["../../../src/render/gi/voxel_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 '../sdf/box_allocator';\r\nimport type { VolumeBox } from '../sdf/box_allocator';\r\n\r\n/** Allocation granularity of the atlas in voxels, per axis. */\r\nexport const VOXEL_ATLAS_BLOCK = 4;\r\n\r\n/**\r\n * A region of the material atlas holding one voxelized mesh.\r\n * @public\r\n */\r\nexport interface VoxelAtlasSlot {\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 slot: VoxelAtlasSlot;\r\n box: VolumeBox;\r\n}\r\n\r\n/**\r\n * Material atlases of the voxel scene: two same-layout 3D textures, albedo\r\n * (rgba8unorm, a = 1 where a surface was rasterized) and emissive (rgba8unorm as RGBE),\r\n * one block-aligned region per voxelized mesh. GPU-written only, so evicted regions are\r\n * re-rasterized and a fragmented atlas is cleared and refilled rather than repacked.\r\n * WebGPU only.\r\n *\r\n * @public\r\n */\r\nexport class VoxelMaterialAtlas {\r\n readonly size: [number, number, number];\r\n private _albedo: Nullable<Texture3D>;\r\n private _emissive: 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(VOXEL_ATLAS_BLOCK, Math.ceil(v / VOXEL_ATLAS_BLOCK) * VOXEL_ATLAS_BLOCK)\r\n ) as [number, number, number];\r\n this._albedo = null;\r\n this._emissive = 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 albedo atlas, created on first use. */\r\n get albedo() {\r\n if (!this._albedo) {\r\n this._albedo = this.createTexture('@VoxelAlbedoAtlas');\r\n }\r\n return this._albedo;\r\n }\r\n /** The emissive atlas (RGBE), created on first use. */\r\n get emissive() {\r\n if (!this._emissive) {\r\n this._emissive = this.createTexture('@VoxelEmissiveAtlas');\r\n }\r\n return this._emissive;\r\n }\r\n /** Meshes resident in the atlas. */\r\n get count() {\r\n return this._entries.size;\r\n }\r\n /** Share of the atlas allocated, 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 is removed, so users of slot offsets can refresh them. */\r\n get version() {\r\n return this._version;\r\n }\r\n /** The slot of a resident mesh, or null. */\r\n getSlot(key: object) {\r\n return this._entries.get(key)?.slot ?? null;\r\n }\r\n /**\r\n * Allocates a region for a mesh.\r\n * @param key - Identity of the mesh, used to look it up and free it.\r\n * @param resolution - Voxels per axis.\r\n * @returns The slot, or null when nothing fits.\r\n */\r\n add(key: object, resolution: [number, number, number]): Nullable<VoxelAtlasSlot> {\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);\r\n if (!box) {\r\n return null;\r\n }\r\n const entry: Entry = {\r\n slot: { offset: [box.x, box.y, box.z], resolution: [...resolution] },\r\n box\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 meshes of the given resolutions would fit an empty atlas, packed\r\n * in {@link VoxelMaterialAtlas.packOrder}. Changes nothing.\r\n */\r\n fits(resolutions: [number, number, number][]) {\r\n const allocator = new VolumeBoxAllocator(this.size);\r\n return VoxelMaterialAtlas.packOrder(resolutions).every((r) => !!allocator.allocate(this.blockAligned(r)));\r\n }\r\n /**\r\n * The order an atlas cleared for a set of meshes adds them in, largest\r\n * first, for which {@link VoxelMaterialAtlas.fits} answers.\r\n */\r\n static packOrder<T extends [number, number, number] | { resolution: [number, number, number] }>(\r\n items: T[]\r\n ) {\r\n const volume = (item: T) => {\r\n const r = Array.isArray(item) ? item : item.resolution;\r\n return r[0] * r[1] * r[2];\r\n };\r\n return [...items].sort((a, b) => volume(b) - volume(a));\r\n }\r\n /**\r\n * Packs the given meshes from an empty atlas in\r\n * {@link VoxelMaterialAtlas.packOrder}, freeing every other region. Fails,\r\n * changing nothing, when they do not all fit (see {@link VoxelMaterialAtlas.fits}).\r\n * @returns The keys whose region moved, whose content is lost, or null.\r\n */\r\n repack(items: { key: object; resolution: [number, number, number] }[]): Nullable<Set<object>> {\r\n const allocator = new VolumeBoxAllocator(this.size);\r\n const placed: { key: object; resolution: [number, number, number]; box: VolumeBox }[] = [];\r\n for (const item of VoxelMaterialAtlas.packOrder(items)) {\r\n const box = allocator.allocate(this.blockAligned(item.resolution));\r\n if (!box) {\r\n return null;\r\n }\r\n placed.push({ ...item, box });\r\n }\r\n const moved = new Set<object>();\r\n const entries = new Map<object, Entry>();\r\n this._usedVoxels = 0;\r\n for (const { key, resolution, box } of placed) {\r\n const old = this._entries.get(key)?.box;\r\n if (!old || old.x !== box.x || old.y !== box.y || old.z !== box.z) {\r\n moved.add(key);\r\n }\r\n entries.set(key, { slot: { offset: [box.x, box.y, box.z], resolution: [...resolution] }, box });\r\n this._usedVoxels += box.w * box.h * box.d;\r\n }\r\n this._entries.clear();\r\n for (const [key, entry] of entries) {\r\n this._entries.set(key, entry);\r\n }\r\n this._allocator = allocator;\r\n this._version++;\r\n return moved;\r\n }\r\n /** Frees the region of a mesh. */\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 /** Frees every region; the textures keep their content until written again. */\r\n clear() {\r\n this._entries.clear();\r\n this._allocator.reset();\r\n this._usedVoxels = 0;\r\n this._version++;\r\n }\r\n dispose() {\r\n this._albedo?.dispose();\r\n this._emissive?.dispose();\r\n this._albedo = null;\r\n this._emissive = null;\r\n this.clear();\r\n }\r\n /** @internal */\r\n private blockAligned(resolution: [number, number, number]) {\r\n return resolution.map((v) => Math.ceil(v / VOXEL_ATLAS_BLOCK) * VOXEL_ATLAS_BLOCK) as [\r\n number,\r\n number,\r\n number\r\n ];\r\n }\r\n /** @internal */\r\n private createTexture(name: string) {\r\n const [w, h, d] = this.size;\r\n const tex = getDevice().createTexture3D('rgba8unorm', w, h, d, { mipmapping: false, writable: true })!;\r\n tex.name = name;\r\n return tex;\r\n }\r\n}\r\n"],"names":["VOXEL_ATLAS_BLOCK","VoxelMaterialAtlas","size","_albedo","_emissive","_allocator","_entries","_usedVoxels","_version","map","v","Math","max","ceil","VolumeBoxAllocator","Map","albedo","createTexture","emissive","count","occupancy","version","getSlot","key","get","slot","add","resolution","existing","need","blockAligned","box","allocate","entry","offset","x","y","z","set","w","h","d","fits","resolutions","allocator","packOrder","every","r","items","volume","item","Array","isArray","sort","a","b","repack","placed","push","moved","Set","entries","old","clear","remove","delete","free","reset","dispose","name","tex","getDevice","createTexture3D","mipmapping","writable"],"mappings":"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"}
|