@zephyr3d/scene 0.9.27 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -27
- package/dist/animation/animation_bank.js +634 -0
- package/dist/animation/animation_bank.js.map +1 -0
- package/dist/animation/animation_bank_gpu.js +256 -0
- package/dist/animation/animation_bank_gpu.js.map +1 -0
- package/dist/animation/animationset.js +54 -0
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_component.js +406 -0
- package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
- package/dist/animation/cloth/gpu_cloth_system.js +332 -202
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/gpu_animation_driver.js +289 -0
- package/dist/animation/gpu_animation_driver.js.map +1 -0
- package/dist/animation/joint_dynamics/collision.js +112 -1
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +6 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +50 -12
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/skeleton.js +279 -55
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skin_palette_atlas.js +252 -0
- package/dist/animation/skin_palette_atlas.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +298 -38
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +2 -0
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +159 -21
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_solver.js +173 -0
- package/dist/animation/spring/spring_solver.js.map +1 -0
- package/dist/animation/spring/spring_system.js +249 -24
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +32 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/app.js +26 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +86 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/gamepad.js +191 -0
- package/dist/app/gamepad.js.map +1 -0
- package/dist/app/inputactions.js +271 -0
- package/dist/app/inputactions.js.map +1 -0
- package/dist/app/inputmgr.js +331 -22
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/loading.js +138 -0
- package/dist/app/loading.js.map +1 -0
- package/dist/app/pipelinecache.js +209 -0
- package/dist/app/pipelinecache.js.map +1 -0
- package/dist/app/runtimescript.js +25 -0
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/scriptingsystem.js +54 -0
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +7 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/asset_manifest.js +59 -0
- package/dist/asset/asset_manifest.js.map +1 -0
- package/dist/asset/asset_preload.js +258 -0
- package/dist/asset/asset_preload.js.map +1 -0
- package/dist/asset/assetmanager.js +117 -65
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/dist/asset/loaders/ktx2/basis_location.js +17 -0
- package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
- package/dist/asset/mesh_lod_builder.js +104 -0
- package/dist/asset/mesh_lod_builder.js.map +1 -0
- package/dist/asset/mesh_settings.js +111 -0
- package/dist/asset/mesh_settings.js.map +1 -0
- package/dist/asset/meshopt_decoder.js +18 -0
- package/dist/asset/meshopt_decoder.js.map +1 -0
- package/dist/asset/meshopt_simplifier.js +26 -0
- package/dist/asset/meshopt_simplifier.js.map +1 -0
- package/dist/asset/model.js +171 -1
- package/dist/asset/model.js.map +1 -1
- package/dist/asset/texture_settings.js +231 -0
- package/dist/asset/texture_settings.js.map +1 -0
- package/dist/asset/zmsh_binary.js +131 -0
- package/dist/asset/zmsh_binary.js.map +1 -0
- package/dist/asset/zsdf_binary.js +111 -0
- package/dist/asset/zsdf_binary.js.map +1 -0
- package/dist/blitter/bilateralblur.js +1 -2
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/gaussianblur.js +1 -6
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +31 -10
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +104 -178
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/follow.js +342 -0
- package/dist/camera/follow.js.map +1 -0
- package/dist/camera/fps.js +9 -7
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +46 -19
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +25436 -15990
- package/dist/index.js +65 -11
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +3 -0
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/eye.js +1 -1
- package/dist/material/eye.js.map +1 -1
- package/dist/material/hair.js +2 -3
- package/dist/material/hair.js.map +1 -1
- package/dist/material/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +66 -4
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +118 -45
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +191 -83
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +31 -206
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +1 -1
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrmr.js +3 -0
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +3 -0
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/sdf_debug.js +78 -0
- package/dist/material/sdf_debug.js.map +1 -0
- package/dist/material/shader/helper.js +333 -191
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +204 -43
- package/dist/material/shader/terrain_blend.js.map +1 -1
- package/dist/material/skin.js +331 -297
- package/dist/material/skin.js.map +1 -1
- package/dist/material/skinprofile.js +1058 -0
- package/dist/material/skinprofile.js.map +1 -0
- package/dist/material/sss.js +353 -0
- package/dist/material/sss.js.map +1 -0
- package/dist/material/sss_kernel.js +265 -0
- package/dist/material/sss_kernel.js.map +1 -0
- package/dist/material/sssprofile.js +879 -0
- package/dist/material/sssprofile.js.map +1 -0
- package/dist/material/subsurfaceprofile.js +4 -8
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/terrain-cm.js +464 -188
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js +3 -0
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js +1261 -1438
- package/dist/material/water.js.map +1 -1
- package/dist/node_modules/meshoptimizer/LICENSE +21 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
- package/dist/physics/character.js +226 -0
- package/dist/physics/character.js.map +1 -0
- package/dist/physics/collider.js +209 -0
- package/dist/physics/collider.js.map +1 -0
- package/dist/physics/events.js +79 -0
- package/dist/physics/events.js.map +1 -0
- package/dist/physics/joint.js +272 -0
- package/dist/physics/joint.js.map +1 -0
- package/dist/physics/node_physics.js +234 -0
- package/dist/physics/node_physics.js.map +1 -0
- package/dist/physics/part.js +91 -0
- package/dist/physics/part.js.map +1 -0
- package/dist/physics/rigid_body.js +379 -0
- package/dist/physics/rigid_body.js.map +1 -0
- package/dist/physics/vehicle.js +335 -0
- package/dist/physics/vehicle.js.map +1 -0
- package/dist/physics/world.js +25 -0
- package/dist/physics/world.js.map +1 -0
- package/dist/posteffect/bloom.js +49 -14
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/motionblur.js +106 -106
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +2 -6
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +605 -355
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +91 -162
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -11
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +4 -13
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +1 -0
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +3 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +179 -64
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +958 -224
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +25 -5
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/debug_views.js +37 -0
- package/dist/render/debug_views.js.map +1 -0
- package/dist/render/depthpass.js +5 -1
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +53 -6
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +5 -5
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +196 -113
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +5 -10
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +247 -157
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +16 -38
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/gi/probe_volume.js +1334 -0
- package/dist/render/gi/probe_volume.js.map +1 -0
- package/dist/render/gi/scene_gi.js +282 -0
- package/dist/render/gi/scene_gi.js.map +1 -0
- package/dist/render/gi/voxel_atlas.js +198 -0
- package/dist/render/gi/voxel_atlas.js.map +1 -0
- package/dist/render/gi/voxel_lighting.js +652 -0
- package/dist/render/gi/voxel_lighting.js.map +1 -0
- package/dist/render/gi/voxel_scene.js +642 -0
- package/dist/render/gi/voxel_scene.js.map +1 -0
- package/dist/render/gi/voxelize_pass.js +223 -0
- package/dist/render/gi/voxelize_pass.js.map +1 -0
- package/dist/render/globalbindgroup_allocator.js +3 -2
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/gpu_picking.js +9 -36
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +19 -8
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/lod.js +46 -0
- package/dist/render/lod.js.map +1 -0
- package/dist/render/primitive.js +301 -9
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/primitive_readback.js +209 -0
- package/dist/render/primitive_readback.js.map +1 -0
- package/dist/render/render_queue.js +162 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +10 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +14 -1
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/executor.js +136 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +272 -55
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +41 -0
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
- package/dist/render/rendergraph/scene_render_context.js +31 -2
- package/dist/render/rendergraph/scene_render_context.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +28 -5
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sdf/box_allocator.js +98 -0
- package/dist/render/sdf/box_allocator.js.map +1 -0
- package/dist/render/sdf/global_sdf.js +865 -0
- package/dist/render/sdf/global_sdf.js.map +1 -0
- package/dist/render/sdf/scene_sdf.js +562 -0
- package/dist/render/sdf/scene_sdf.js.map +1 -0
- package/dist/render/sdf/sdf_atlas.js +227 -0
- package/dist/render/sdf/sdf_atlas.js.map +1 -0
- package/dist/render/sdf/sdf_programs.js +42 -0
- package/dist/render/sdf/sdf_programs.js.map +1 -0
- package/dist/render/sdf/sdf_view.js +199 -0
- package/dist/render/sdf/sdf_view.js.map +1 -0
- package/dist/render/sdf/waterline.js +610 -0
- package/dist/render/sdf/waterline.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +142 -25
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/shore_wave_generator.js +1193 -0
- package/dist/render/shore_wave_generator.js.map +1 -0
- package/dist/render/sky.js +516 -86
- package/dist/render/sky.js.map +1 -1
- package/dist/render/transmission_thickness_pass.js +477 -0
- package/dist/render/transmission_thickness_pass.js.map +1 -0
- package/dist/render/underwater.js +58 -158
- package/dist/render/underwater.js.map +1 -1
- package/dist/render/virtualtexture/virtual_texture.js +1214 -0
- package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_common.js +472 -0
- package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
- package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
- package/dist/render/volumetric_cloud/debug_view.js +131 -0
- package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
- package/dist/render/volumetric_cloud/resources.js +380 -0
- package/dist/render/volumetric_cloud/resources.js.map +1 -0
- package/dist/render/volumetric_cloud/sky_cache.js +380 -0
- package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
- package/dist/render/water_caustics.js +134 -319
- package/dist/render/water_caustics.js.map +1 -1
- package/dist/render/water_foam.js +627 -0
- package/dist/render/water_foam.js.map +1 -0
- package/dist/render/water_interaction.js +1795 -0
- package/dist/render/water_interaction.js.map +1 -0
- package/dist/render/weightedblended_oit.js +3 -3
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +9 -4
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +108 -12
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +28 -7
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/foliage.js +1020 -0
- package/dist/scene/foliage.js.map +1 -0
- package/dist/scene/foliage_buckets.js +147 -0
- package/dist/scene/foliage_buckets.js.map +1 -0
- package/dist/scene/foliage_mask.js +358 -0
- package/dist/scene/foliage_mask.js.map +1 -0
- package/dist/scene/hair.js +15 -4
- package/dist/scene/hair.js.map +1 -1
- package/dist/scene/light.js +179 -13
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +327 -45
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +9 -3
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +9 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +8 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/physics_settings.js +157 -0
- package/dist/scene/physics_settings.js.map +1 -0
- package/dist/scene/scene.js +190 -44
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +147 -6
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
- package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +881 -42
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grass_gpu.js +929 -0
- package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js +180 -9
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +465 -36
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
- package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
- package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
- package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
- package/dist/scene/update_queue.js +54 -0
- package/dist/scene/update_queue.js.map +1 -0
- package/dist/scene/water.js +633 -268
- package/dist/scene/water.js.map +1 -1
- package/dist/scene/water_surface_sampler.js +324 -0
- package/dist/scene/water_surface_sampler.js.map +1 -0
- package/dist/scene/wind.js +317 -0
- package/dist/scene/wind.js.map +1 -0
- package/dist/shaders/atmosphere.js +388 -166
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +100 -32
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/gi.js +365 -0
- package/dist/shaders/gi.js.map +1 -0
- package/dist/shaders/ltc_rect.js +202 -0
- package/dist/shaders/ltc_rect.js.map +1 -0
- package/dist/shaders/misc.js +1 -10
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +5 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/probes.js +309 -0
- package/dist/shaders/probes.js.map +1 -0
- package/dist/shaders/sdf.js +537 -0
- package/dist/shaders/sdf.js.map +1 -0
- package/dist/shaders/shadow.js +104 -70
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/skin_brdf.js +243 -0
- package/dist/shaders/skin_brdf.js.map +1 -0
- package/dist/shaders/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.js.map +1 -0
- package/dist/shaders/ssr.js +6 -159
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js +38 -27
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +32 -82
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +7 -21
- package/dist/shaders/water_medium.js.map +1 -1
- package/dist/shadow/dom.js +110 -19
- package/dist/shadow/dom.js.map +1 -1
- package/dist/shadow/esm.js +3 -3
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -48
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -53
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +34 -9
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +3 -8
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +40 -2
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +93 -53
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +18 -72
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -3
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/shape.js +44 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/utility/buoyancy.js +287 -0
- package/dist/utility/buoyancy.js.map +1 -0
- package/dist/utility/physical.js +10 -1
- package/dist/utility/physical.js.map +1 -1
- package/dist/utility/pmrem.js +17 -43
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/sdf/bake.js +435 -0
- package/dist/utility/sdf/bake.js.map +1 -0
- package/dist/utility/sdf/bvh.js +576 -0
- package/dist/utility/sdf/bvh.js.map +1 -0
- package/dist/utility/serialization/manager.js +34 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +46 -5
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +11 -4
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +87 -254
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth.js +25 -0
- package/dist/utility/serialization/scene/cloth.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +14 -6
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/foliage.js +821 -0
- package/dist/utility/serialization/scene/foliage.js.map +1 -0
- package/dist/utility/serialization/scene/hair.js +11 -4
- package/dist/utility/serialization/scene/hair.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +115 -7
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +388 -220
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +69 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +140 -5
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/node_physics.js +1318 -0
- package/dist/utility/serialization/scene/node_physics.js.map +1 -0
- package/dist/utility/serialization/scene/particle.js +11 -4
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/physics.js +120 -0
- package/dist/utility/serialization/scene/physics.js.map +1 -0
- package/dist/utility/serialization/scene/primitive.js +124 -10
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +1687 -51
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +11 -4
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +163 -33
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +11 -4
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +1543 -264
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +10 -22
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/foam.js +170 -0
- package/dist/utility/textures/foam.js.map +1 -0
- package/dist/utility/textures/ggxlut.js +17 -43
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +4 -4
- package/dist/utility/textures/ltcdata.js.map +1 -1
- package/dist/utility/textures/ltclut.js +16 -6
- package/dist/utility/textures/ltclut.js.map +1 -1
- package/dist/utility/unsupported.js +24 -0
- package/dist/utility/unsupported.js.map +1 -0
- package/dist/values.js +13 -1
- package/dist/values.js.map +1 -1
- package/package.json +25 -12
- package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/src/asset/meshoptimizer/LICENSE +21 -0
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrain-cm.js","sources":["../../../src/scene/terrain-cm/terrain-cm.ts"],"sourcesContent":["import type { Immutable, Matrix4x4, Nullable } from '@zephyr3d/base';\r\nimport { Vector4, applyMixins, Vector3, DRef, randomUUID } from '@zephyr3d/base';\r\nimport type { PBInsideFunctionScope, PBShaderExp, Texture2D } from '@zephyr3d/device';\r\nimport type { Scene } from '../scene';\r\nimport { GraphNode } from '../graph_node';\r\nimport { mixinDrawable } from '../../render/drawable_mixin';\r\nimport type { Drawable, DrawContext, PickTarget, PrimitiveInstanceInfo, RenderQueue } from '../../render';\r\nimport { Clipmap } from '../../render';\r\nimport { ClipmapTerrainMaterial } from '../../material/terrain-cm';\r\nimport { BoundingBox } from '../../utility/bounding_volume';\r\nimport {\r\n MAX_TERRAIN_MIPMAP_LEVELS,\r\n QUEUE_OPAQUE,\r\n RENDER_PASS_TYPE_OBJECT_COLOR,\r\n RENDER_PASS_TYPE_SHADOWMAP\r\n} from '../../values';\r\nimport type { BlitType } from '../../blitter';\r\nimport { CopyBlitter } from '../../blitter';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { RenderMipmap } from '../../utility/rendermipmap';\r\nimport { GrassRenderer } from './grass';\r\nimport type { Camera } from '../../camera';\r\nimport { getDevice } from '../../app/api';\r\n\r\nclass HeightMinMaxBlitter extends CopyBlitter {\r\n filter(\r\n scope: PBInsideFunctionScope,\r\n type: BlitType,\r\n srcTex: PBShaderExp,\r\n srcUV: PBShaderExp,\r\n srcLayer: PBShaderExp,\r\n sampleType: 'float' | 'int' | 'uint'\r\n ) {\r\n return this.readTexel(scope, type, srcTex, srcUV, srcLayer, sampleType).xxxx as PBShaderExp;\r\n }\r\n}\r\n\r\nclass HeightBoundingGenerator extends RenderMipmap {\r\n renderPixel(\r\n scope: PBInsideFunctionScope,\r\n leftTop: PBShaderExp,\r\n rightTop: PBShaderExp,\r\n leftBottom: PBShaderExp,\r\n rightBottom: PBShaderExp\r\n ) {\r\n const pb = scope.$builder;\r\n scope.$l.maxHeight = pb.max(pb.max(leftTop.r, rightTop.r), pb.max(leftBottom.r, rightBottom.r));\r\n scope.$l.minHeight = pb.min(pb.min(leftTop.g, rightTop.g), pb.min(leftBottom.g, rightBottom.g));\r\n return pb.vec4(scope.maxHeight, scope.minHeight, leftTop.r, 1);\r\n }\r\n}\r\n\r\n/**\r\n * ClipmapTerrain implements an efficient terrain rendering system using clipmaps.\r\n *\r\n * Clipmaps provide level-of-detail (LOD) rendering for large terrains by using\r\n * multiple nested grids at different resolutions. The terrain automatically\r\n * adjusts detail levels based on camera distance, providing high detail near\r\n * the camera and lower detail in the distance.\r\n *\r\n * Key features:\r\n * - Automatic LOD management based on camera position\r\n * - Support for height maps, splat maps, and detail textures\r\n * - Integrated grass rendering system\r\n *\r\n * @public\r\n */\r\nexport class ClipmapTerrain extends applyMixins(GraphNode, mixinDrawable) implements Drawable {\r\n private static readonly _heightBoundingGenerator = new HeightBoundingGenerator();\r\n private static readonly _copyBlitter = new HeightMinMaxBlitter();\r\n private static readonly _tmpBuffer = new Float32Array(MAX_TERRAIN_MIPMAP_LEVELS * 2 * 4);\r\n private readonly _pickTarget: PickTarget;\r\n private _clipmap: Clipmap;\r\n private _renderData: Nullable<PrimitiveInstanceInfo[]>;\r\n private _gridScale: number;\r\n private _material: DRef<ClipmapTerrainMaterial>;\r\n private _grassRenderer: DRef<GrassRenderer>;\r\n private _castShadow: boolean;\r\n private _sizeX: number;\r\n private _sizeZ: number;\r\n private _heightMapAssetId: string;\r\n private _splatMapAssetId: string;\r\n private _grassAssetId: string;\r\n private _minHeight: number;\r\n private _maxHeight: number;\r\n private _tmpTexture: DRef<Texture2D>;\r\n /**\r\n * Creates a new clipmap terrain instance.\r\n *\r\n * @param scene - Scene to add the terrain to\r\n * @param sizeX - Terrain width in world units (default: 256)\r\n * @param sizeZ - Terrain depth in world units (default: 256)\r\n * @param clipMapTileSize - Size of each clipmap tile in vertices (default: 64)\r\n * Larger values use more memory but reduce draw calls\r\n *\r\n */\r\n constructor(scene: Scene, sizeX = 256, sizeZ = 256, clipMapTileSize = 64) {\r\n super(scene);\r\n this._pickTarget = { node: this };\r\n this._clipmap = new Clipmap(clipMapTileSize, ['tex1_f32'], MAX_TERRAIN_MIPMAP_LEVELS);\r\n this._renderData = null;\r\n this._grassRenderer = new DRef(new GrassRenderer(this));\r\n this._gridScale = 1;\r\n this._castShadow = true;\r\n this._sizeX = sizeX;\r\n this._sizeZ = sizeZ;\r\n this._heightMapAssetId = `assets/.embedded.dir/${this.persistentId}-heightmap.bin`;\r\n this._grassAssetId = `assets/.embedded.dir/${this.persistentId}-grass.bin`;\r\n this._splatMapAssetId = `assets/.embedded.dir/${this.persistentId}-splatmap.bin`;\r\n this._minHeight = 0;\r\n this._maxHeight = 0;\r\n this._material = new DRef(\r\n new ClipmapTerrainMaterial(this.createHeightMapTexture(this._sizeX, this._sizeZ))\r\n );\r\n this._tmpTexture = new DRef();\r\n this.updateRegion();\r\n scene.queuePerCameraUpdateNode(this);\r\n }\r\n /**\r\n * Gets the integrated grass renderer for this terrain.\r\n * The grass renderer handles vegetation rendering on the terrain surface.\r\n *\r\n * @returns The grass renderer instance\r\n */\r\n get grassRenderer() {\r\n return this._grassRenderer.get()!;\r\n }\r\n /**\r\n * Gets the maximum number of detail maps supported by the terrain material.\r\n * Detail maps provide surface texturing (grass, rock, sand, etc.).\r\n *\r\n * @returns Maximum number of detail maps\r\n */\r\n get MAX_DETAIL_MAP_COUNT() {\r\n return ClipmapTerrainMaterial.MAX_DETAIL_MAP_COUNT;\r\n }\r\n /**\r\n * Gets the asset ID for the height map texture.\r\n * Generates a random UUID if not previously set.\r\n *\r\n * @returns Height map asset ID\r\n * @internal\r\n */\r\n get heightMapAssetId() {\r\n if (!this._heightMapAssetId) {\r\n this._heightMapAssetId = randomUUID();\r\n }\r\n return this._heightMapAssetId;\r\n }\r\n /** @internal */\r\n set heightMapAssetId(val: string) {\r\n this._heightMapAssetId = val;\r\n }\r\n /**\r\n * Gets the asset ID for the splat map texture.\r\n * Generates a random UUID if not previously set.\r\n *\r\n * @returns Splat map asset ID\r\n * @internal\r\n */\r\n get splatMapAssetId() {\r\n if (!this._splatMapAssetId) {\r\n this._splatMapAssetId = randomUUID();\r\n }\r\n return this._splatMapAssetId;\r\n }\r\n /** @internal */\r\n set splatMapAssetId(val: string) {\r\n this._splatMapAssetId = val;\r\n }\r\n /**\r\n * Gets the asset ID for grass configuration.\r\n * Generates a random UUID if not previously set.\r\n *\r\n * @returns Grass asset ID\r\n * @internal\r\n */\r\n get grassAssetId() {\r\n if (!this._grassAssetId) {\r\n this._grassAssetId = randomUUID();\r\n }\r\n return this._grassAssetId;\r\n }\r\n /** @internal */\r\n set grassAssetId(val: string) {\r\n this._grassAssetId = val;\r\n }\r\n /**\r\n * The current number of active detail maps.\r\n * Detail maps define different surface materials (grass, rock, etc.).\r\n *\r\n * @returns Number of active detail maps\r\n */\r\n get numDetailMaps() {\r\n return this.material?.numDetailMaps ?? 0;\r\n }\r\n set numDetailMaps(val) {\r\n if (this.material) {\r\n this.material.numDetailMaps = val;\r\n }\r\n }\r\n /** {@inheritDoc SceneNode.clone} */\r\n async clone(): Promise<this> {\r\n throw new Error('Cloning clipmap terrain not implemented');\r\n }\r\n /**\r\n * Sets the terrain size.\r\n * Triggers height map resize if dimensions change.\r\n *\r\n * @param sizeX - New width\r\n * @param sizeZ - New depth\r\n */\r\n setSize(sizeX: number, sizeZ: number) {\r\n if (sizeX !== this._sizeX || sizeZ !== this._sizeZ) {\r\n this._sizeX = sizeX;\r\n this._sizeZ = sizeZ;\r\n this.resizeHeightMap(this._sizeX, this._sizeZ);\r\n }\r\n }\r\n /** Wether the mesh node casts shadows */\r\n get castShadow() {\r\n return this._castShadow;\r\n }\r\n set castShadow(val) {\r\n this._castShadow = !!val;\r\n }\r\n /** The terrain width. */\r\n get sizeX() {\r\n return this._sizeX;\r\n }\r\n set sizeX(val) {\r\n if (val !== this._sizeX) {\r\n this._sizeX = val;\r\n this.resizeHeightMap(this._sizeX, this._sizeZ);\r\n }\r\n }\r\n /** The terrain depth. */\r\n get sizeZ() {\r\n return this._sizeZ;\r\n }\r\n set sizeZ(val) {\r\n if (val !== this._sizeZ) {\r\n this._sizeZ = val;\r\n this.resizeHeightMap(this._sizeX, this._sizeZ);\r\n }\r\n }\r\n /** The current height map texture. */\r\n get heightMap() {\r\n return this.material?.heightMap ?? null;\r\n }\r\n set heightMap(val) {\r\n if (this.material && val) {\r\n this.material.heightMap = val;\r\n this.updateRegion();\r\n }\r\n }\r\n /** The splat map texture */\r\n get splatMap() {\r\n return this.material?.getSplatMap() ?? null;\r\n }\r\n /** Material instance of the terrain */\r\n get material() {\r\n return this._material?.get() ?? null;\r\n }\r\n /** whether wireframe rendering is enabled */\r\n get wireframe() {\r\n return this._clipmap.wireframe;\r\n }\r\n set wireframe(val) {\r\n this._clipmap.wireframe = val;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getPickTarget }\r\n */\r\n getPickTarget() {\r\n return this._pickTarget;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getMorphData}\r\n */\r\n getMorphData() {\r\n return null;\r\n }\r\n getSkinInfluenceData() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getMorphInfo}\r\n */\r\n getMorphInfo() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getQueueType}\r\n */\r\n getQueueType() {\r\n return this.material?.getQueueType() ?? QUEUE_OPAQUE;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.isUnlit}\r\n */\r\n isUnlit() {\r\n return this.material ? !this.material.supportLighting() : false;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.needSceneColor}\r\n */\r\n needSceneColor() {\r\n return this.material?.needSceneColor() ?? false;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.needSceneDepth}\r\n */\r\n needSceneDepth() {\r\n return this.material?.needSceneDepth() ?? false;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getMaterial}\r\n */\r\n getMaterial() {\r\n return this._material.get();\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getPrimitive}\r\n */\r\n getPrimitive() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.isClipmapTerrain}\r\n */\r\n isClipmapTerrain(): this is ClipmapTerrain {\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.computeBoundingVolume}\r\n */\r\n computeBoundingVolume() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.computeWorldBoundingVolume}\r\n */\r\n computeWorldBoundingVolume() {\r\n if (this.material) {\r\n const p = this.worldMatrix.transformPointAffine(Vector3.zero());\r\n const minHeight = this._minHeight * this.scale.y;\r\n const maxHeight = this._maxHeight * this.scale.y;\r\n return new BoundingBox(\r\n new Vector3(this.material.region.x, p.y + Math.min(minHeight, maxHeight), this.material.region.y),\r\n new Vector3(this.material.region.z, p.y + Math.max(minHeight, maxHeight), this.material.region.w)\r\n );\r\n } else {\r\n return null;\r\n }\r\n }\r\n /**\r\n * the actual world-space region covered by this terrain (After applying world transform).\r\n */\r\n get worldRegion(): Immutable<Vector4> {\r\n return this.material?.region ?? Vector4.zero();\r\n }\r\n /**\r\n * Calculates the local transformation matrix.\r\n * For terrains, this only includes translation.\r\n *\r\n * @param outMatrix - Output matrix to store the result\r\n */\r\n calculateLocalTransform(outMatrix: Matrix4x4) {\r\n outMatrix.translation(this._position);\r\n }\r\n /**\r\n * Calculates the world transformation matrix.\r\n * Terrains inherit only translation from parent nodes.\r\n *\r\n * @param outMatrix - Output matrix to store the result\r\n */\r\n calculateWorldTransform(outMatrix: Matrix4x4) {\r\n outMatrix.set(this.localMatrix);\r\n if (this.parent) {\r\n outMatrix.m03 += this.parent.worldMatrix.m03;\r\n outMatrix.m13 += this.parent.worldMatrix.m13;\r\n outMatrix.m23 += this.parent.worldMatrix.m23;\r\n }\r\n }\r\n /**\r\n * Updates the terrain's bounding box by analyzing the height map.\r\n * This is an asynchronous operation that reads back GPU data.\r\n *\r\n * @param tmpTexture - Optional temporary texture to reuse (optimization)\r\n *\r\n * @example\r\n * ```typescript\r\n * // Update bounding box after changing height map\r\n * terrain.heightMap = newHeightMap;\r\n * terrain.updateBoundingBox();\r\n * ```\r\n */\r\n updateBoundingBox() {\r\n const heightMap = this.heightMap;\r\n if (!heightMap) {\r\n return;\r\n }\r\n const device = getDevice();\r\n let tmp = this._tmpTexture.get();\r\n if (tmp && (tmp.width !== heightMap.width || tmp.height !== heightMap.height)) {\r\n this._tmpTexture.dispose();\r\n }\r\n if (!this._tmpTexture.get()) {\r\n tmp = getDevice().createTexture2D(\r\n device.type === 'webgl' ? 'rgba32f' : 'rg32f',\r\n heightMap.width,\r\n heightMap.height\r\n )!;\r\n tmp.name = 'TerrainBoundingBoxTexture';\r\n this._tmpTexture.set(tmp);\r\n }\r\n const tmpFB = device.createFrameBuffer([tmp!], null);\r\n ClipmapTerrain._copyBlitter.blit(heightMap, tmpFB, fetchSampler('clamp_nearest_nomip'));\r\n tmpFB.dispose();\r\n ClipmapTerrain._heightBoundingGenerator.render(tmp!);\r\n const data = new Float32Array(4);\r\n tmp!\r\n .readPixels(0, 0, 1, 1, 0, tmp!.mipLevelCount - 1, data)\r\n .then(() => {\r\n this._minHeight = data[0];\r\n this._maxHeight = data[1];\r\n this.invalidateWorldBoundingVolume(false);\r\n })\r\n .catch((_err) => {\r\n console.error('Read pixels failed');\r\n });\r\n }\r\n /** @internal */\r\n createHeightMapTexture(width: number, height: number) {\r\n return getDevice().createTexture2D(getDevice().type === 'webgl' ? 'rgba16f' : 'r16f', width, height)!;\r\n }\r\n /** @internal */\r\n protected _onTransformChanged(invalidateLocal: boolean) {\r\n super._onTransformChanged(invalidateLocal);\r\n this.updateRegion();\r\n }\r\n /** {@inheritDoc SceneNode.updatePerCamera} */\r\n updatePerCamera(camera: Camera, _elapsedInSeconds: number, _deltaInSeconds: number) {\r\n const mat = this._material.get();\r\n if (!mat) {\r\n return;\r\n }\r\n const that = this;\r\n const bv = this.getWorldBoundingVolume()!.toAABB();\r\n this._renderData = this._clipmap.gather({\r\n camera: camera,\r\n minMaxWorldPos: mat.region,\r\n gridScale: this._gridScale,\r\n userData: this,\r\n frustumCulling: !this.castShadow,\r\n calcAABB(userData: unknown, minX, maxX, minZ, maxZ, outAABB) {\r\n const p = that.worldMatrix.transformPointAffine(Vector3.zero());\r\n outAABB.minPoint.setXYZ(minX, bv ? bv.minPoint.y : p.y - 9999, minZ);\r\n outAABB.maxPoint.setXYZ(maxX, bv ? bv.maxPoint.y : p.y + 9999, maxZ);\r\n }\r\n });\r\n let maxMipLevel = 0;\r\n for (const info of this._renderData) {\r\n const buffer = info.primitive.getVertexBuffer('texCoord1')!;\r\n buffer.bufferSubData(0, info.mipLevels, 0, info.numInstances);\r\n if (info.maxMiplevel > maxMipLevel) {\r\n maxMipLevel = info.maxMiplevel;\r\n }\r\n }\r\n const levelAABB = this._clipmap.calcLevelAABB(camera, mat.region, this._gridScale);\r\n const cameraPos = camera.getWorldPosition();\r\n const tmpBuffer = ClipmapTerrain._tmpBuffer;\r\n\r\n for (let i = 0; i <= maxMipLevel; i++) {\r\n if (i === 0) {\r\n tmpBuffer[i * 8 + 0] = cameraPos.x;\r\n tmpBuffer[i * 8 + 1] = cameraPos.z;\r\n tmpBuffer[i * 8 + 2] = cameraPos.x;\r\n tmpBuffer[i * 8 + 3] = cameraPos.z;\r\n } else {\r\n const prevAABB = levelAABB[i - 1];\r\n tmpBuffer[i * 8 + 0] = prevAABB.minPoint.x;\r\n tmpBuffer[i * 8 + 1] = prevAABB.minPoint.z;\r\n tmpBuffer[i * 8 + 2] = prevAABB.maxPoint.x;\r\n tmpBuffer[i * 8 + 3] = prevAABB.maxPoint.z;\r\n }\r\n const currentAABB = levelAABB[i];\r\n tmpBuffer[i * 8 + 4] = 1 / (currentAABB.minPoint.x - tmpBuffer[i * 8 + 0]);\r\n tmpBuffer[i * 8 + 5] = 1 / (currentAABB.minPoint.z - tmpBuffer[i * 8 + 1]);\r\n tmpBuffer[i * 8 + 6] = 1 / (currentAABB.maxPoint.x - tmpBuffer[i * 8 + 2]);\r\n tmpBuffer[i * 8 + 7] = 1 / (currentAABB.maxPoint.z - tmpBuffer[i * 8 + 3]);\r\n }\r\n mat.setLevelData(tmpBuffer, 8 * (maxMipLevel + 1));\r\n\r\n this.scene?.queuePerCameraUpdateNode(this);\r\n }\r\n /**\r\n * Updates the terrain material region based on current position and scale.\r\n * Should be called after changing position, scale, or height map.\r\n */\r\n updateRegion() {\r\n if (this.material) {\r\n const x = Math.abs(this.scale.x);\r\n const z = Math.abs(this.scale.z);\r\n const px = this.position.x + (this.parent?.worldMatrix.m03 ?? 0);\r\n const pz = this.position.z + (this.parent?.worldMatrix.m23 ?? 0);\r\n this._gridScale = Math.max(\r\n (x * this._sizeX) / this.material.heightMap.width,\r\n (z * this._sizeZ) / this.material.heightMap.height\r\n );\r\n this.material.update(new Vector4(px, pz, px + x * this._sizeX, pz + z * this._sizeZ), this.scale);\r\n this.grassRenderer.updateMaterial();\r\n }\r\n }\r\n /** {@inheritDoc Drawable.draw} */\r\n draw(ctx: DrawContext, renderQueue: Nullable<RenderQueue>) {\r\n const mat = this._material?.get();\r\n if (mat) {\r\n this.bind(ctx, renderQueue);\r\n mat.setClipmapGridInfo(this._gridScale, this.worldMatrix.m03, this.worldMatrix.m23);\r\n mat.apply(ctx);\r\n for (const info of this._renderData!) {\r\n mat.draw(info.primitive, ctx, info.numInstances);\r\n }\r\n if (\r\n ctx.renderPass!.type !== RENDER_PASS_TYPE_OBJECT_COLOR &&\r\n ctx.renderPass!.type !== RENDER_PASS_TYPE_SHADOWMAP\r\n ) {\r\n this.grassRenderer.draw(ctx);\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private resizeHeightMap(sizeX: number, sizeZ: number) {\r\n if (this.material) {\r\n const oldHeightMap = this.material.heightMap;\r\n const device = getDevice();\r\n const maxTextureSize = device.getDeviceCaps().textureCaps.maxTextureSize;\r\n sizeX = Math.min(Math.max(sizeX, 1), maxTextureSize) >> 0;\r\n sizeZ = Math.min(Math.max(sizeZ, 1), maxTextureSize) >> 0;\r\n if (sizeX !== oldHeightMap.width || sizeZ !== oldHeightMap.height) {\r\n const newHeightMap = device.createTexture2D(\r\n device.type === 'webgl' ? 'rgba16f' : 'r16f',\r\n sizeX,\r\n sizeZ\r\n )!;\r\n const fb = device.createFrameBuffer([newHeightMap], null);\r\n ClipmapTerrain._copyBlitter.blit(oldHeightMap, fb, fetchSampler('clamp_linear_nomip'));\r\n fb.dispose();\r\n this.heightMap = newHeightMap;\r\n this.updateBoundingBox();\r\n }\r\n }\r\n }\r\n /*\r\n private calcNormalHeightMap(): Texture2D {\r\n const device = getDevice();\r\n if (!ClipmapTerrain._normalHeightMapProgram) {\r\n ClipmapTerrain._normalHeightMapProgram = device.buildRenderProgram({\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 if (device.type === 'webgpu') {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n }\r\n });\r\n },\r\n fragment(pb) {\r\n this.heightMap = pb.tex2D().uniform(0);\r\n this.texelSize = pb.vec2().uniform(0);\r\n this.terrainScale = pb.vec3().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('calcNormal', [pb.vec2('texCoord')], function () {\r\n this.$l.t = pb.textureSample(\r\n this.heightMap,\r\n pb.sub(this.texCoord, pb.vec2(0, this.texelSize.y))\r\n ).r;\r\n this.$l.l = pb.textureSample(\r\n this.heightMap,\r\n pb.sub(this.texCoord, pb.vec2(this.texelSize.x, 0))\r\n ).r;\r\n this.$l.r = pb.textureSample(\r\n this.heightMap,\r\n pb.add(this.texCoord, pb.vec2(this.texelSize.x, 0))\r\n ).r;\r\n this.$l.b = pb.textureSample(\r\n this.heightMap,\r\n pb.add(this.texCoord, pb.vec2(0, this.texelSize.y))\r\n ).r;\r\n this.$l.tx = pb.vec3(this.terrainScale.x, pb.mul(pb.sub(this.r, this.l), this.terrainScale.y), 0);\r\n this.$l.tz = pb.vec3(0, pb.mul(pb.sub(this.b, this.t), this.terrainScale.y), this.terrainScale.z);\r\n this.$l.normal = pb.normalize(pb.cross(this.tz, this.tx));\r\n this.$return(this.normal);\r\n });\r\n pb.main(function () {\r\n this.$l.normal = this.calcNormal(this.$inputs.uv);\r\n this.$outputs.outColor = pb.vec4(pb.add(pb.mul(this.normal, 0.5), pb.vec3(0.5)), 1);\r\n });\r\n }\r\n });\r\n }\r\n }\r\n */\r\n /**\r\n * Disposes of all resources used by this terrain.\r\n * Should be called when the terrain is no longer needed.\r\n */\r\n protected onDispose() {\r\n super.onDispose();\r\n this._clipmap?.dispose();\r\n this._material?.dispose();\r\n this._grassRenderer?.dispose();\r\n }\r\n}\r\n"],"names":["HeightMinMaxBlitter","CopyBlitter","filter","scope","type","srcTex","srcUV","srcLayer","sampleType","readTexel","xxxx","HeightBoundingGenerator","RenderMipmap","renderPixel","leftTop","rightTop","leftBottom","rightBottom","pb","$builder","$l","maxHeight","max","r","minHeight","min","g","vec4","ClipmapTerrain","applyMixins","GraphNode","mixinDrawable","_heightBoundingGenerator","_copyBlitter","_tmpBuffer","Float32Array","MAX_TERRAIN_MIPMAP_LEVELS","_pickTarget","_clipmap","_renderData","_gridScale","_material","_grassRenderer","_castShadow","_sizeX","_sizeZ","_heightMapAssetId","_splatMapAssetId","_grassAssetId","_minHeight","_maxHeight","_tmpTexture","scene","sizeX","sizeZ","clipMapTileSize","node","Clipmap","DRef","GrassRenderer","persistentId","ClipmapTerrainMaterial","createHeightMapTexture","updateRegion","queuePerCameraUpdateNode","grassRenderer","get","MAX_DETAIL_MAP_COUNT","heightMapAssetId","randomUUID","val","splatMapAssetId","grassAssetId","numDetailMaps","material","clone","Error","setSize","resizeHeightMap","castShadow","heightMap","splatMap","getSplatMap","wireframe","getPickTarget","getMorphData","getSkinInfluenceData","getMorphInfo","getQueueType","QUEUE_OPAQUE","isUnlit","supportLighting","needSceneColor","needSceneDepth","getMaterial","getPrimitive","isClipmapTerrain","computeBoundingVolume","computeWorldBoundingVolume","p","worldMatrix","transformPointAffine","Vector3","zero","scale","y","BoundingBox","region","x","Math","z","w","worldRegion","Vector4","calculateLocalTransform","outMatrix","translation","_position","calculateWorldTransform","set","localMatrix","parent","m03","m13","m23","updateBoundingBox","device","getDevice","tmp","width","height","dispose","createTexture2D","name","tmpFB","createFrameBuffer","blit","fetchSampler","render","data","readPixels","mipLevelCount","then","invalidateWorldBoundingVolume","catch","_err","console","error","_onTransformChanged","invalidateLocal","updatePerCamera","camera","_elapsedInSeconds","_deltaInSeconds","mat","that","bv","getWorldBoundingVolume","toAABB","gather","minMaxWorldPos","gridScale","userData","frustumCulling","calcAABB","minX","maxX","minZ","maxZ","outAABB","minPoint","setXYZ","maxPoint","maxMipLevel","info","buffer","primitive","getVertexBuffer","bufferSubData","mipLevels","numInstances","maxMiplevel","levelAABB","calcLevelAABB","cameraPos","getWorldPosition","tmpBuffer","i","prevAABB","currentAABB","setLevelData","abs","px","position","pz","update","updateMaterial","draw","ctx","renderQueue","bind","setClipmapGridInfo","apply","renderPass","RENDER_PASS_TYPE_OBJECT_COLOR","RENDER_PASS_TYPE_SHADOWMAP","oldHeightMap","maxTextureSize","getDeviceCaps","textureCaps","newHeightMap","fb","onDispose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terrain-cm.js","sources":["../../../src/scene/terrain-cm/terrain-cm.ts"],"sourcesContent":["import type { AABB, Immutable, Matrix4x4, Nullable } from '@zephyr3d/base';\r\nimport { Vector4, applyMixins, Vector3, DRef, randomUUID, half2float, nextPowerOf2 } from '@zephyr3d/base';\r\nimport type {\r\n BaseTexture,\r\n BindGroup,\r\n PBGlobalScope,\r\n PBInsideFunctionScope,\r\n PBShaderExp,\r\n Texture2D\r\n} from '@zephyr3d/device';\r\nimport type { Scene } from '../scene';\r\nimport { GraphNode } from '../graph_node';\r\nimport { mixinDrawable } from '../../render/drawable_mixin';\r\nimport type {\r\n ClipmapGatherContext,\r\n Drawable,\r\n DrawContext,\r\n PickTarget,\r\n PrimitiveInstanceInfo,\r\n RenderQueue\r\n} from '../../render';\r\nimport { Clipmap } from '../../render';\r\nimport { ClipmapTerrainMaterial } from '../../material/terrain-cm';\r\nimport { BoundingBox } from '../../utility/bounding_volume';\r\nimport {\r\n MAX_TERRAIN_MIPMAP_LEVELS,\r\n QUEUE_OPAQUE,\r\n RENDER_PASS_TYPE_OBJECT_COLOR,\r\n RENDER_PASS_TYPE_SHADOWMAP\r\n} from '../../values';\r\nimport type { BlitType } from '../../blitter';\r\nimport { CopyBlitter } from '../../blitter';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { RenderMipmap } from '../../utility/rendermipmap';\r\nimport { GrassRenderer } from './grass';\r\nimport type { Camera } from '../../camera';\r\nimport { getDevice } from '../../app/api';\r\nimport type { TerrainVirtualTextureOptions } from './terrain_rvt';\r\nimport type { VirtualTexture } from '../../render/virtualtexture/virtual_texture';\r\nimport { TerrainVirtualTexture } from './terrain_rvt';\r\nimport { TerrainGIAlbedo } from './terrain_gi_albedo';\r\nimport { warnUnsupported } from '../../utility/unsupported';\r\n\r\nclass HeightMinMaxBlitter extends CopyBlitter {\r\n filter(\r\n scope: PBInsideFunctionScope,\r\n type: BlitType,\r\n srcTex: PBShaderExp,\r\n srcUV: PBShaderExp,\r\n srcLayer: PBShaderExp,\r\n sampleType: 'float' | 'int' | 'uint'\r\n ) {\r\n return this.readTexel(scope, type, srcTex, srcUV, srcLayer, sampleType).xxxx as PBShaderExp;\r\n }\r\n}\r\n\r\n/**\r\n * Copies the height map into the top-left of a power-of-two target, repeating the last row and\r\n * column into the padding. The min/max reduction halves each level with a 2x2 footprint, which\r\n * drops the last row or column of an odd sized level; padding with edge copies avoids that\r\n * without affecting either extreme.\r\n */\r\nclass HeightPadBlitter extends CopyBlitter {\r\n /** (dest width, dest height, source width, source height) */\r\n readonly sizes = new Vector4();\r\n setup(scope: PBGlobalScope, _type: BlitType) {\r\n const pb = scope.$builder;\r\n if (pb.shaderKind === 'fragment') {\r\n scope.padSizes = pb.vec4().uniform(0);\r\n }\r\n }\r\n setUniforms(bindGroup: BindGroup, _sourceTex: BaseTexture) {\r\n bindGroup.setValue('padSizes', this.sizes);\r\n }\r\n filter(\r\n scope: PBInsideFunctionScope,\r\n type: BlitType,\r\n srcTex: PBShaderExp,\r\n srcUV: PBShaderExp,\r\n srcLayer: PBShaderExp,\r\n sampleType: 'float' | 'int' | 'uint'\r\n ) {\r\n const pb = scope.$builder;\r\n const sizes = scope.padSizes as PBShaderExp;\r\n const texel = pb.min(pb.floor(pb.mul(srcUV, sizes.xy)), pb.sub(sizes.zw, pb.vec2(1)));\r\n const uv = pb.div(pb.add(texel, pb.vec2(0.5)), sizes.zw);\r\n return this.readTexel(scope, type, srcTex, uv, srcLayer, sampleType).xxxx as PBShaderExp;\r\n }\r\n}\r\n\r\nclass HeightBoundingGenerator extends RenderMipmap {\r\n renderPixel(\r\n scope: PBInsideFunctionScope,\r\n leftTop: PBShaderExp,\r\n rightTop: PBShaderExp,\r\n leftBottom: PBShaderExp,\r\n rightBottom: PBShaderExp\r\n ) {\r\n const pb = scope.$builder;\r\n scope.$l.maxHeight = pb.max(pb.max(leftTop.r, rightTop.r), pb.max(leftBottom.r, rightBottom.r));\r\n scope.$l.minHeight = pb.min(pb.min(leftTop.g, rightTop.g), pb.min(leftBottom.g, rightBottom.g));\r\n return pb.vec4(scope.maxHeight, scope.minHeight, leftTop.r, 1);\r\n }\r\n}\r\n\r\n/**\r\n * ClipmapTerrain implements an efficient terrain rendering system using clipmaps.\r\n *\r\n * Clipmaps provide level-of-detail (LOD) rendering for large terrains by using\r\n * multiple nested grids at different resolutions. The terrain automatically\r\n * adjusts detail levels based on camera distance, providing high detail near\r\n * the camera and lower detail in the distance.\r\n *\r\n * Key features:\r\n * - Automatic LOD management based on camera position\r\n * - Support for height maps, splat maps, and detail textures\r\n * - Integrated grass rendering system\r\n *\r\n * @public\r\n */\r\nexport class ClipmapTerrain extends applyMixins(GraphNode, mixinDrawable) implements Drawable {\r\n private static readonly _heightBoundingGenerator = new HeightBoundingGenerator();\r\n private static readonly _copyBlitter = new HeightMinMaxBlitter();\r\n private static readonly _padBlitter = new HeightPadBlitter();\r\n private static readonly _tmpBuffer = new Float32Array(MAX_TERRAIN_MIPMAP_LEVELS * 2 * 4);\r\n private readonly _pickTarget: PickTarget;\r\n private _clipmap: Clipmap;\r\n private _shadowClipmap: Clipmap;\r\n private _renderData: Nullable<PrimitiveInstanceInfo[]>;\r\n private _shadowRenderData: Nullable<PrimitiveInstanceInfo[]>;\r\n private _shadowGatherContext: Nullable<ClipmapGatherContext>;\r\n private _gridScale: number;\r\n /**\r\n * World position of clipmap grid point (0, 0): the centre of the first height map texel.\r\n * Texel i holds the height at the centre of cell i (the convention the height sampling,\r\n * brushes and grass placement all share), so this is what puts the finest level's vertices\r\n * on the samples instead of halfway between them.\r\n */\r\n private _gridOriginX: number;\r\n private _gridOriginZ: number;\r\n private _material: DRef<ClipmapTerrainMaterial>;\r\n private _grassRenderer: DRef<GrassRenderer>;\r\n private _castShadow: boolean;\r\n private _sizeX: number;\r\n private _sizeZ: number;\r\n private _heightMapAssetId: string;\r\n private _splatMapAssetId: string;\r\n private _grassAssetId: string;\r\n private _minHeight: number;\r\n private _maxHeight: number;\r\n /** Bumped by every height range update, so a read back overtaken by a newer one is dropped */\r\n private _heightRangeSerial: number;\r\n private _heightData: Nullable<{ data: Uint16Array; width: number; height: number }>;\r\n private _heightReadBack: Nullable<{\r\n version: number;\r\n promise: Promise<Nullable<{ data: Uint16Array; width: number; height: number }>>;\r\n }>;\r\n private _heightVersion: number;\r\n private _tmpTexture: DRef<Texture2D>;\r\n private _virtualTexture: Nullable<TerrainVirtualTexture>;\r\n private _giAlbedo: Nullable<TerrainGIAlbedo>;\r\n /**\r\n * Creates a new clipmap terrain instance.\r\n *\r\n * @param scene - Scene to add the terrain to\r\n * @param sizeX - Terrain width in world units (default: 256)\r\n * @param sizeZ - Terrain depth in world units (default: 256)\r\n * @param clipMapTileSize - Size of each clipmap tile in vertices (default: 64)\r\n * Larger values use more memory but reduce draw calls\r\n *\r\n */\r\n constructor(scene: Scene, sizeX = 256, sizeZ = 256, clipMapTileSize = 64) {\r\n super(scene);\r\n this._pickTarget = { node: this };\r\n this._clipmap = new Clipmap(clipMapTileSize, ['tex1_f32'], MAX_TERRAIN_MIPMAP_LEVELS);\r\n this._shadowClipmap = new Clipmap(clipMapTileSize, ['tex1_f32'], MAX_TERRAIN_MIPMAP_LEVELS);\r\n this._renderData = null;\r\n this._shadowRenderData = null;\r\n this._shadowGatherContext = null;\r\n this._grassRenderer = new DRef(new GrassRenderer(this));\r\n this._gridScale = 1;\r\n this._gridOriginX = 0;\r\n this._gridOriginZ = 0;\r\n this._castShadow = true;\r\n this._sizeX = sizeX;\r\n this._sizeZ = sizeZ;\r\n this._heightMapAssetId = `assets/.embedded.dir/${this.persistentId}-heightmap.bin`;\r\n this._grassAssetId = `assets/.embedded.dir/${this.persistentId}-grass.bin`;\r\n this._splatMapAssetId = `assets/.embedded.dir/${this.persistentId}-splatmap.bin`;\r\n this._minHeight = 0;\r\n this._maxHeight = 0;\r\n this._heightRangeSerial = 0;\r\n this._heightData = null;\r\n this._heightReadBack = null;\r\n this._heightVersion = 0;\r\n this._material = new DRef(\r\n new ClipmapTerrainMaterial(this.createHeightMapTexture(this._sizeX, this._sizeZ))\r\n );\r\n this._tmpTexture = new DRef();\r\n this._virtualTexture = null;\r\n this._giAlbedo = null;\r\n this.updateRegion();\r\n this.updateHeightPyramid();\r\n scene.queuePerCameraUpdateNode(this);\r\n }\r\n /**\r\n * Gets the integrated grass renderer for this terrain.\r\n * The grass renderer handles vegetation rendering on the terrain surface.\r\n *\r\n * @returns The grass renderer instance\r\n */\r\n get grassRenderer() {\r\n return this._grassRenderer.get()!;\r\n }\r\n /**\r\n * Gets the maximum number of detail maps supported by the terrain material.\r\n * Detail maps provide surface texturing (grass, rock, sand, etc.).\r\n *\r\n * @returns Maximum number of detail maps\r\n */\r\n get MAX_DETAIL_MAP_COUNT() {\r\n return ClipmapTerrainMaterial.MAX_DETAIL_MAP_COUNT;\r\n }\r\n /**\r\n * Gets the asset ID for the height map texture.\r\n * Generates a random UUID if not previously set.\r\n *\r\n * @returns Height map asset ID\r\n * @internal\r\n */\r\n get heightMapAssetId() {\r\n if (!this._heightMapAssetId) {\r\n this._heightMapAssetId = randomUUID();\r\n }\r\n return this._heightMapAssetId;\r\n }\r\n /** @internal */\r\n set heightMapAssetId(val: string) {\r\n this._heightMapAssetId = val;\r\n }\r\n /**\r\n * Gets the asset ID for the splat map texture.\r\n * Generates a random UUID if not previously set.\r\n *\r\n * @returns Splat map asset ID\r\n * @internal\r\n */\r\n get splatMapAssetId() {\r\n if (!this._splatMapAssetId) {\r\n this._splatMapAssetId = randomUUID();\r\n }\r\n return this._splatMapAssetId;\r\n }\r\n /** @internal */\r\n set splatMapAssetId(val: string) {\r\n this._splatMapAssetId = val;\r\n }\r\n /**\r\n * Gets the asset ID for grass configuration.\r\n * Generates a random UUID if not previously set.\r\n *\r\n * @returns Grass asset ID\r\n * @internal\r\n */\r\n get grassAssetId() {\r\n if (!this._grassAssetId) {\r\n this._grassAssetId = randomUUID();\r\n }\r\n return this._grassAssetId;\r\n }\r\n /** @internal */\r\n set grassAssetId(val: string) {\r\n this._grassAssetId = val;\r\n }\r\n /**\r\n * The current number of active detail maps.\r\n * Detail maps define different surface materials (grass, rock, etc.).\r\n *\r\n * @returns Number of active detail maps\r\n */\r\n get numDetailMaps() {\r\n return this.material?.numDetailMaps ?? 0;\r\n }\r\n set numDetailMaps(val) {\r\n if (this.material) {\r\n this.material.numDetailMaps = val;\r\n }\r\n }\r\n /** {@inheritDoc SceneNode.clone} */\r\n async clone(): Promise<this> {\r\n throw new Error('Cloning clipmap terrain not implemented');\r\n }\r\n /**\r\n * Sets the terrain size.\r\n * Triggers height map resize if dimensions change.\r\n *\r\n * @param sizeX - New width\r\n * @param sizeZ - New depth\r\n */\r\n setSize(sizeX: number, sizeZ: number) {\r\n if (sizeX !== this._sizeX || sizeZ !== this._sizeZ) {\r\n this._sizeX = sizeX;\r\n this._sizeZ = sizeZ;\r\n this.resizeHeightMap(this._sizeX, this._sizeZ);\r\n }\r\n }\r\n /**\r\n * Whether the detail layers are blended into a runtime virtual texture instead of per pixel.\r\n * Pages are blended once, as the camera needs them, so shading costs the same whatever the\r\n * number of layers. WebGPU only, ignored elsewhere; has no effect without detail layers.\r\n *\r\n * Code writing into the splat map or the height map directly must call\r\n * {@link ClipmapTerrain.invalidateRuntimeVirtualTexture} for the area it changed.\r\n */\r\n get runtimeVirtualTexture() {\r\n return !!this._virtualTexture;\r\n }\r\n set runtimeVirtualTexture(val: boolean) {\r\n if (!!val !== this.runtimeVirtualTexture) {\r\n this.setRuntimeVirtualTexture(val ? {} : null);\r\n }\r\n }\r\n /**\r\n * Enables the runtime virtual texture with the given options, or disables it with null.\r\n * See {@link ClipmapTerrain.runtimeVirtualTexture}.\r\n */\r\n setRuntimeVirtualTexture(options: Nullable<TerrainVirtualTextureOptions>) {\r\n if (options && getDevice().type !== 'webgpu') {\r\n warnUnsupported(\r\n 'Terrain runtime virtual texture (ClipmapTerrain.runtimeVirtualTexture)',\r\n 'WebGPU',\r\n 'the terrain is shaded directly every frame'\r\n );\r\n return;\r\n }\r\n if (options && !this.scene) {\r\n return;\r\n }\r\n if (this._virtualTexture && options) {\r\n this._virtualTexture.setOptions(options);\r\n return;\r\n }\r\n if (this._virtualTexture) {\r\n this.scene?.removeVirtualTextureClient(this._virtualTexture);\r\n this._virtualTexture.dispose();\r\n this._virtualTexture = null;\r\n if (this.material) {\r\n this.material.virtualTexture = null;\r\n }\r\n }\r\n if (options && this.material) {\r\n this._virtualTexture = new TerrainVirtualTexture(this, options);\r\n this.material.virtualTexture = this._virtualTexture.virtualTexture;\r\n this.scene!.addVirtualTextureClient(this._virtualTexture);\r\n }\r\n }\r\n /**\r\n * Refills the runtime virtual texture over a world XZ rectangle, or everywhere without\r\n * arguments, and recaptures the albedo global illumination reads there. Needed after writing\r\n * into the splat map or the height map directly (brushes); replacing textures or changing\r\n * layer parameters through the material is picked up automatically.\r\n */\r\n invalidateRuntimeVirtualTexture(x0?: number, z0?: number, x1?: number, z1?: number) {\r\n this._giAlbedo?.invalidate(x0, z0, x1, z1);\r\n if (!this._virtualTexture) {\r\n return;\r\n }\r\n if (x0 === undefined || z0 === undefined || x1 === undefined || z1 === undefined) {\r\n this._virtualTexture.invalidate();\r\n } else {\r\n this._virtualTexture.invalidateWorldRegion(x0, z0, x1, z1);\r\n }\r\n }\r\n /**\r\n * Top-down capture of the material albedo read by global illumination, created on first use.\r\n * WebGPU only.\r\n * @internal\r\n */\r\n get giAlbedo() {\r\n if (!this._giAlbedo) {\r\n this._giAlbedo = new TerrainGIAlbedo(this);\r\n }\r\n return this._giAlbedo;\r\n }\r\n /**\r\n * The virtual texture behind {@link ClipmapTerrain.runtimeVirtualTexture}, null when disabled.\r\n * For inspection: {@link VirtualTexture.stats}, {@link VirtualTexture.renderDebugTexture}.\r\n * It is recreated when the terrain aspect or the options change.\r\n */\r\n get runtimeVirtualTextureData(): Nullable<VirtualTexture> {\r\n return this._virtualTexture?.virtualTexture ?? null;\r\n }\r\n /** Wether the mesh node casts shadows */\r\n get castShadow() {\r\n return this._castShadow;\r\n }\r\n set castShadow(val) {\r\n this._castShadow = !!val;\r\n }\r\n /** The terrain width. */\r\n get sizeX() {\r\n return this._sizeX;\r\n }\r\n set sizeX(val) {\r\n if (val !== this._sizeX) {\r\n this._sizeX = val;\r\n this.resizeHeightMap(this._sizeX, this._sizeZ);\r\n }\r\n }\r\n /** The terrain depth. */\r\n get sizeZ() {\r\n return this._sizeZ;\r\n }\r\n set sizeZ(val) {\r\n if (val !== this._sizeZ) {\r\n this._sizeZ = val;\r\n this.resizeHeightMap(this._sizeX, this._sizeZ);\r\n }\r\n }\r\n /** The current height map texture. */\r\n get heightMap() {\r\n return this.material?.heightMap ?? null;\r\n }\r\n set heightMap(val) {\r\n if (this.material && val) {\r\n this.material.heightMap = val;\r\n this._heightData = null;\r\n this.updateRegion();\r\n this.updateHeightPyramid();\r\n this._heightVersion++;\r\n this.readBackHeightData();\r\n }\r\n }\r\n /**\r\n * Goes up whenever the heights change: a new height map, or edits to the\r\n * current one once {@link ClipmapTerrain.updateBoundingBox} is called after\r\n * them. Lets CPU-side users such as physics notice they are out of date.\r\n */\r\n get heightVersion() {\r\n return this._heightVersion;\r\n }\r\n /**\r\n * CPU copy of the heights, half floats row by row (height map texel values, before the terrain\r\n * scale and translation); null while unknown.\r\n *\r\n * @remarks\r\n * Lets CPU-side users such as physics and prop placement read heights without a GPU read back.\r\n * Known at once when loaded or set with {@link ClipmapTerrain.setHeights}; after other edits\r\n * it is null until a read back started by {@link ClipmapTerrain.updateBoundingBox} lands, which\r\n * {@link ClipmapTerrain.whenHeightDataReady} waits for.\r\n */\r\n get heightData(): Nullable<{\r\n readonly data: Uint16Array;\r\n readonly width: number;\r\n readonly height: number;\r\n }> {\r\n return this._heightData;\r\n }\r\n /**\r\n * Records the CPU copy of the heights just uploaded to the height map.\r\n * @internal\r\n */\r\n setHeightData(data: Uint16Array, width: number, height: number) {\r\n this._heightData = { data, width, height };\r\n this._heightVersion++;\r\n }\r\n /**\r\n * Resolves once {@link ClipmapTerrain.heightData} is known, reading the heights back from the\r\n * GPU if needed. Resolves to null when the height map format cannot be read back.\r\n */\r\n whenHeightDataReady(): Promise<\r\n Nullable<{ readonly data: Uint16Array; readonly width: number; readonly height: number }>\r\n > {\r\n if (this._heightData) {\r\n return Promise.resolve(this._heightData);\r\n }\r\n return this.readBackHeightData() ?? Promise.resolve(null);\r\n }\r\n /**\r\n * World height of the terrain surface at a world position, bilinearly interpolated, or null\r\n * outside the terrain or while {@link ClipmapTerrain.heightData} is unknown.\r\n */\r\n getHeightAt(x: number, z: number): Nullable<number> {\r\n const data = this._heightData;\r\n const region = this.worldRegion;\r\n if (!data || region.z <= region.x || region.w <= region.y) {\r\n return null;\r\n }\r\n const u = (x - region.x) / (region.z - region.x);\r\n const v = (z - region.y) / (region.w - region.y);\r\n if (u < 0 || u > 1 || v < 0 || v > 1) {\r\n return null;\r\n }\r\n return this.sampleHeightTexel(data, u, v) * this.scale.y + this.worldMatrix.m13;\r\n }\r\n /**\r\n * Unit surface normal of the terrain at a world position, from central differences one height\r\n * map texel apart, or null where {@link ClipmapTerrain.getHeightAt} is.\r\n */\r\n getNormalAt(x: number, z: number, out?: Vector3): Nullable<Vector3> {\r\n const data = this._heightData;\r\n const region = this.worldRegion;\r\n if (!data || region.z <= region.x || region.w <= region.y) {\r\n return null;\r\n }\r\n const rw = region.z - region.x;\r\n const rh = region.w - region.y;\r\n const u = (x - region.x) / rw;\r\n const v = (z - region.y) / rh;\r\n if (u < 0 || u > 1 || v < 0 || v > 1) {\r\n return null;\r\n }\r\n const du = 1 / data.width;\r\n const dv = 1 / data.height;\r\n const sy = this.scale.y;\r\n const dx = (this.sampleHeightTexel(data, u + du, v) - this.sampleHeightTexel(data, u - du, v)) * sy;\r\n const dz = (this.sampleHeightTexel(data, u, v + dv) - this.sampleHeightTexel(data, u, v - dv)) * sy;\r\n out = out ?? new Vector3();\r\n out.setXYZ(-dx / (2 * du * rw), 1, -dz / (2 * dv * rh));\r\n return out.inplaceNormalize();\r\n }\r\n private sampleHeightTexel(\r\n data: { data: Uint16Array; width: number; height: number },\r\n u: number,\r\n v: number\r\n ) {\r\n // Texel i holds the height at the centre of cell i, at u = (i + 0.5) / width\r\n const w = data.width;\r\n const h = data.height;\r\n const fx = Math.min(Math.max(u * w - 0.5, 0), w - 1);\r\n const fz = Math.min(Math.max(v * h - 0.5, 0), h - 1);\r\n const x0 = Math.floor(fx);\r\n const z0 = Math.floor(fz);\r\n const x1 = Math.min(x0 + 1, w - 1);\r\n const z1 = Math.min(z0 + 1, h - 1);\r\n const tx = fx - x0;\r\n const tz = fz - z0;\r\n const d = data.data;\r\n const h00 = half2float(d[z0 * w + x0]);\r\n const h10 = half2float(d[z0 * w + x1]);\r\n const h01 = half2float(d[z1 * w + x0]);\r\n const h11 = half2float(d[z1 * w + x1]);\r\n const a = h00 + (h10 - h00) * tx;\r\n const b = h01 + (h11 - h01) * tx;\r\n return a + (b - a) * tz;\r\n }\r\n /**\r\n * Reads the half float heights back from the GPU into {@link ClipmapTerrain.heightData}.\r\n * A read back overtaken by another height change is dropped.\r\n */\r\n private readBackHeightData() {\r\n const map = this.heightMap;\r\n if (!map || (map.format !== 'r16f' && map.format !== 'rgba16f')) {\r\n return null;\r\n }\r\n if (this._heightReadBack && this._heightReadBack.version === this._heightVersion) {\r\n return this._heightReadBack.promise;\r\n }\r\n const version = this._heightVersion;\r\n const w = map.width;\r\n const h = map.height;\r\n const channels = map.format === 'r16f' ? 1 : 4;\r\n const buffer = new Uint16Array(w * h * channels);\r\n const promise = map\r\n .readPixels(0, 0, w, h, 0, 0, buffer)\r\n .then(() => {\r\n if (version !== this._heightVersion || this.heightMap !== map) {\r\n return this._heightData;\r\n }\r\n let data = buffer;\r\n if (channels !== 1) {\r\n // The height is in the red channel\r\n data = new Uint16Array(w * h);\r\n for (let i = 0; i < data.length; i++) {\r\n data[i] = buffer[i * channels];\r\n }\r\n }\r\n // Same heights as on the GPU: the version stays, physics need not rebuild\r\n this._heightData = { data, width: w, height: h };\r\n return this._heightData;\r\n })\r\n .catch((err) => {\r\n console.error(`Terrain height read back failed: ${err}`);\r\n return null;\r\n })\r\n .finally(() => {\r\n if (this._heightReadBack?.promise === promise) {\r\n this._heightReadBack = null;\r\n }\r\n });\r\n this._heightReadBack = { version, promise };\r\n return promise;\r\n }\r\n /** The splat map texture */\r\n get splatMap() {\r\n return this.material?.getSplatMap() ?? null;\r\n }\r\n /** Material instance of the terrain */\r\n get material() {\r\n return this._material?.get() ?? null;\r\n }\r\n /** whether wireframe rendering is enabled */\r\n get wireframe() {\r\n return this._clipmap.wireframe;\r\n }\r\n set wireframe(val) {\r\n this._clipmap.wireframe = val;\r\n this._shadowClipmap.wireframe = val;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getPickTarget }\r\n */\r\n getPickTarget() {\r\n return this._pickTarget;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getMorphData}\r\n */\r\n getMorphData() {\r\n return null;\r\n }\r\n getSkinInfluenceData() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getMorphInfo}\r\n */\r\n getMorphInfo() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getQueueType}\r\n */\r\n getQueueType() {\r\n return this.material?.getQueueType() ?? QUEUE_OPAQUE;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.isUnlit}\r\n */\r\n isUnlit() {\r\n return this.material ? !this.material.supportLighting() : false;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.needSceneColor}\r\n */\r\n needSceneColor() {\r\n return this.material?.needSceneColor() ?? false;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.needSceneDepth}\r\n */\r\n needSceneDepth() {\r\n return this.material?.needSceneDepth() ?? false;\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getMaterial}\r\n */\r\n getMaterial() {\r\n return this._material.get();\r\n }\r\n /**\r\n * {@inheritDoc Drawable.getPrimitive}\r\n */\r\n getPrimitive() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.isClipmapTerrain}\r\n */\r\n isClipmapTerrain(): this is ClipmapTerrain {\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.computeBoundingVolume}\r\n */\r\n computeBoundingVolume() {\r\n return null;\r\n }\r\n /**\r\n * {@inheritDoc SceneNode.computeWorldBoundingVolume}\r\n */\r\n computeWorldBoundingVolume() {\r\n if (this.material) {\r\n const p = this.worldMatrix.transformPointAffine(Vector3.zero());\r\n const minHeight = this._minHeight * this.scale.y;\r\n const maxHeight = this._maxHeight * this.scale.y;\r\n return new BoundingBox(\r\n new Vector3(this.material.region.x, p.y + Math.min(minHeight, maxHeight), this.material.region.y),\r\n new Vector3(this.material.region.z, p.y + Math.max(minHeight, maxHeight), this.material.region.w)\r\n );\r\n } else {\r\n return null;\r\n }\r\n }\r\n /**\r\n * the actual world-space region covered by this terrain (After applying world transform).\r\n */\r\n get worldRegion(): Immutable<Vector4> {\r\n return this.material?.region ?? Vector4.zero();\r\n }\r\n /**\r\n * Calculates the local transformation matrix.\r\n * For terrains, this only includes translation.\r\n *\r\n * @param outMatrix - Output matrix to store the result\r\n */\r\n calculateLocalTransform(outMatrix: Matrix4x4) {\r\n outMatrix.translation(this._position);\r\n }\r\n /**\r\n * Calculates the world transformation matrix.\r\n * Terrains inherit only translation from parent nodes.\r\n *\r\n * @param outMatrix - Output matrix to store the result\r\n */\r\n calculateWorldTransform(outMatrix: Matrix4x4) {\r\n outMatrix.set(this.localMatrix);\r\n if (this.parent) {\r\n outMatrix.m03 += this.parent.worldMatrix.m03;\r\n outMatrix.m13 += this.parent.worldMatrix.m13;\r\n outMatrix.m23 += this.parent.worldMatrix.m23;\r\n }\r\n }\r\n /**\r\n * Updates the terrain's bounding box by analyzing the height map.\r\n * This is an asynchronous operation that reads back GPU data.\r\n *\r\n * @param tmpTexture - Optional temporary texture to reuse (optimization)\r\n *\r\n * @example\r\n * ```typescript\r\n * // Update bounding box after changing height map\r\n * terrain.heightMap = newHeightMap;\r\n * terrain.updateBoundingBox();\r\n * ```\r\n */\r\n updateBoundingBox() {\r\n // Called after the heights changed on the GPU: a CPU copy is stale now.\r\n this._heightData = null;\r\n this._heightVersion++;\r\n this.readBackHeightData();\r\n const tmp = this.updateHeightPyramid();\r\n if (!tmp) {\r\n return;\r\n }\r\n const data = new Float32Array(4);\r\n const serial = ++this._heightRangeSerial;\r\n tmp\r\n .readPixels(0, 0, 1, 1, 0, tmp.mipLevelCount - 1, data)\r\n .then(() => {\r\n // Loading sets the range synchronously right after a resize has started a read back of\r\n // the empty height map; that stale result must not land on top of it.\r\n if (serial !== this._heightRangeSerial) {\r\n return;\r\n }\r\n // The reduction stores (max, min) in (r, g)\r\n this._maxHeight = data[0];\r\n this._minHeight = data[1];\r\n this.invalidateWorldBoundingVolume(false);\r\n })\r\n .catch((_err) => {\r\n console.error('Read pixels failed');\r\n });\r\n }\r\n /**\r\n * Replaces every height of an r16f height map with heights from the CPU.\r\n *\r\n * Unlike writing into {@link ClipmapTerrain.heightMap} and calling\r\n * {@link ClipmapTerrain.updateBoundingBox}, the bounds are right at once and the heights stay\r\n * available as {@link ClipmapTerrain.heightData}, so physics colliders need no GPU read back.\r\n *\r\n * @param data - Half float heights, one per height map texel, row by row\r\n */\r\n setHeights(data: Uint16Array<ArrayBuffer>) {\r\n const heightMap = this.heightMap;\r\n if (!heightMap || heightMap.format !== 'r16f' || data.length !== heightMap.width * heightMap.height) {\r\n console.error('setHeights() needs one half float per texel of an r16f height map');\r\n return;\r\n }\r\n heightMap.update(data, 0, 0, heightMap.width, heightMap.height);\r\n this.updateHeightPyramid();\r\n this.setHeightRangeFromHalfData(data);\r\n this.setHeightData(data, heightMap.width, heightMap.height);\r\n this.invalidateRuntimeVirtualTexture();\r\n }\r\n /**\r\n * The min/max height pyramid of the height map: (max, min) in (r, g), mip 0 padded to a power\r\n * of two by repeating the last row and column, so texel j of mip m covers height map texels\r\n * [j * 2^m, (j + 1) * 2^m). Null until built.\r\n * @internal\r\n */\r\n get heightPyramid() {\r\n return this._tmpTexture.get() ?? null;\r\n }\r\n /**\r\n * Tile resolution of the clipmap, in grid cells\r\n * @internal\r\n */\r\n get clipmapTileResolution() {\r\n return this._clipmap.tileResolution;\r\n }\r\n /**\r\n * Rebuilds the min/max height pyramid from the current height map.\r\n * Called when the height map is replaced and by {@link ClipmapTerrain.updateBoundingBox}; code\r\n * that writes into the height map directly must call one of them afterwards.\r\n * @internal\r\n */\r\n updateHeightPyramid() {\r\n const heightMap = this.heightMap;\r\n if (!heightMap) {\r\n return null;\r\n }\r\n const device = getDevice();\r\n const width = nextPowerOf2(heightMap.width);\r\n const height = nextPowerOf2(heightMap.height);\r\n let tmp = this._tmpTexture.get();\r\n if (tmp && (tmp.width !== width || tmp.height !== height)) {\r\n this._tmpTexture.dispose();\r\n }\r\n if (!this._tmpTexture.get()) {\r\n tmp = getDevice().createTexture2D('rg32f', width, height)!;\r\n tmp.name = 'TerrainBoundingBoxTexture';\r\n this._tmpTexture.set(tmp);\r\n }\r\n const tmpFB = device.createFrameBuffer([tmp!], null);\r\n ClipmapTerrain._padBlitter.sizes.setXYZW(width, height, heightMap.width, heightMap.height);\r\n ClipmapTerrain._padBlitter.blit(heightMap, tmpFB, fetchSampler('clamp_nearest_nomip'));\r\n tmpFB.dispose();\r\n ClipmapTerrain._heightBoundingGenerator.render(tmp!);\r\n return tmp!;\r\n }\r\n /**\r\n * Sets the height range from height map data already on the CPU, e.g. when loading.\r\n *\r\n * {@link ClipmapTerrain.updateBoundingBox} reads the range back from the GPU, which lands a\r\n * few frames later; until then the bounds would stay flat and cull the terrain wrongly.\r\n *\r\n * @param data - Half float heights, one per texel\r\n * @param stride - Number of half floats per texel, the height being the first\r\n * @internal\r\n */\r\n setHeightRangeFromHalfData(data: Uint16Array, stride = 1) {\r\n let minHeight = Number.POSITIVE_INFINITY;\r\n let maxHeight = Number.NEGATIVE_INFINITY;\r\n for (let i = 0; i < data.length; i += stride) {\r\n const h = half2float(data[i]);\r\n if (h < minHeight) {\r\n minHeight = h;\r\n }\r\n if (h > maxHeight) {\r\n maxHeight = h;\r\n }\r\n }\r\n if (minHeight <= maxHeight) {\r\n this._heightRangeSerial++;\r\n this._minHeight = minHeight;\r\n this._maxHeight = maxHeight;\r\n this.invalidateWorldBoundingVolume(false);\r\n }\r\n }\r\n /** @internal */\r\n createHeightMapTexture(width: number, height: number) {\r\n return getDevice().createTexture2D('r16f', width, height)!;\r\n }\r\n /** @internal */\r\n protected _onTransformChanged(invalidateLocal: boolean) {\r\n super._onTransformChanged(invalidateLocal);\r\n this.updateRegion();\r\n }\r\n /** {@inheritDoc SceneNode.updatePerCamera} */\r\n updatePerCamera(camera: Camera, _elapsedInSeconds: number, _deltaInSeconds: number) {\r\n const mat = this._material.get();\r\n if (!mat) {\r\n return;\r\n }\r\n const bv = this.getWorldBoundingVolume()?.toAABB() ?? null;\r\n const originY = this.worldMatrix.m13;\r\n const calcAABB = (\r\n _userData: unknown,\r\n minX: number,\r\n maxX: number,\r\n minZ: number,\r\n maxZ: number,\r\n outAABB: AABB\r\n ) => {\r\n outAABB.minPoint.setXYZ(minX, bv ? bv.minPoint.y : originY - 9999, minZ);\r\n outAABB.maxPoint.setXYZ(maxX, bv ? bv.maxPoint.y : originY + 9999, maxZ);\r\n };\r\n // Passes rendered from this camera only need the tiles inside its frustum. Shadow passes\r\n // render from the light and need casters outside of it too, so they get an unculled set\r\n // built around the same camera (same levels, so the level data below serves both).\r\n this._renderData = this._clipmap.gather({\r\n camera: camera,\r\n minMaxWorldPos: mat.region,\r\n gridScale: this._gridScale,\r\n gridOriginX: this._gridOriginX,\r\n gridOriginZ: this._gridOriginZ,\r\n userData: this,\r\n frustumCulling: true,\r\n calcAABB\r\n });\r\n // Each shadow map camera (cascade, cube face) culls this set again in draw()\r\n this._shadowGatherContext = this.castShadow\r\n ? {\r\n camera: camera,\r\n minMaxWorldPos: mat.region,\r\n gridScale: this._gridScale,\r\n gridOriginX: this._gridOriginX,\r\n gridOriginZ: this._gridOriginZ,\r\n userData: this,\r\n frustumCulling: false,\r\n calcAABB\r\n }\r\n : null;\r\n this._shadowRenderData = this._shadowGatherContext\r\n ? this._shadowClipmap.gather(this._shadowGatherContext)\r\n : null;\r\n let maxMipLevel = 0;\r\n for (const renderData of [this._renderData, this._shadowRenderData]) {\r\n for (const info of renderData ?? []) {\r\n const buffer = info.primitive.getVertexBuffer('texCoord1')!;\r\n buffer.bufferSubData(0, info.mipLevels, 0, info.numInstances);\r\n if (info.maxMiplevel > maxMipLevel) {\r\n maxMipLevel = info.maxMiplevel;\r\n }\r\n }\r\n }\r\n const levelAABB = this._clipmap.calcLevelAABB(\r\n camera,\r\n mat.region,\r\n this._gridScale,\r\n this._gridOriginX,\r\n this._gridOriginZ\r\n );\r\n const cameraPos = camera.getWorldPosition();\r\n const tmpBuffer = ClipmapTerrain._tmpBuffer;\r\n\r\n for (let i = 0; i <= maxMipLevel; i++) {\r\n if (i === 0) {\r\n tmpBuffer[i * 8 + 0] = cameraPos.x;\r\n tmpBuffer[i * 8 + 1] = cameraPos.z;\r\n tmpBuffer[i * 8 + 2] = cameraPos.x;\r\n tmpBuffer[i * 8 + 3] = cameraPos.z;\r\n } else {\r\n const prevAABB = levelAABB[i - 1];\r\n tmpBuffer[i * 8 + 0] = prevAABB.minPoint.x;\r\n tmpBuffer[i * 8 + 1] = prevAABB.minPoint.z;\r\n tmpBuffer[i * 8 + 2] = prevAABB.maxPoint.x;\r\n tmpBuffer[i * 8 + 3] = prevAABB.maxPoint.z;\r\n }\r\n const currentAABB = levelAABB[i];\r\n tmpBuffer[i * 8 + 4] = 1 / (currentAABB.minPoint.x - tmpBuffer[i * 8 + 0]);\r\n tmpBuffer[i * 8 + 5] = 1 / (currentAABB.minPoint.z - tmpBuffer[i * 8 + 1]);\r\n tmpBuffer[i * 8 + 6] = 1 / (currentAABB.maxPoint.x - tmpBuffer[i * 8 + 2]);\r\n tmpBuffer[i * 8 + 7] = 1 / (currentAABB.maxPoint.z - tmpBuffer[i * 8 + 3]);\r\n }\r\n mat.setLevelData(tmpBuffer, 8 * (maxMipLevel + 1));\r\n // Grass placed on the GPU is generated around this camera, outside of any render pass\r\n this.grassRenderer.updatePerCamera(camera);\r\n\r\n this.scene?.queuePerCameraUpdateNode(this);\r\n }\r\n /**\r\n * Updates the terrain material region based on current position and scale.\r\n * Should be called after changing position, scale, or height map.\r\n */\r\n updateRegion() {\r\n if (this.material) {\r\n const x = Math.abs(this.scale.x);\r\n const z = Math.abs(this.scale.z);\r\n const px = this.position.x + (this.parent?.worldMatrix.m03 ?? 0);\r\n const pz = this.position.z + (this.parent?.worldMatrix.m23 ?? 0);\r\n const cellX = (x * this._sizeX) / this.material.heightMap.width;\r\n const cellZ = (z * this._sizeZ) / this.material.heightMap.height;\r\n this._gridScale = Math.max(cellX, cellZ);\r\n this._gridOriginX = px + cellX * 0.5;\r\n this._gridOriginZ = pz + cellZ * 0.5;\r\n this.material.update(new Vector4(px, pz, px + x * this._sizeX, pz + z * this._sizeZ), this.scale);\r\n this.grassRenderer.updateMaterial();\r\n }\r\n }\r\n /** {@inheritDoc Drawable.draw} */\r\n draw(ctx: DrawContext, renderQueue: Nullable<RenderQueue>) {\r\n const mat = this._material?.get();\r\n if (mat) {\r\n this.bind(ctx, renderQueue);\r\n // The shader places vertices at grid * gridScale - offset, then adds the world translation\r\n mat.setClipmapGridInfo(\r\n this._gridScale,\r\n this.worldMatrix.m03 - this._gridOriginX,\r\n this.worldMatrix.m23 - this._gridOriginZ\r\n );\r\n mat.apply(ctx);\r\n const isShadowPass = ctx.renderPass!.type === RENDER_PASS_TYPE_SHADOWMAP;\r\n let renderData = isShadowPass ? this._shadowRenderData : this._renderData;\r\n const cullCamera = renderQueue?.cullCamera;\r\n if (isShadowPass && renderData && cullCamera && this._shadowGatherContext) {\r\n this._shadowGatherContext.camera = cullCamera;\r\n renderData = this._shadowClipmap.cullInstances(renderData, this._shadowGatherContext);\r\n for (const info of renderData) {\r\n info.primitive.getVertexBuffer('texCoord1')!.bufferSubData(0, info.mipLevels, 0, info.numInstances);\r\n }\r\n }\r\n for (const info of renderData ?? []) {\r\n mat.draw(info.primitive, ctx, info.numInstances);\r\n }\r\n // In shadow map passes the grass renderer draws the blades that cast shadows only\r\n if (ctx.renderPass!.type !== RENDER_PASS_TYPE_OBJECT_COLOR) {\r\n this.grassRenderer.draw(ctx);\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private resizeHeightMap(sizeX: number, sizeZ: number) {\r\n if (this.material) {\r\n const oldHeightMap = this.material.heightMap;\r\n const device = getDevice();\r\n const maxTextureSize = device.getDeviceCaps().textureCaps.maxTextureSize;\r\n sizeX = Math.min(Math.max(sizeX, 1), maxTextureSize) >> 0;\r\n sizeZ = Math.min(Math.max(sizeZ, 1), maxTextureSize) >> 0;\r\n if (sizeX !== oldHeightMap.width || sizeZ !== oldHeightMap.height) {\r\n const newHeightMap = device.createTexture2D('r16f', sizeX, sizeZ)!;\r\n const fb = device.createFrameBuffer([newHeightMap], null);\r\n ClipmapTerrain._copyBlitter.blit(oldHeightMap, fb, fetchSampler('clamp_linear_nomip'));\r\n fb.dispose();\r\n this.heightMap = newHeightMap;\r\n this.updateBoundingBox();\r\n }\r\n }\r\n }\r\n /*\r\n private calcNormalHeightMap(): Texture2D {\r\n const device = getDevice();\r\n if (!ClipmapTerrain._normalHeightMapProgram) {\r\n ClipmapTerrain._normalHeightMapProgram = device.buildRenderProgram({\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 if (device.type === 'webgpu') {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n }\r\n });\r\n },\r\n fragment(pb) {\r\n this.heightMap = pb.tex2D().uniform(0);\r\n this.texelSize = pb.vec2().uniform(0);\r\n this.terrainScale = pb.vec3().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('calcNormal', [pb.vec2('texCoord')], function () {\r\n this.$l.t = pb.textureSample(\r\n this.heightMap,\r\n pb.sub(this.texCoord, pb.vec2(0, this.texelSize.y))\r\n ).r;\r\n this.$l.l = pb.textureSample(\r\n this.heightMap,\r\n pb.sub(this.texCoord, pb.vec2(this.texelSize.x, 0))\r\n ).r;\r\n this.$l.r = pb.textureSample(\r\n this.heightMap,\r\n pb.add(this.texCoord, pb.vec2(this.texelSize.x, 0))\r\n ).r;\r\n this.$l.b = pb.textureSample(\r\n this.heightMap,\r\n pb.add(this.texCoord, pb.vec2(0, this.texelSize.y))\r\n ).r;\r\n this.$l.tx = pb.vec3(this.terrainScale.x, pb.mul(pb.sub(this.r, this.l), this.terrainScale.y), 0);\r\n this.$l.tz = pb.vec3(0, pb.mul(pb.sub(this.b, this.t), this.terrainScale.y), this.terrainScale.z);\r\n this.$l.normal = pb.normalize(pb.cross(this.tz, this.tx));\r\n this.$return(this.normal);\r\n });\r\n pb.main(function () {\r\n this.$l.normal = this.calcNormal(this.$inputs.uv);\r\n this.$outputs.outColor = pb.vec4(pb.add(pb.mul(this.normal, 0.5), pb.vec3(0.5)), 1);\r\n });\r\n }\r\n });\r\n }\r\n }\r\n */\r\n /**\r\n * Disposes of all resources used by this terrain.\r\n * Should be called when the terrain is no longer needed.\r\n */\r\n protected onDispose() {\r\n super.onDispose();\r\n this.setRuntimeVirtualTexture(null);\r\n this._giAlbedo?.dispose();\r\n this._giAlbedo = null;\r\n this._clipmap?.dispose();\r\n this._shadowClipmap?.dispose();\r\n this._material?.dispose();\r\n this._grassRenderer?.dispose();\r\n this._tmpTexture.dispose();\r\n }\r\n}\r\n"],"names":["HeightMinMaxBlitter","CopyBlitter","filter","scope","type","srcTex","srcUV","srcLayer","sampleType","readTexel","xxxx","HeightPadBlitter","sizes","Vector4","setup","_type","pb","$builder","shaderKind","padSizes","vec4","uniform","setUniforms","bindGroup","_sourceTex","setValue","texel","min","floor","mul","xy","sub","zw","vec2","uv","div","add","HeightBoundingGenerator","RenderMipmap","renderPixel","leftTop","rightTop","leftBottom","rightBottom","$l","maxHeight","max","r","minHeight","g","ClipmapTerrain","applyMixins","GraphNode","mixinDrawable","_heightBoundingGenerator","_copyBlitter","_padBlitter","_tmpBuffer","Float32Array","MAX_TERRAIN_MIPMAP_LEVELS","_pickTarget","_clipmap","_shadowClipmap","_renderData","_shadowRenderData","_shadowGatherContext","_gridScale","_gridOriginZ","_material","_grassRenderer","_castShadow","_sizeX","_sizeZ","_heightMapAssetId","_splatMapAssetId","_grassAssetId","_minHeight","_maxHeight","_heightData","_heightReadBack","_heightVersion","_tmpTexture","_virtualTexture","_giAlbedo","scene","sizeX","sizeZ","clipMapTileSize","node","Clipmap","DRef","GrassRenderer","_gridOriginX","persistentId","_heightRangeSerial","ClipmapTerrainMaterial","createHeightMapTexture","updateRegion","updateHeightPyramid","queuePerCameraUpdateNode","grassRenderer","get","MAX_DETAIL_MAP_COUNT","heightMapAssetId","randomUUID","val","splatMapAssetId","grassAssetId","numDetailMaps","material","clone","Error","setSize","resizeHeightMap","runtimeVirtualTexture","setRuntimeVirtualTexture","options","getDevice","warnUnsupported","setOptions","removeVirtualTextureClient","dispose","virtualTexture","TerrainVirtualTexture","addVirtualTextureClient","invalidateRuntimeVirtualTexture","x0","z0","x1","z1","invalidate","undefined","invalidateWorldRegion","giAlbedo","TerrainGIAlbedo","runtimeVirtualTextureData","castShadow","heightMap","readBackHeightData","heightVersion","heightData","setHeightData","data","width","height","whenHeightDataReady","Promise","resolve","getHeightAt","x","z","region","worldRegion","w","y","u","v","sampleHeightTexel","scale","worldMatrix","m13","getNormalAt","out","rw","rh","du","dv","sy","dx","dz","Vector3","setXYZ","inplaceNormalize","h","fx","Math","fz","tx","tz","d","h00","half2float","h10","h01","h11","a","b","map","format","version","promise","channels","buffer","Uint16Array","readPixels","then","i","length","catch","err","console","error","finally","splatMap","getSplatMap","wireframe","getPickTarget","getMorphData","getSkinInfluenceData","getMorphInfo","getQueueType","QUEUE_OPAQUE","isUnlit","supportLighting","needSceneColor","needSceneDepth","getMaterial","getPrimitive","isClipmapTerrain","computeBoundingVolume","computeWorldBoundingVolume","p","transformPointAffine","zero","BoundingBox","calculateLocalTransform","outMatrix","translation","_position","calculateWorldTransform","set","localMatrix","parent","m03","m23","updateBoundingBox","tmp","serial","mipLevelCount","invalidateWorldBoundingVolume","_err","setHeights","update","setHeightRangeFromHalfData","heightPyramid","clipmapTileResolution","tileResolution","device","nextPowerOf2","createTexture2D","name","tmpFB","createFrameBuffer","setXYZW","blit","fetchSampler","render","stride","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","_onTransformChanged","invalidateLocal","updatePerCamera","camera","_elapsedInSeconds","_deltaInSeconds","mat","bv","getWorldBoundingVolume","toAABB","originY","calcAABB","_userData","minX","maxX","minZ","maxZ","outAABB","minPoint","maxPoint","gather","minMaxWorldPos","gridScale","gridOriginX","gridOriginZ","userData","frustumCulling","maxMipLevel","renderData","info","primitive","getVertexBuffer","bufferSubData","mipLevels","numInstances","maxMiplevel","levelAABB","calcLevelAABB","cameraPos","getWorldPosition","tmpBuffer","prevAABB","currentAABB","setLevelData","abs","px","position","pz","cellX","cellZ","updateMaterial","draw","ctx","renderQueue","bind","setClipmapGridInfo","apply","isShadowPass","renderPass","RENDER_PASS_TYPE_SHADOWMAP","cullCamera","cullInstances","RENDER_PASS_TYPE_OBJECT_COLOR","oldHeightMap","maxTextureSize","getDeviceCaps","textureCaps","newHeightMap","fb","onDispose"],"mappings":"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"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { Disposable, DRef, Vector4 } from '@zephyr3d/base';
|
|
2
|
+
import { getDevice } from '../../app/api.js';
|
|
3
|
+
import { fetchSampler } from '../../utility/misc.js';
|
|
4
|
+
import { terrainSplatMaskCount, blendTerrainAlbedo } from '../../material/shader/terrain_blend.js';
|
|
5
|
+
|
|
6
|
+
/** Texels along the longer side of the capture; GI only needs the low frequencies. */ const CAPTURE_SIZE = 1024;
|
|
7
|
+
/** Albedo of the default checker material far away, where it fades to its mean. */ const CHECKER_MEAN_ALBEDO = 0.7;
|
|
8
|
+
/**
|
|
9
|
+
* Top-down capture of a terrain's material albedo for global illumination, after the Lumen
|
|
10
|
+
* surface cache, which captures a landscape into a heightfield card seen from above
|
|
11
|
+
* (LumenSceneCardCapture.cpp) and reads it where heightfield rays hit.
|
|
12
|
+
*
|
|
13
|
+
* One rgba8 texture over the terrain region, 1024 texels along its longer side, with mips so
|
|
14
|
+
* coarse material voxels read an average. Each texel blends the detail layers by the splat map
|
|
15
|
+
* as the terrain material does ({@link blendTerrainAlbedo}), with the texel step as the uv
|
|
16
|
+
* gradient so the layers come from the mip of that footprint, as the runtime virtual texture
|
|
17
|
+
* fills its pages. Recaptured where the splat map is edited (through
|
|
18
|
+
* {@link ClipmapTerrain.invalidateRuntimeVirtualTexture}) or wholly when the layers change.
|
|
19
|
+
*
|
|
20
|
+
* WebGPU only.
|
|
21
|
+
* @internal
|
|
22
|
+
*/ class TerrainGIAlbedo extends Disposable {
|
|
23
|
+
_terrain;
|
|
24
|
+
_texture;
|
|
25
|
+
_program;
|
|
26
|
+
_bindGroup;
|
|
27
|
+
_programKey;
|
|
28
|
+
/** Terrain uv rectangle (u0, v0, u1, v1) waiting to be recaptured, or null */ _dirty;
|
|
29
|
+
_contentVersion;
|
|
30
|
+
_contentParams;
|
|
31
|
+
_params;
|
|
32
|
+
constructor(terrain){
|
|
33
|
+
super();
|
|
34
|
+
this._terrain = terrain;
|
|
35
|
+
this._texture = new DRef();
|
|
36
|
+
this._program = null;
|
|
37
|
+
this._bindGroup = null;
|
|
38
|
+
this._programKey = '';
|
|
39
|
+
this._dirty = [
|
|
40
|
+
0,
|
|
41
|
+
0,
|
|
42
|
+
1,
|
|
43
|
+
1
|
|
44
|
+
];
|
|
45
|
+
this._contentVersion = -1;
|
|
46
|
+
this._contentParams = new Float32Array(0);
|
|
47
|
+
this._params = new Vector4();
|
|
48
|
+
}
|
|
49
|
+
/** The capture, null before the first {@link TerrainGIAlbedo.update} */ get texture() {
|
|
50
|
+
return this._texture.get() ?? null;
|
|
51
|
+
}
|
|
52
|
+
/** Marks a world XZ rectangle, or the whole terrain, for recapture */ invalidate(x0, z0, x1, z1) {
|
|
53
|
+
let rect = [
|
|
54
|
+
0,
|
|
55
|
+
0,
|
|
56
|
+
1,
|
|
57
|
+
1
|
|
58
|
+
];
|
|
59
|
+
if (x0 !== undefined && z0 !== undefined && x1 !== undefined && z1 !== undefined) {
|
|
60
|
+
const region = this._terrain.worldRegion;
|
|
61
|
+
const sx = region.z - region.x;
|
|
62
|
+
const sz = region.w - region.y;
|
|
63
|
+
if (!(sx > 0 && sz > 0)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
rect = [
|
|
67
|
+
Math.max(0, (Math.min(x0, x1) - region.x) / sx),
|
|
68
|
+
Math.max(0, (Math.min(z0, z1) - region.y) / sz),
|
|
69
|
+
Math.min(1, (Math.max(x0, x1) - region.x) / sx),
|
|
70
|
+
Math.min(1, (Math.max(z0, z1) - region.y) / sz)
|
|
71
|
+
];
|
|
72
|
+
if (rect[2] <= rect[0] || rect[3] <= rect[1]) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const d = this._dirty;
|
|
77
|
+
this._dirty = d ? [
|
|
78
|
+
Math.min(d[0], rect[0]),
|
|
79
|
+
Math.min(d[1], rect[1]),
|
|
80
|
+
Math.max(d[2], rect[2]),
|
|
81
|
+
Math.max(d[3], rect[3])
|
|
82
|
+
] : rect;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Recaptures what changed since the last call.
|
|
86
|
+
* @returns The world XZ rectangle (x0, z0, x1, z1) recaptured, or null when nothing was
|
|
87
|
+
*/ update() {
|
|
88
|
+
const material = this._terrain.material;
|
|
89
|
+
if (!material) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
this.ensureTexture();
|
|
93
|
+
this.syncContent();
|
|
94
|
+
const dirty = this._dirty;
|
|
95
|
+
if (!dirty) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
this._dirty = null;
|
|
99
|
+
const texture = this._texture.get();
|
|
100
|
+
const numLayers = material.numDetailMaps;
|
|
101
|
+
const hexMask = numLayers > 0 ? material.hexTilingMask : 0;
|
|
102
|
+
const key = `${numLayers}:${hexMask}`;
|
|
103
|
+
if (!this._program || this._programKey !== key) {
|
|
104
|
+
this.releaseProgram();
|
|
105
|
+
this._program = createCaptureProgram(numLayers, hexMask);
|
|
106
|
+
this._bindGroup = getDevice().createBindGroup(this._program.bindGroupLayouts[0]);
|
|
107
|
+
this._programKey = key;
|
|
108
|
+
}
|
|
109
|
+
// Texel rectangle covering the dirty uv rectangle
|
|
110
|
+
const w = texture.width;
|
|
111
|
+
const h = texture.height;
|
|
112
|
+
const tx0 = Math.max(0, Math.floor(dirty[0] * w));
|
|
113
|
+
const ty0 = Math.max(0, Math.floor(dirty[1] * h));
|
|
114
|
+
const tx1 = Math.min(w, Math.ceil(dirty[2] * w));
|
|
115
|
+
const ty1 = Math.min(h, Math.ceil(dirty[3] * h));
|
|
116
|
+
if (tx1 <= tx0 || ty1 <= ty0) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const bindGroup = this._bindGroup;
|
|
120
|
+
bindGroup.setTextureView('dst', texture, 0, 0, 1);
|
|
121
|
+
this._params.setXYZW(w, h, tx0, ty0);
|
|
122
|
+
bindGroup.setValue('params', this._params);
|
|
123
|
+
if (numLayers > 0) {
|
|
124
|
+
const splatMap = material.getSplatMap();
|
|
125
|
+
bindGroup.setTexture('splatMap', splatMap, fetchSampler('clamp_linear'));
|
|
126
|
+
bindGroup.setTexture('detailAlbedoMap', material.detailMapArray, fetchSampler('repeat_linear'));
|
|
127
|
+
bindGroup.setValue('detailParams', material.detailMapParams.subarray(0, numLayers * 4));
|
|
128
|
+
if (hexMask) {
|
|
129
|
+
bindGroup.setValue('detailHexParams', material.detailHexParams.subarray(0, numLayers * 4));
|
|
130
|
+
}
|
|
131
|
+
bindGroup.setValue('splatSize', splatMap.width);
|
|
132
|
+
}
|
|
133
|
+
const device = getDevice();
|
|
134
|
+
device.setProgram(this._program);
|
|
135
|
+
device.setBindGroup(0, bindGroup);
|
|
136
|
+
device.compute(Math.ceil((tx1 - tx0) / 8), Math.ceil((ty1 - ty0) / 8), 1);
|
|
137
|
+
texture.generateMipmaps();
|
|
138
|
+
const region = this._terrain.worldRegion;
|
|
139
|
+
const sx = region.z - region.x;
|
|
140
|
+
const sz = region.w - region.y;
|
|
141
|
+
return [
|
|
142
|
+
region.x + tx0 / w * sx,
|
|
143
|
+
region.y + ty0 / h * sz,
|
|
144
|
+
region.x + tx1 / w * sx,
|
|
145
|
+
region.y + ty1 / h * sz
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
/** Sized to the region's aspect, 1024 texels along the longer side */ ensureTexture() {
|
|
149
|
+
const region = this._terrain.worldRegion;
|
|
150
|
+
const sx = Math.max(region.z - region.x, 1e-6);
|
|
151
|
+
const sz = Math.max(region.w - region.y, 1e-6);
|
|
152
|
+
const w = sx >= sz ? CAPTURE_SIZE : Math.max(1, Math.round(CAPTURE_SIZE * sx / sz));
|
|
153
|
+
const h = sz >= sx ? CAPTURE_SIZE : Math.max(1, Math.round(CAPTURE_SIZE * sz / sx));
|
|
154
|
+
const tex = this._texture.get();
|
|
155
|
+
if (!tex || tex.width !== w || tex.height !== h) {
|
|
156
|
+
const created = getDevice().createTexture2D('rgba8unorm', w, h);
|
|
157
|
+
created.name = '@TerrainGIAlbedo';
|
|
158
|
+
this._texture.set(created);
|
|
159
|
+
this._dirty = [
|
|
160
|
+
0,
|
|
161
|
+
0,
|
|
162
|
+
1,
|
|
163
|
+
1
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** A full recapture when the layers, their parameters or the textures changed */ syncContent() {
|
|
168
|
+
const material = this._terrain.material;
|
|
169
|
+
const numLayers = material.numDetailMaps;
|
|
170
|
+
const current = new Float32Array(numLayers * 8 + 2);
|
|
171
|
+
current.set(material.detailMapParams.subarray(0, numLayers * 4));
|
|
172
|
+
current.set(material.detailHexParams.subarray(0, numLayers * 4), numLayers * 4);
|
|
173
|
+
current[numLayers * 8] = numLayers;
|
|
174
|
+
current[numLayers * 8 + 1] = numLayers > 0 ? material.hexTilingMask : 0;
|
|
175
|
+
let changed = this._contentVersion !== material.contentVersion || current.length !== this._contentParams.length;
|
|
176
|
+
for(let i = 0; i < current.length && !changed; i++){
|
|
177
|
+
changed = current[i] !== this._contentParams[i];
|
|
178
|
+
}
|
|
179
|
+
if (changed) {
|
|
180
|
+
this._contentParams = current;
|
|
181
|
+
this._contentVersion = material.contentVersion;
|
|
182
|
+
this._dirty = [
|
|
183
|
+
0,
|
|
184
|
+
0,
|
|
185
|
+
1,
|
|
186
|
+
1
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
releaseProgram() {
|
|
191
|
+
this._bindGroup?.dispose();
|
|
192
|
+
this._bindGroup = null;
|
|
193
|
+
this._program?.dispose();
|
|
194
|
+
this._program = null;
|
|
195
|
+
}
|
|
196
|
+
onDispose() {
|
|
197
|
+
super.onDispose();
|
|
198
|
+
this._texture.dispose();
|
|
199
|
+
this.releaseProgram();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function createCaptureProgram(numLayers, hexMask) {
|
|
203
|
+
return getDevice().buildComputeProgram({
|
|
204
|
+
label: `TerrainGIAlbedo${numLayers}_${hexMask}`,
|
|
205
|
+
workgroupSize: [
|
|
206
|
+
8,
|
|
207
|
+
8,
|
|
208
|
+
1
|
|
209
|
+
],
|
|
210
|
+
compute (pb) {
|
|
211
|
+
this.dst = pb.texStorage2D.rgba8unorm().storage(0);
|
|
212
|
+
// (width, height, first texel x, first texel y)
|
|
213
|
+
this.params = pb.vec4().uniform(0);
|
|
214
|
+
if (numLayers > 0) {
|
|
215
|
+
this.splatMap = pb.tex2DArray().uniform(0);
|
|
216
|
+
this.detailAlbedoMap = pb.tex2DArray().uniform(0);
|
|
217
|
+
this.detailParams = pb.vec4[numLayers]().uniform(0);
|
|
218
|
+
if (hexMask) {
|
|
219
|
+
this.detailHexParams = pb.vec4[numLayers]().uniform(0);
|
|
220
|
+
}
|
|
221
|
+
this.splatSize = pb.float().uniform(0);
|
|
222
|
+
}
|
|
223
|
+
pb.main(function() {
|
|
224
|
+
this.$l.size = pb.vec2(this.params.xy);
|
|
225
|
+
this.$l.texel = pb.add(pb.vec2(this.$builtins.globalInvocationId.xy), this.params.zw);
|
|
226
|
+
this.$if(pb.all(pb.lessThan(this.texel, this.size)), function() {
|
|
227
|
+
if (numLayers === 0) {
|
|
228
|
+
pb.textureStore(this.dst, pb.uvec2(this.texel), pb.vec4(pb.vec3(CHECKER_MEAN_ALBEDO), 1));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.$l.uv = pb.div(pb.add(this.texel, pb.vec2(0.5)), this.size);
|
|
232
|
+
// As TerrainVirtualTexture fills a level: the texel step stands for the screen
|
|
233
|
+
// derivatives, so splat and detail layers come from the mip of the texel footprint
|
|
234
|
+
this.$l.splatLod = pb.max(pb.log2(pb.div(this.splatSize, pb.min(this.size.x, this.size.y))), 0);
|
|
235
|
+
const masks = [];
|
|
236
|
+
for(let i = 0; i < terrainSplatMaskCount(numLayers); i++){
|
|
237
|
+
this.$l[`mask${i}`] = pb.textureArraySampleLevel(this.splatMap, this.uv, i, this.splatLod);
|
|
238
|
+
masks.push(this[`mask${i}`]);
|
|
239
|
+
}
|
|
240
|
+
const grad = {
|
|
241
|
+
ddx: pb.vec2(pb.div(1, this.size.x), 0),
|
|
242
|
+
ddy: pb.vec2(0, pb.div(1, this.size.y))
|
|
243
|
+
};
|
|
244
|
+
const hex = hexMask ? {
|
|
245
|
+
mask: hexMask,
|
|
246
|
+
params: this.detailHexParams
|
|
247
|
+
} : null;
|
|
248
|
+
this.$l.albedo = blendTerrainAlbedo(this, numLayers, masks, this.uv, this.detailParams, (s, i, uv, ddx, ddy)=>pb.textureArraySampleGrad(s.detailAlbedoMap, uv, i, ddx, ddy), grad, hex);
|
|
249
|
+
pb.textureStore(this.dst, pb.uvec2(this.texel), pb.vec4(pb.clamp(this.albedo, pb.vec3(0), pb.vec3(1)), 1));
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export { TerrainGIAlbedo };
|
|
257
|
+
//# sourceMappingURL=terrain_gi_albedo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain_gi_albedo.js","sources":["../../../src/scene/terrain-cm/terrain_gi_albedo.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Disposable, DRef, Vector4 } from '@zephyr3d/base';\r\nimport type { BindGroup, GPUProgram, PBShaderExp, Texture2D } from '@zephyr3d/device';\r\nimport { getDevice } from '../../app/api';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { blendTerrainAlbedo, terrainSplatMaskCount } from '../../material/shader/terrain_blend';\r\nimport type { ClipmapTerrain } from './terrain-cm';\r\n\r\n/** Texels along the longer side of the capture; GI only needs the low frequencies. */\r\nconst CAPTURE_SIZE = 1024;\r\n/** Albedo of the default checker material far away, where it fades to its mean. */\r\nconst CHECKER_MEAN_ALBEDO = 0.7;\r\n\r\n/**\r\n * Top-down capture of a terrain's material albedo for global illumination, after the Lumen\r\n * surface cache, which captures a landscape into a heightfield card seen from above\r\n * (LumenSceneCardCapture.cpp) and reads it where heightfield rays hit.\r\n *\r\n * One rgba8 texture over the terrain region, 1024 texels along its longer side, with mips so\r\n * coarse material voxels read an average. Each texel blends the detail layers by the splat map\r\n * as the terrain material does ({@link blendTerrainAlbedo}), with the texel step as the uv\r\n * gradient so the layers come from the mip of that footprint, as the runtime virtual texture\r\n * fills its pages. Recaptured where the splat map is edited (through\r\n * {@link ClipmapTerrain.invalidateRuntimeVirtualTexture}) or wholly when the layers change.\r\n *\r\n * WebGPU only.\r\n * @internal\r\n */\r\nexport class TerrainGIAlbedo extends Disposable {\r\n private readonly _terrain: ClipmapTerrain;\r\n private readonly _texture: DRef<Texture2D>;\r\n private _program: Nullable<GPUProgram>;\r\n private _bindGroup: Nullable<BindGroup>;\r\n private _programKey: string;\r\n /** Terrain uv rectangle (u0, v0, u1, v1) waiting to be recaptured, or null */\r\n private _dirty: Nullable<[number, number, number, number]>;\r\n private _contentVersion: number;\r\n private _contentParams: Float32Array<ArrayBuffer>;\r\n private readonly _params: Vector4;\r\n constructor(terrain: ClipmapTerrain) {\r\n super();\r\n this._terrain = terrain;\r\n this._texture = new DRef();\r\n this._program = null;\r\n this._bindGroup = null;\r\n this._programKey = '';\r\n this._dirty = [0, 0, 1, 1];\r\n this._contentVersion = -1;\r\n this._contentParams = new Float32Array(0);\r\n this._params = new Vector4();\r\n }\r\n /** The capture, null before the first {@link TerrainGIAlbedo.update} */\r\n get texture() {\r\n return this._texture.get() ?? null;\r\n }\r\n /** Marks a world XZ rectangle, or the whole terrain, for recapture */\r\n invalidate(x0?: number, z0?: number, x1?: number, z1?: number) {\r\n let rect: [number, number, number, number] = [0, 0, 1, 1];\r\n if (x0 !== undefined && z0 !== undefined && x1 !== undefined && z1 !== undefined) {\r\n const region = this._terrain.worldRegion;\r\n const sx = region.z - region.x;\r\n const sz = region.w - region.y;\r\n if (!(sx > 0 && sz > 0)) {\r\n return;\r\n }\r\n rect = [\r\n Math.max(0, (Math.min(x0, x1) - region.x) / sx),\r\n Math.max(0, (Math.min(z0, z1) - region.y) / sz),\r\n Math.min(1, (Math.max(x0, x1) - region.x) / sx),\r\n Math.min(1, (Math.max(z0, z1) - region.y) / sz)\r\n ];\r\n if (rect[2] <= rect[0] || rect[3] <= rect[1]) {\r\n return;\r\n }\r\n }\r\n const d = this._dirty;\r\n this._dirty = d\r\n ? [Math.min(d[0], rect[0]), Math.min(d[1], rect[1]), Math.max(d[2], rect[2]), Math.max(d[3], rect[3])]\r\n : rect;\r\n }\r\n /**\r\n * Recaptures what changed since the last call.\r\n * @returns The world XZ rectangle (x0, z0, x1, z1) recaptured, or null when nothing was\r\n */\r\n update(): Nullable<[number, number, number, number]> {\r\n const material = this._terrain.material;\r\n if (!material) {\r\n return null;\r\n }\r\n this.ensureTexture();\r\n this.syncContent();\r\n const dirty = this._dirty;\r\n if (!dirty) {\r\n return null;\r\n }\r\n this._dirty = null;\r\n const texture = this._texture.get()!;\r\n const numLayers = material.numDetailMaps;\r\n const hexMask = numLayers > 0 ? material.hexTilingMask : 0;\r\n const key = `${numLayers}:${hexMask}`;\r\n if (!this._program || this._programKey !== key) {\r\n this.releaseProgram();\r\n this._program = createCaptureProgram(numLayers, hexMask);\r\n this._bindGroup = getDevice().createBindGroup(this._program.bindGroupLayouts[0]);\r\n this._programKey = key;\r\n }\r\n // Texel rectangle covering the dirty uv rectangle\r\n const w = texture.width;\r\n const h = texture.height;\r\n const tx0 = Math.max(0, Math.floor(dirty[0] * w));\r\n const ty0 = Math.max(0, Math.floor(dirty[1] * h));\r\n const tx1 = Math.min(w, Math.ceil(dirty[2] * w));\r\n const ty1 = Math.min(h, Math.ceil(dirty[3] * h));\r\n if (tx1 <= tx0 || ty1 <= ty0) {\r\n return null;\r\n }\r\n const bindGroup = this._bindGroup!;\r\n bindGroup.setTextureView('dst', texture, 0, 0, 1);\r\n this._params.setXYZW(w, h, tx0, ty0);\r\n bindGroup.setValue('params', this._params);\r\n if (numLayers > 0) {\r\n const splatMap = material.getSplatMap()!;\r\n bindGroup.setTexture('splatMap', splatMap, fetchSampler('clamp_linear'));\r\n bindGroup.setTexture('detailAlbedoMap', material.detailMapArray!, fetchSampler('repeat_linear'));\r\n bindGroup.setValue('detailParams', material.detailMapParams.subarray(0, numLayers * 4));\r\n if (hexMask) {\r\n bindGroup.setValue('detailHexParams', material.detailHexParams.subarray(0, numLayers * 4));\r\n }\r\n bindGroup.setValue('splatSize', splatMap.width);\r\n }\r\n const device = getDevice();\r\n device.setProgram(this._program);\r\n device.setBindGroup(0, bindGroup);\r\n device.compute(Math.ceil((tx1 - tx0) / 8), Math.ceil((ty1 - ty0) / 8), 1);\r\n texture.generateMipmaps();\r\n const region = this._terrain.worldRegion;\r\n const sx = region.z - region.x;\r\n const sz = region.w - region.y;\r\n return [\r\n region.x + (tx0 / w) * sx,\r\n region.y + (ty0 / h) * sz,\r\n region.x + (tx1 / w) * sx,\r\n region.y + (ty1 / h) * sz\r\n ];\r\n }\r\n /** Sized to the region's aspect, 1024 texels along the longer side */\r\n private ensureTexture() {\r\n const region = this._terrain.worldRegion;\r\n const sx = Math.max(region.z - region.x, 1e-6);\r\n const sz = Math.max(region.w - region.y, 1e-6);\r\n const w = sx >= sz ? CAPTURE_SIZE : Math.max(1, Math.round((CAPTURE_SIZE * sx) / sz));\r\n const h = sz >= sx ? CAPTURE_SIZE : Math.max(1, Math.round((CAPTURE_SIZE * sz) / sx));\r\n const tex = this._texture.get();\r\n if (!tex || tex.width !== w || tex.height !== h) {\r\n const created = getDevice().createTexture2D('rgba8unorm', w, h)!;\r\n created.name = '@TerrainGIAlbedo';\r\n this._texture.set(created);\r\n this._dirty = [0, 0, 1, 1];\r\n }\r\n }\r\n /** A full recapture when the layers, their parameters or the textures changed */\r\n private syncContent() {\r\n const material = this._terrain.material!;\r\n const numLayers = material.numDetailMaps;\r\n const current = new Float32Array(numLayers * 8 + 2);\r\n current.set(material.detailMapParams.subarray(0, numLayers * 4));\r\n current.set(material.detailHexParams.subarray(0, numLayers * 4), numLayers * 4);\r\n current[numLayers * 8] = numLayers;\r\n current[numLayers * 8 + 1] = numLayers > 0 ? material.hexTilingMask : 0;\r\n let changed =\r\n this._contentVersion !== material.contentVersion || current.length !== this._contentParams.length;\r\n for (let i = 0; i < current.length && !changed; i++) {\r\n changed = current[i] !== this._contentParams[i];\r\n }\r\n if (changed) {\r\n this._contentParams = current;\r\n this._contentVersion = material.contentVersion;\r\n this._dirty = [0, 0, 1, 1];\r\n }\r\n }\r\n private releaseProgram() {\r\n this._bindGroup?.dispose();\r\n this._bindGroup = null;\r\n this._program?.dispose();\r\n this._program = null;\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._texture.dispose();\r\n this.releaseProgram();\r\n }\r\n}\r\n\r\nfunction createCaptureProgram(numLayers: number, hexMask: number) {\r\n return getDevice().buildComputeProgram({\r\n label: `TerrainGIAlbedo${numLayers}_${hexMask}`,\r\n workgroupSize: [8, 8, 1],\r\n compute(pb) {\r\n this.dst = pb.texStorage2D.rgba8unorm().storage(0);\r\n // (width, height, first texel x, first texel y)\r\n this.params = pb.vec4().uniform(0);\r\n if (numLayers > 0) {\r\n this.splatMap = pb.tex2DArray().uniform(0);\r\n this.detailAlbedoMap = pb.tex2DArray().uniform(0);\r\n this.detailParams = pb.vec4[numLayers]().uniform(0);\r\n if (hexMask) {\r\n this.detailHexParams = pb.vec4[numLayers]().uniform(0);\r\n }\r\n this.splatSize = pb.float().uniform(0);\r\n }\r\n pb.main(function () {\r\n this.$l.size = pb.vec2(this.params.xy);\r\n this.$l.texel = pb.add(pb.vec2(this.$builtins.globalInvocationId.xy), this.params.zw);\r\n this.$if(pb.all(pb.lessThan(this.texel, this.size)), function () {\r\n if (numLayers === 0) {\r\n pb.textureStore(this.dst, pb.uvec2(this.texel), pb.vec4(pb.vec3(CHECKER_MEAN_ALBEDO), 1));\r\n return;\r\n }\r\n this.$l.uv = pb.div(pb.add(this.texel, pb.vec2(0.5)), this.size);\r\n // As TerrainVirtualTexture fills a level: the texel step stands for the screen\r\n // derivatives, so splat and detail layers come from the mip of the texel footprint\r\n this.$l.splatLod = pb.max(pb.log2(pb.div(this.splatSize, pb.min(this.size.x, this.size.y))), 0);\r\n const masks: PBShaderExp[] = [];\r\n for (let i = 0; i < terrainSplatMaskCount(numLayers); i++) {\r\n this.$l[`mask${i}`] = pb.textureArraySampleLevel(this.splatMap, this.uv, i, this.splatLod);\r\n masks.push(this[`mask${i}`]);\r\n }\r\n const grad = {\r\n ddx: pb.vec2(pb.div(1, this.size.x), 0),\r\n ddy: pb.vec2(0, pb.div(1, this.size.y))\r\n };\r\n const hex = hexMask ? { mask: hexMask, params: this.detailHexParams as PBShaderExp } : null;\r\n this.$l.albedo = blendTerrainAlbedo(\r\n this,\r\n numLayers,\r\n masks,\r\n this.uv,\r\n this.detailParams,\r\n (s, i, uv, ddx, ddy) => pb.textureArraySampleGrad(s.detailAlbedoMap, uv, i, ddx!, ddy!),\r\n grad,\r\n hex\r\n );\r\n pb.textureStore(\r\n this.dst,\r\n pb.uvec2(this.texel),\r\n pb.vec4(pb.clamp(this.albedo, pb.vec3(0), pb.vec3(1)), 1)\r\n );\r\n });\r\n });\r\n }\r\n })!;\r\n}\r\n"],"names":["CAPTURE_SIZE","CHECKER_MEAN_ALBEDO","TerrainGIAlbedo","Disposable","_terrain","_texture","_program","_bindGroup","_programKey","_contentVersion","_contentParams","_params","terrain","DRef","_dirty","Float32Array","Vector4","texture","get","invalidate","x0","z0","x1","z1","rect","undefined","region","worldRegion","sx","z","x","sz","w","y","Math","max","min","d","update","material","ensureTexture","syncContent","dirty","numLayers","numDetailMaps","hexMask","hexTilingMask","key","releaseProgram","createCaptureProgram","getDevice","createBindGroup","bindGroupLayouts","width","h","height","tx0","floor","ty0","tx1","ceil","ty1","bindGroup","setTextureView","setXYZW","setValue","splatMap","getSplatMap","setTexture","fetchSampler","detailMapArray","detailMapParams","subarray","detailHexParams","device","setProgram","setBindGroup","compute","generateMipmaps","round","tex","created","createTexture2D","name","set","current","changed","contentVersion","length","i","dispose","onDispose","buildComputeProgram","label","workgroupSize","pb","dst","texStorage2D","rgba8unorm","storage","params","vec4","uniform","tex2DArray","detailAlbedoMap","detailParams","splatSize","float","main","$l","size","vec2","xy","texel","add","$builtins","globalInvocationId","zw","$if","all","lessThan","textureStore","uvec2","vec3","uv","div","splatLod","log2","masks","terrainSplatMaskCount","textureArraySampleLevel","push","grad","ddx","ddy","hex","mask","albedo","blendTerrainAlbedo","s","textureArraySampleGrad","clamp"],"mappings":"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"}
|