@zephyr3d/scene 0.9.26 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -27
- package/dist/animation/animation_bank.js +634 -0
- package/dist/animation/animation_bank.js.map +1 -0
- package/dist/animation/animation_bank_gpu.js +256 -0
- package/dist/animation/animation_bank_gpu.js.map +1 -0
- package/dist/animation/animationset.js +146 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_component.js +406 -0
- package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
- package/dist/animation/cloth/gpu_cloth_system.js +332 -202
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/gpu_animation_driver.js +289 -0
- package/dist/animation/gpu_animation_driver.js.map +1 -0
- package/dist/animation/joint_dynamics/collision.js +112 -1
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +6 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +50 -12
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/skeleton.js +300 -56
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skin_palette_atlas.js +252 -0
- package/dist/animation/skin_palette_atlas.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +298 -38
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +2 -0
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +159 -21
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_solver.js +173 -0
- package/dist/animation/spring/spring_solver.js.map +1 -0
- package/dist/animation/spring/spring_system.js +249 -24
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +32 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/app.js +26 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +86 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/gamepad.js +191 -0
- package/dist/app/gamepad.js.map +1 -0
- package/dist/app/inputactions.js +271 -0
- package/dist/app/inputactions.js.map +1 -0
- package/dist/app/inputmgr.js +331 -22
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/loading.js +138 -0
- package/dist/app/loading.js.map +1 -0
- package/dist/app/pipelinecache.js +209 -0
- package/dist/app/pipelinecache.js.map +1 -0
- package/dist/app/runtimescript.js +25 -0
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/scriptingsystem.js +54 -0
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +7 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/asset_manifest.js +59 -0
- package/dist/asset/asset_manifest.js.map +1 -0
- package/dist/asset/asset_preload.js +258 -0
- package/dist/asset/asset_preload.js.map +1 -0
- package/dist/asset/assetmanager.js +117 -65
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/dist/asset/loaders/ktx2/basis_location.js +17 -0
- package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
- package/dist/asset/mesh_lod_builder.js +104 -0
- package/dist/asset/mesh_lod_builder.js.map +1 -0
- package/dist/asset/mesh_settings.js +111 -0
- package/dist/asset/mesh_settings.js.map +1 -0
- package/dist/asset/meshopt_decoder.js +18 -0
- package/dist/asset/meshopt_decoder.js.map +1 -0
- package/dist/asset/meshopt_simplifier.js +26 -0
- package/dist/asset/meshopt_simplifier.js.map +1 -0
- package/dist/asset/model.js +177 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/asset/texture_settings.js +231 -0
- package/dist/asset/texture_settings.js.map +1 -0
- package/dist/asset/zmsh_binary.js +131 -0
- package/dist/asset/zmsh_binary.js.map +1 -0
- package/dist/asset/zsdf_binary.js +111 -0
- package/dist/asset/zsdf_binary.js.map +1 -0
- package/dist/blitter/bilateralblur.js +1 -2
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/gaussianblur.js +1 -6
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +31 -10
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +178 -200
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/follow.js +342 -0
- package/dist/camera/follow.js.map +1 -0
- package/dist/camera/fps.js +9 -7
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +46 -19
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +30475 -19865
- package/dist/index.js +67 -12
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +3 -0
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/eye.js +1 -1
- package/dist/material/eye.js.map +1 -1
- package/dist/material/hair.js +2 -3
- package/dist/material/hair.js.map +1 -1
- package/dist/material/hairstrand.js +235 -235
- package/dist/material/hairstrand.js.map +1 -1
- package/dist/material/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +362 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +118 -45
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +223 -83
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +31 -206
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +1 -1
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrmr.js +3 -0
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +3 -0
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/sdf_debug.js +78 -0
- package/dist/material/sdf_debug.js.map +1 -0
- package/dist/material/shader/helper.js +733 -190
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +204 -43
- package/dist/material/shader/terrain_blend.js.map +1 -1
- package/dist/material/skin.js +331 -297
- package/dist/material/skin.js.map +1 -1
- package/dist/material/skinprofile.js +1058 -0
- package/dist/material/skinprofile.js.map +1 -0
- package/dist/material/sss.js +353 -0
- package/dist/material/sss.js.map +1 -0
- package/dist/material/sss_kernel.js +265 -0
- package/dist/material/sss_kernel.js.map +1 -0
- package/dist/material/sssprofile.js +879 -0
- package/dist/material/sssprofile.js.map +1 -0
- package/dist/material/subsurfaceprofile.js +4 -8
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/terrain-cm.js +464 -188
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js +3 -0
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js +2009 -201
- package/dist/material/water.js.map +1 -1
- package/dist/node_modules/meshoptimizer/LICENSE +21 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
- package/dist/physics/character.js +226 -0
- package/dist/physics/character.js.map +1 -0
- package/dist/physics/collider.js +209 -0
- package/dist/physics/collider.js.map +1 -0
- package/dist/physics/events.js +79 -0
- package/dist/physics/events.js.map +1 -0
- package/dist/physics/joint.js +272 -0
- package/dist/physics/joint.js.map +1 -0
- package/dist/physics/node_physics.js +234 -0
- package/dist/physics/node_physics.js.map +1 -0
- package/dist/physics/part.js +91 -0
- package/dist/physics/part.js.map +1 -0
- package/dist/physics/rigid_body.js +379 -0
- package/dist/physics/rigid_body.js.map +1 -0
- package/dist/physics/vehicle.js +335 -0
- package/dist/physics/vehicle.js.map +1 -0
- package/dist/physics/world.js +25 -0
- package/dist/physics/world.js.map +1 -0
- package/dist/posteffect/bloom.js +49 -14
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/motionblur.js +668 -63
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +12 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +48 -50
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +605 -355
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +91 -162
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -11
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +34 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +1 -0
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +40 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +328 -62
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +958 -224
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +26 -5
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/debug_views.js +37 -0
- package/dist/render/debug_views.js.map +1 -0
- package/dist/render/depthpass.js +5 -1
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +53 -6
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +53 -53
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +196 -113
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +8 -13
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +268 -136
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +113 -28
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/gi/probe_volume.js +1334 -0
- package/dist/render/gi/probe_volume.js.map +1 -0
- package/dist/render/gi/scene_gi.js +282 -0
- package/dist/render/gi/scene_gi.js.map +1 -0
- package/dist/render/gi/voxel_atlas.js +198 -0
- package/dist/render/gi/voxel_atlas.js.map +1 -0
- package/dist/render/gi/voxel_lighting.js +652 -0
- package/dist/render/gi/voxel_lighting.js.map +1 -0
- package/dist/render/gi/voxel_scene.js +642 -0
- package/dist/render/gi/voxel_scene.js.map +1 -0
- package/dist/render/gi/voxelize_pass.js +223 -0
- package/dist/render/gi/voxelize_pass.js.map +1 -0
- package/dist/render/globalbindgroup_allocator.js +3 -2
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/gpu_picking.js +9 -36
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +23 -9
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/lod.js +46 -0
- package/dist/render/lod.js.map +1 -0
- package/dist/render/oit.js +11 -11
- package/dist/render/oit.js.map +1 -1
- package/dist/render/primitive.js +301 -9
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/primitive_readback.js +209 -0
- package/dist/render/primitive_readback.js.map +1 -0
- package/dist/render/render_queue.js +198 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +14 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +15 -1
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/executor.js +136 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +585 -59
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +8 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +31 -2
- package/dist/render/rendergraph/scene_render_context.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +28 -5
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sdf/box_allocator.js +98 -0
- package/dist/render/sdf/box_allocator.js.map +1 -0
- package/dist/render/sdf/global_sdf.js +865 -0
- package/dist/render/sdf/global_sdf.js.map +1 -0
- package/dist/render/sdf/scene_sdf.js +562 -0
- package/dist/render/sdf/scene_sdf.js.map +1 -0
- package/dist/render/sdf/sdf_atlas.js +227 -0
- package/dist/render/sdf/sdf_atlas.js.map +1 -0
- package/dist/render/sdf/sdf_programs.js +42 -0
- package/dist/render/sdf/sdf_programs.js.map +1 -0
- package/dist/render/sdf/sdf_view.js +199 -0
- package/dist/render/sdf/sdf_view.js.map +1 -0
- package/dist/render/sdf/waterline.js +610 -0
- package/dist/render/sdf/waterline.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +142 -25
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/shore_wave_generator.js +1193 -0
- package/dist/render/shore_wave_generator.js.map +1 -0
- package/dist/render/sky.js +516 -86
- package/dist/render/sky.js.map +1 -1
- package/dist/render/transmission_thickness_pass.js +477 -0
- package/dist/render/transmission_thickness_pass.js.map +1 -0
- package/dist/render/underwater.js +524 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/virtualtexture/virtual_texture.js +1214 -0
- package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_common.js +472 -0
- package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
- package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
- package/dist/render/volumetric_cloud/debug_view.js +131 -0
- package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
- package/dist/render/volumetric_cloud/resources.js +380 -0
- package/dist/render/volumetric_cloud/resources.js.map +1 -0
- package/dist/render/volumetric_cloud/sky_cache.js +380 -0
- package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
- package/dist/render/water_caustics.js +1195 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/water_foam.js +627 -0
- package/dist/render/water_foam.js.map +1 -0
- package/dist/render/water_interaction.js +1795 -0
- package/dist/render/water_interaction.js.map +1 -0
- package/dist/render/weightedblended_oit.js +36 -36
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +9 -4
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +108 -12
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +28 -7
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/foliage.js +1020 -0
- package/dist/scene/foliage.js.map +1 -0
- package/dist/scene/foliage_buckets.js +147 -0
- package/dist/scene/foliage_buckets.js.map +1 -0
- package/dist/scene/foliage_mask.js +358 -0
- package/dist/scene/foliage_mask.js.map +1 -0
- package/dist/scene/hair.js +15 -4
- package/dist/scene/hair.js.map +1 -1
- package/dist/scene/light.js +179 -13
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +327 -45
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +9 -3
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +9 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +8 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/physics_settings.js +157 -0
- package/dist/scene/physics_settings.js.map +1 -0
- package/dist/scene/scene.js +190 -44
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +147 -6
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
- package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +881 -42
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grass_gpu.js +929 -0
- package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js +180 -9
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +465 -36
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
- package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
- package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
- package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
- package/dist/scene/update_queue.js +54 -0
- package/dist/scene/update_queue.js.map +1 -0
- package/dist/scene/water.js +997 -96
- package/dist/scene/water.js.map +1 -1
- package/dist/scene/water_surface_sampler.js +324 -0
- package/dist/scene/water_surface_sampler.js.map +1 -0
- package/dist/scene/wind.js +317 -0
- package/dist/scene/wind.js.map +1 -0
- package/dist/shaders/atmosphere.js +388 -166
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +100 -32
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/gi.js +365 -0
- package/dist/shaders/gi.js.map +1 -0
- package/dist/shaders/ltc_rect.js +202 -0
- package/dist/shaders/ltc_rect.js.map +1 -0
- package/dist/shaders/misc.js +1 -10
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +5 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/probes.js +309 -0
- package/dist/shaders/probes.js.map +1 -0
- package/dist/shaders/sdf.js +537 -0
- package/dist/shaders/sdf.js.map +1 -0
- package/dist/shaders/shadow.js +104 -70
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/skin_brdf.js +243 -0
- package/dist/shaders/skin_brdf.js.map +1 -0
- package/dist/shaders/ssr.js +6 -159
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js +38 -27
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +40 -87
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +42 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +110 -19
- package/dist/shadow/dom.js.map +1 -1
- package/dist/shadow/esm.js +3 -3
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -48
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -53
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +34 -9
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +3 -8
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +87 -49
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +93 -53
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +18 -72
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -3
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/shape.js +44 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/utility/buoyancy.js +287 -0
- package/dist/utility/buoyancy.js.map +1 -0
- package/dist/utility/physical.js +10 -1
- package/dist/utility/physical.js.map +1 -1
- package/dist/utility/pmrem.js +17 -43
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/sdf/bake.js +435 -0
- package/dist/utility/sdf/bake.js.map +1 -0
- package/dist/utility/sdf/bvh.js +576 -0
- package/dist/utility/sdf/bvh.js.map +1 -0
- package/dist/utility/serialization/manager.js +36 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +77 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +11 -4
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +140 -279
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth.js +25 -0
- package/dist/utility/serialization/scene/cloth.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +14 -6
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/foliage.js +821 -0
- package/dist/utility/serialization/scene/foliage.js.map +1 -0
- package/dist/utility/serialization/scene/hair.js +11 -4
- package/dist/utility/serialization/scene/hair.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +115 -7
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +388 -220
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +69 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +140 -5
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/node_physics.js +1318 -0
- package/dist/utility/serialization/scene/node_physics.js.map +1 -0
- package/dist/utility/serialization/scene/particle.js +11 -4
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/physics.js +120 -0
- package/dist/utility/serialization/scene/physics.js.map +1 -0
- package/dist/utility/serialization/scene/primitive.js +124 -10
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +1687 -51
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +11 -4
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +163 -33
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +11 -4
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +2473 -114
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +97 -109
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/foam.js +170 -0
- package/dist/utility/textures/foam.js.map +1 -0
- package/dist/utility/textures/ggxlut.js +17 -43
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +4 -4
- package/dist/utility/textures/ltcdata.js.map +1 -1
- package/dist/utility/textures/ltclut.js +16 -6
- package/dist/utility/textures/ltclut.js.map +1 -1
- package/dist/utility/unsupported.js +24 -0
- package/dist/utility/unsupported.js.map +1 -0
- package/dist/values.js +13 -1
- package/dist/values.js.map +1 -1
- package/package.json +25 -12
- package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/src/asset/meshoptimizer/LICENSE +21 -0
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
import { Vector4 } from '@zephyr3d/base';
|
|
2
|
+
import { getDevice } from '../../app/api.js';
|
|
3
|
+
import { fetchSampler } from '../../utility/misc.js';
|
|
4
|
+
import { declareGlobalSDFUniforms, declareDynamicSDFUniforms, sampleGlobalSDF } from '../../shaders/sdf.js';
|
|
5
|
+
import { buildSDFProgram } from './sdf_programs.js';
|
|
6
|
+
|
|
7
|
+
/** Seed coordinate meaning "no seed yet". */ const NO_SEED = -1e5;
|
|
8
|
+
const WORKGROUP = 8;
|
|
9
|
+
/** Gaussian smoothing of the shore coordinates, in cells: half width and sigma. */ const SMOOTH_RADIUS = 4;
|
|
10
|
+
const SMOOTH_SIGMA = 2;
|
|
11
|
+
/** Field value within which the bed model is used, and its coefficient bound. */ const SMOOTH_MODEL_REACH = 4;
|
|
12
|
+
const SMOOTH_MODEL_CLAMP = 1000;
|
|
13
|
+
/** Jump-flooded distance, in metres, over which the bed model hands over to it. */ const SMOOTH_BLEND_START = 1;
|
|
14
|
+
const SMOOTH_BLEND_END = 4;
|
|
15
|
+
/** Horizontal field gradient below which the bed counts as flat. */ const WATERLINE_MIN_SLOPE = 0.02;
|
|
16
|
+
/** Bound of the linear model coefficients, within half float range. */ const WATERLINE_MODEL_CLAMP = 10000;
|
|
17
|
+
/** Distance a terrain source reports off its height map: open water, well past the bed model's reach. */ const TERRAIN_OFF_MAP = 1e4;
|
|
18
|
+
/**
|
|
19
|
+
* The global scene field as a waterline source: static geometry and the
|
|
20
|
+
* terrain, without the dynamic instances.
|
|
21
|
+
* @internal
|
|
22
|
+
*/ class SDFWaterlineSource {
|
|
23
|
+
label = 'SDF';
|
|
24
|
+
_global;
|
|
25
|
+
constructor(global){
|
|
26
|
+
this._global = global;
|
|
27
|
+
}
|
|
28
|
+
get version() {
|
|
29
|
+
return this._global.staticVersion;
|
|
30
|
+
}
|
|
31
|
+
declareUniforms(scope) {
|
|
32
|
+
declareGlobalSDFUniforms(scope, 0, this._global.levels);
|
|
33
|
+
// Unsampled, declared for GlobalSDF.applyBindGroup
|
|
34
|
+
declareDynamicSDFUniforms(scope, 0);
|
|
35
|
+
}
|
|
36
|
+
applyBindGroup(bindGroup) {
|
|
37
|
+
this._global.applyBindGroup(bindGroup);
|
|
38
|
+
}
|
|
39
|
+
sampleDistance(scope, pos) {
|
|
40
|
+
return sampleGlobalSDF(scope, pos, this._global.levels);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A terrain's height map as a waterline source: the distance above the
|
|
45
|
+
* surface over its slope, exact on a plane, as the global field composites
|
|
46
|
+
* the terrain. Only the terrain, so nothing standing on a beach bends its
|
|
47
|
+
* shoreline. Off the height map, or with no terrain, everything is water.
|
|
48
|
+
* @internal
|
|
49
|
+
*/ class TerrainWaterlineSource {
|
|
50
|
+
label = 'Terrain';
|
|
51
|
+
_terrain;
|
|
52
|
+
_version;
|
|
53
|
+
_key;
|
|
54
|
+
_region;
|
|
55
|
+
/** (height scale, world y, 1 / width, 1 / height) */ _params;
|
|
56
|
+
_dummy;
|
|
57
|
+
constructor(){
|
|
58
|
+
this._terrain = null;
|
|
59
|
+
this._version = 0;
|
|
60
|
+
this._key = '';
|
|
61
|
+
this._region = new Vector4(0, 0, 0, 0);
|
|
62
|
+
this._params = new Vector4(0, 0, 1, 1);
|
|
63
|
+
this._dummy = null;
|
|
64
|
+
}
|
|
65
|
+
get terrain() {
|
|
66
|
+
return this._terrain;
|
|
67
|
+
}
|
|
68
|
+
get version() {
|
|
69
|
+
return this._version;
|
|
70
|
+
}
|
|
71
|
+
/** Sets the terrain and notices changes to it; call before the field updates. */ setTerrain(terrain) {
|
|
72
|
+
this._terrain = terrain;
|
|
73
|
+
const heightMap = terrain?.heightMap ?? null;
|
|
74
|
+
let key = '';
|
|
75
|
+
if (terrain && heightMap) {
|
|
76
|
+
const r = terrain.worldRegion;
|
|
77
|
+
this._region.setXYZW(r.x, r.y, r.z, r.w);
|
|
78
|
+
this._params.setXYZW(Math.abs(terrain.scale.y), terrain.worldMatrix.m13, 1 / heightMap.width, 1 / heightMap.height);
|
|
79
|
+
key = `${heightMap.uid}:${terrain.heightVersion}:${[
|
|
80
|
+
...this._region,
|
|
81
|
+
...this._params
|
|
82
|
+
].join(',')}`;
|
|
83
|
+
} else {
|
|
84
|
+
this._region.setXYZW(0, 0, 0, 0);
|
|
85
|
+
}
|
|
86
|
+
if (key !== this._key) {
|
|
87
|
+
this._key = key;
|
|
88
|
+
this._version++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
declareUniforms(scope) {
|
|
92
|
+
const pb = scope.$builder;
|
|
93
|
+
scope.wlHeightMap = pb.tex2D().uniform(0);
|
|
94
|
+
// (min x, min z, max x, max z); empty for no terrain
|
|
95
|
+
scope.wlTerrainRegion = pb.vec4().uniform(0);
|
|
96
|
+
scope.wlTerrainParams = pb.vec4().uniform(0);
|
|
97
|
+
}
|
|
98
|
+
applyBindGroup(bindGroup) {
|
|
99
|
+
const heightMap = this._terrain?.heightMap ?? null;
|
|
100
|
+
bindGroup.setTexture('wlHeightMap', heightMap ?? this.getDummy(), fetchSampler('clamp_linear_nomip'));
|
|
101
|
+
bindGroup.setValue('wlTerrainRegion', this._region);
|
|
102
|
+
bindGroup.setValue('wlTerrainParams', this._params);
|
|
103
|
+
}
|
|
104
|
+
sampleDistance(scope, pos) {
|
|
105
|
+
const pb = scope.$builder;
|
|
106
|
+
pb.func('wlTerrainHeight', [
|
|
107
|
+
pb.vec2('xz')
|
|
108
|
+
], function() {
|
|
109
|
+
this.$l.uv = pb.div(pb.sub(this.xz, this.wlTerrainRegion.xy), pb.sub(this.wlTerrainRegion.zw, this.wlTerrainRegion.xy));
|
|
110
|
+
this.$return(pb.add(pb.mul(pb.textureSampleLevel(this.wlHeightMap, this.uv, 0).r, this.wlTerrainParams.x), this.wlTerrainParams.y));
|
|
111
|
+
});
|
|
112
|
+
pb.func('wlTerrainDistance', [
|
|
113
|
+
pb.vec3('p')
|
|
114
|
+
], function() {
|
|
115
|
+
this.$if(pb.or(pb.any(pb.lessThanEqual(this.wlTerrainRegion.zw, this.wlTerrainRegion.xy)), pb.or(pb.any(pb.lessThan(this.p.xz, this.wlTerrainRegion.xy)), pb.any(pb.greaterThan(this.p.xz, this.wlTerrainRegion.zw)))), function() {
|
|
116
|
+
this.$return(pb.float(TERRAIN_OFF_MAP));
|
|
117
|
+
});
|
|
118
|
+
this.$l.h = this.wlTerrainHeight(this.p.xz);
|
|
119
|
+
// Central differences one height map texel apart, in world units
|
|
120
|
+
this.$l.cell = pb.mul(pb.sub(this.wlTerrainRegion.zw, this.wlTerrainRegion.xy), this.wlTerrainParams.zw);
|
|
121
|
+
this.$l.hx = pb.sub(this.wlTerrainHeight(pb.add(this.p.xz, pb.vec2(this.cell.x, 0))), this.wlTerrainHeight(pb.sub(this.p.xz, pb.vec2(this.cell.x, 0))));
|
|
122
|
+
this.$l.hz = pb.sub(this.wlTerrainHeight(pb.add(this.p.xz, pb.vec2(0, this.cell.y))), this.wlTerrainHeight(pb.sub(this.p.xz, pb.vec2(0, this.cell.y))));
|
|
123
|
+
this.$l.grad = pb.div(pb.vec2(this.hx, this.hz), pb.mul(this.cell, 2));
|
|
124
|
+
this.$return(pb.div(pb.sub(this.p.y, this.h), pb.sqrt(pb.add(1, pb.dot(this.grad, this.grad)))));
|
|
125
|
+
});
|
|
126
|
+
return scope.wlTerrainDistance(pos);
|
|
127
|
+
}
|
|
128
|
+
dispose() {
|
|
129
|
+
this._dummy?.dispose();
|
|
130
|
+
this._dummy = null;
|
|
131
|
+
}
|
|
132
|
+
/** @internal */ getDummy() {
|
|
133
|
+
if (!this._dummy) {
|
|
134
|
+
this._dummy = getDevice().createTexture2D('r16f', 1, 1, {
|
|
135
|
+
mipmapping: false
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return this._dummy;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Horizontal distance to the waterline around the camera: on square grids at
|
|
143
|
+
* the rest level of a body of water, the distance in world units from each
|
|
144
|
+
* cell to the nearest point where the ground pierces that level.
|
|
145
|
+
*
|
|
146
|
+
* Unlike the 3D distance to the nearest solid (the water depth over a gently
|
|
147
|
+
* shelving bed), this measures shoreline bands outwards from where the ground
|
|
148
|
+
* meets the water.
|
|
149
|
+
*
|
|
150
|
+
* Built on the GPU from a {@link WaterlineSource}: the global clipmap (static
|
|
151
|
+
* geometry and the terrain; dynamic instances, a boat or a car wading in, are
|
|
152
|
+
* not shores and would ring themselves with shore waves and foam) or the
|
|
153
|
+
* terrain alone. One or more levels, all centred on the camera, each twice the
|
|
154
|
+
* cell size of the one before. Per level:
|
|
155
|
+
*
|
|
156
|
+
* 1. Seed: a cell whose centre is inside the ground at the water level is its own nearest shore.
|
|
157
|
+
* 2. Jump flooding, log2(resolution) passes, carries the nearest seed across the grid.
|
|
158
|
+
* 3. Resolve, into an rgba16f texture:
|
|
159
|
+
* - x: distance to the nearest seed, the waterline at the rest level;
|
|
160
|
+
* - y, z: a linear model of the ground around the cell, A and B with the horizontal distance
|
|
161
|
+
* to the waterline at a height `level + dy` being `A + B * dy`;
|
|
162
|
+
* - w: the field value at the cell at the rest level, telling how far the linear model holds.
|
|
163
|
+
* 4. Smooth, into a layer of {@link WaterlineField.smoothTexture}.
|
|
164
|
+
*
|
|
165
|
+
* The linear model lets the waterline follow the waves (a surface raised by dy moves the edge
|
|
166
|
+
* dy / tan(a) inland on a slope of angle a). From the field value s and its gradient g at the rest
|
|
167
|
+
* level, the ground near the cell is the plane s + g.(p - p0) = 0, crossed at height dy
|
|
168
|
+
* (s + g.y * dy) / |g.xz| away horizontally: A = s / |g.xz|, B = g.y / |g.xz|. Exact for a planar
|
|
169
|
+
* bed; farther from the shore the jump-flooded distance is used.
|
|
170
|
+
*
|
|
171
|
+
* The jump-flooded distance is accurate to about half a cell. A level only sees
|
|
172
|
+
* the shores on its own grid, so near its edge the nearest one may lie off it.
|
|
173
|
+
* WebGPU only.
|
|
174
|
+
*
|
|
175
|
+
* @public
|
|
176
|
+
*/ class WaterlineField {
|
|
177
|
+
levels;
|
|
178
|
+
resolution;
|
|
179
|
+
cellSize;
|
|
180
|
+
maxRebuilds;
|
|
181
|
+
_source;
|
|
182
|
+
_level;
|
|
183
|
+
_requested;
|
|
184
|
+
_seedA;
|
|
185
|
+
_seedB;
|
|
186
|
+
/** Seeds in the water, flooded for the distance inland from it; and the pass between. */ _wetA;
|
|
187
|
+
_wetB;
|
|
188
|
+
/** (field at the rest level, field half a cell above) per cell. */ _probe;
|
|
189
|
+
_result;
|
|
190
|
+
/** Smoothed shore coordinates, a layer per level, see {@link WaterlineField.smoothTexture}. */ _smooth;
|
|
191
|
+
_smoothTemp;
|
|
192
|
+
_smoothHProgram;
|
|
193
|
+
_smoothVProgram;
|
|
194
|
+
_seedProgram;
|
|
195
|
+
_jfaProgram;
|
|
196
|
+
_resolveProgram;
|
|
197
|
+
_bindGroups;
|
|
198
|
+
/** Per level: (origin x, origin z, cell size, resolution) as last built; 0 cells before it is. */ _regions;
|
|
199
|
+
/** Per level: source version, origin x, origin z and water level it was last built at. */ _builtAt;
|
|
200
|
+
constructor(source, options){
|
|
201
|
+
this._source = source;
|
|
202
|
+
this.levels = Math.max(1, Math.min(8, Math.floor(options?.levels ?? 1)));
|
|
203
|
+
this.resolution = Math.max(16, 2 ** Math.round(Math.log2(options?.resolution ?? 256)));
|
|
204
|
+
this.cellSize = Math.max(1e-3, options?.cellSize ?? 0.5);
|
|
205
|
+
this.maxRebuilds = Math.max(1, Math.floor(options?.maxRebuilds ?? this.levels));
|
|
206
|
+
this._level = null;
|
|
207
|
+
this._requested = false;
|
|
208
|
+
this._seedA = null;
|
|
209
|
+
this._seedB = null;
|
|
210
|
+
this._wetA = null;
|
|
211
|
+
this._wetB = null;
|
|
212
|
+
this._probe = null;
|
|
213
|
+
this._result = null;
|
|
214
|
+
this._smooth = null;
|
|
215
|
+
this._smoothTemp = null;
|
|
216
|
+
this._smoothHProgram = null;
|
|
217
|
+
this._smoothVProgram = null;
|
|
218
|
+
this._seedProgram = null;
|
|
219
|
+
this._jfaProgram = null;
|
|
220
|
+
this._resolveProgram = null;
|
|
221
|
+
this._bindGroups = [];
|
|
222
|
+
this._regions = Array.from({
|
|
223
|
+
length: this.levels
|
|
224
|
+
}, ()=>new Vector4(0, 0, 0, 0));
|
|
225
|
+
this._builtAt = Array.from({
|
|
226
|
+
length: this.levels
|
|
227
|
+
}, ()=>[
|
|
228
|
+
NaN,
|
|
229
|
+
NaN,
|
|
230
|
+
NaN,
|
|
231
|
+
NaN
|
|
232
|
+
]);
|
|
233
|
+
}
|
|
234
|
+
/** Grids built so far, a level each, for diagnosis. */ get rebuilds() {
|
|
235
|
+
return this._rebuilds;
|
|
236
|
+
}
|
|
237
|
+
_rebuilds = 0;
|
|
238
|
+
/** What the field is built from. */ get source() {
|
|
239
|
+
return this._source;
|
|
240
|
+
}
|
|
241
|
+
/** World Y the field is built at, or null before anything asked for it. */ get level() {
|
|
242
|
+
return this._level;
|
|
243
|
+
}
|
|
244
|
+
/** True once the finest level has been built. */ get ready() {
|
|
245
|
+
return this._regions[0].w > 0;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Smooth shore coordinates per cell, an rgba16f array with a layer per
|
|
249
|
+
* level, for effects that build geometry on them (see ShoreWaveGenerator):
|
|
250
|
+
* (signed distance to the waterline, negative inland; B of the bed model;
|
|
251
|
+
* height of the bed over the rest level; 0). The first two are
|
|
252
|
+
* Gaussian-filtered over two cells; the bed height is the cell's own, so it
|
|
253
|
+
* matches the ground. Null before the finest level is built.
|
|
254
|
+
*/ get smoothTexture() {
|
|
255
|
+
return this.ready ? this._smooth : null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* (rest-level distance, model A, model B, field at the rest level) per cell
|
|
259
|
+
* of the level built last, rgba16f: for a field of a single level, that level.
|
|
260
|
+
*/ get texture() {
|
|
261
|
+
return this._result;
|
|
262
|
+
}
|
|
263
|
+
/** (origin x, origin z, cell size, resolution) of the finest level, for sampling. */ get region() {
|
|
264
|
+
return this._regions[0];
|
|
265
|
+
}
|
|
266
|
+
/** (origin x, origin z, cell size, resolution) per level; 0 cells for a level not built yet. */ get regions() {
|
|
267
|
+
return this._regions;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Asks for the field at a water level this frame. Without a request in a
|
|
271
|
+
* frame it is not rebuilt; with several, the last one wins.
|
|
272
|
+
*/ request(level) {
|
|
273
|
+
this._level = level;
|
|
274
|
+
this._requested = true;
|
|
275
|
+
}
|
|
276
|
+
/** Rebuilds the levels around the camera that moved or went stale, when requested. */ update(cameraPos) {
|
|
277
|
+
if (!this._requested || this._level === null) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
this._requested = false;
|
|
281
|
+
this.ensureResources();
|
|
282
|
+
const version = this._source.version;
|
|
283
|
+
let budget = this.maxRebuilds;
|
|
284
|
+
// Finest first: it is the one the camera moves out of soonest and the one
|
|
285
|
+
// seen up close; a coarser level waiting a frame keeps its old grid, which
|
|
286
|
+
// its region still describes
|
|
287
|
+
for(let i = 0; i < this.levels && budget > 0; i++){
|
|
288
|
+
const h = this.cellSize * 2 ** i;
|
|
289
|
+
const n = this.resolution;
|
|
290
|
+
// Snapped to cells, so the grid does not swim as the camera moves
|
|
291
|
+
const ox = (Math.floor(cameraPos.x / h) - n / 2) * h;
|
|
292
|
+
const oz = (Math.floor(cameraPos.z / h) - n / 2) * h;
|
|
293
|
+
const at = this._builtAt[i];
|
|
294
|
+
if (this._regions[i].w > 0 && at[0] === version && at[1] === ox && at[2] === oz && at[3] === this._level) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
at[0] = version;
|
|
298
|
+
at[1] = ox;
|
|
299
|
+
at[2] = oz;
|
|
300
|
+
at[3] = this._level;
|
|
301
|
+
this.buildLevel(i, ox, oz, h);
|
|
302
|
+
this._regions[i].setXYZW(ox, oz, h, n);
|
|
303
|
+
this._rebuilds++;
|
|
304
|
+
budget--;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
dispose() {
|
|
308
|
+
this._seedA?.dispose();
|
|
309
|
+
this._seedB?.dispose();
|
|
310
|
+
this._wetA?.dispose();
|
|
311
|
+
this._wetB?.dispose();
|
|
312
|
+
this._probe?.dispose();
|
|
313
|
+
this._result?.dispose();
|
|
314
|
+
this._smooth?.dispose();
|
|
315
|
+
this._smoothTemp?.dispose();
|
|
316
|
+
this._seedA = this._seedB = this._wetA = this._wetB = null;
|
|
317
|
+
this._probe = this._result = this._smoothTemp = null;
|
|
318
|
+
this._smooth = null;
|
|
319
|
+
for (const bgs of this._bindGroups){
|
|
320
|
+
bgs.seed.dispose();
|
|
321
|
+
bgs.resolve.dispose();
|
|
322
|
+
for (const bg of [
|
|
323
|
+
...bgs.jfa,
|
|
324
|
+
...bgs.wetJfa,
|
|
325
|
+
...bgs.smooth
|
|
326
|
+
]){
|
|
327
|
+
bg.dispose();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
this._bindGroups = [];
|
|
331
|
+
for (const r of this._regions){
|
|
332
|
+
r.setXYZW(0, 0, 0, 0);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/** Builds one level into its layer of the smoothed array. @internal */ buildLevel(index, ox, oz, h) {
|
|
336
|
+
const device = getDevice();
|
|
337
|
+
const n = this.resolution;
|
|
338
|
+
const groups = n / WORKGROUP;
|
|
339
|
+
const bgs = this._bindGroups[index];
|
|
340
|
+
// Seed
|
|
341
|
+
const seedBG = bgs.seed;
|
|
342
|
+
seedBG.setValue('grid', new Vector4(ox, oz, h, this._level));
|
|
343
|
+
seedBG.setTexture('seedOut', this._seedA);
|
|
344
|
+
seedBG.setTexture('wetOut', this._wetA);
|
|
345
|
+
seedBG.setTexture('probeOut', this._probe);
|
|
346
|
+
this._source.applyBindGroup(seedBG);
|
|
347
|
+
device.setProgram(this._seedProgram);
|
|
348
|
+
device.setBindGroup(0, seedBG);
|
|
349
|
+
device.compute(groups, groups, 1);
|
|
350
|
+
// Jump flooding, halving the step down to one cell, from the shore and from the water side
|
|
351
|
+
const flood = (a, b, bindGroups)=>{
|
|
352
|
+
let src = a;
|
|
353
|
+
let dst = b;
|
|
354
|
+
let pass = 0;
|
|
355
|
+
for(let step = n / 2; step >= 1; step >>= 1, pass++){
|
|
356
|
+
const bg = bindGroups[pass];
|
|
357
|
+
bg.setValue('step', new Vector4(step, n, 0, 0));
|
|
358
|
+
bg.setTexture('seedIn', src, fetchSampler('clamp_nearest_nomip'));
|
|
359
|
+
bg.setTexture('seedOut', dst);
|
|
360
|
+
device.setProgram(this._jfaProgram);
|
|
361
|
+
device.setBindGroup(0, bg);
|
|
362
|
+
device.compute(groups, groups, 1);
|
|
363
|
+
const t = src;
|
|
364
|
+
src = dst;
|
|
365
|
+
dst = t;
|
|
366
|
+
}
|
|
367
|
+
return src;
|
|
368
|
+
};
|
|
369
|
+
const seeds = flood(this._seedA, this._seedB, bgs.jfa);
|
|
370
|
+
const wet = flood(this._wetA, this._wetB, bgs.wetJfa);
|
|
371
|
+
// Resolve
|
|
372
|
+
const rbg = bgs.resolve;
|
|
373
|
+
rbg.setValue('grid', new Vector4(ox, oz, h, n));
|
|
374
|
+
rbg.setTexture('seedIn', seeds, fetchSampler('clamp_nearest_nomip'));
|
|
375
|
+
rbg.setTexture('probeIn', this._probe, fetchSampler('clamp_nearest_nomip'));
|
|
376
|
+
rbg.setTexture('result', this._result);
|
|
377
|
+
device.setProgram(this._resolveProgram);
|
|
378
|
+
device.setBindGroup(0, rbg);
|
|
379
|
+
device.compute(groups, groups, 1);
|
|
380
|
+
// Smooth, separably: the first pass also turns the result into the signed distance
|
|
381
|
+
for(let pass = 0; pass < 2; pass++){
|
|
382
|
+
const bg = bgs.smooth[pass];
|
|
383
|
+
bg.setValue('smoothPass', new Vector4(pass, n, h, index));
|
|
384
|
+
bg.setTexture('wetIn', wet, fetchSampler('clamp_nearest_nomip'));
|
|
385
|
+
bg.setTexture('src', pass === 0 ? this._result : this._smoothTemp, fetchSampler('clamp_nearest_nomip'));
|
|
386
|
+
bg.setTexture('dst', pass === 0 ? this._smoothTemp : this._smooth);
|
|
387
|
+
device.setProgram(pass === 0 ? this._smoothHProgram : this._smoothVProgram);
|
|
388
|
+
device.setBindGroup(0, bg);
|
|
389
|
+
device.compute(groups, groups, 1);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/** @internal */ ensureResources() {
|
|
393
|
+
if (this._seedProgram) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const device = getDevice();
|
|
397
|
+
const n = this.resolution;
|
|
398
|
+
const tex = (format)=>device.createTexture2D(format, n, n, {
|
|
399
|
+
mipmapping: false,
|
|
400
|
+
writable: true
|
|
401
|
+
});
|
|
402
|
+
this._seedA = tex('rg32f');
|
|
403
|
+
this._seedB = tex('rg32f');
|
|
404
|
+
this._wetA = tex('rg32f');
|
|
405
|
+
this._wetB = tex('rg32f');
|
|
406
|
+
this._probe = tex('rg32f');
|
|
407
|
+
this._result = tex('rgba16f');
|
|
408
|
+
this._result.name = `@Waterline${this._source.label}`;
|
|
409
|
+
this._smoothTemp = tex('rgba16f');
|
|
410
|
+
this._smooth = device.createTexture2DArray('rgba16f', n, n, this.levels, {
|
|
411
|
+
mipmapping: false,
|
|
412
|
+
writable: true
|
|
413
|
+
});
|
|
414
|
+
this._smooth.name = `@Waterline${this._source.label}Smooth`;
|
|
415
|
+
const source = this._source;
|
|
416
|
+
this._seedProgram = buildSDFProgram({
|
|
417
|
+
label: `WaterlineSeed${source.label}`,
|
|
418
|
+
workgroupSize: [
|
|
419
|
+
WORKGROUP,
|
|
420
|
+
WORKGROUP,
|
|
421
|
+
1
|
|
422
|
+
],
|
|
423
|
+
compute (pb) {
|
|
424
|
+
// (origin x, origin z, cell size, water level)
|
|
425
|
+
this.grid = pb.vec4().uniform(0);
|
|
426
|
+
this.seedOut = pb.texStorage2D.rg32float().storage(0);
|
|
427
|
+
this.wetOut = pb.texStorage2D.rg32float().storage(0);
|
|
428
|
+
this.probeOut = pb.texStorage2D.rg32float().storage(0);
|
|
429
|
+
source.declareUniforms(this);
|
|
430
|
+
pb.main(function() {
|
|
431
|
+
this.$l.id = this.$builtins.globalInvocationId.xy;
|
|
432
|
+
this.$l.xz = pb.add(this.grid.xy, pb.mul(pb.add(pb.vec2(this.id), pb.vec2(0.5)), this.grid.z));
|
|
433
|
+
this.$l.d = source.sampleDistance(this, pb.vec3(this.xz.x, this.grid.w, this.xz.y));
|
|
434
|
+
// Half a cell up, for the vertical slope of the field
|
|
435
|
+
this.$l.dUp = source.sampleDistance(this, pb.vec3(this.xz.x, pb.add(this.grid.w, pb.mul(this.grid.z, 0.5)), this.xz.y));
|
|
436
|
+
pb.textureStore(this.probeOut, this.id, pb.vec4(this.d, this.dUp, 0, 0));
|
|
437
|
+
pb.textureStore(this.seedOut, this.id, this.$choice(pb.lessThan(this.d, 0), pb.vec4(pb.vec2(this.id), 0, 0), pb.vec4(NO_SEED, NO_SEED, 0, 0)));
|
|
438
|
+
pb.textureStore(this.wetOut, this.id, this.$choice(pb.lessThan(this.d, 0), pb.vec4(NO_SEED, NO_SEED, 0, 0), pb.vec4(pb.vec2(this.id), 0, 0)));
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
this._jfaProgram = buildSDFProgram({
|
|
443
|
+
label: 'WaterlineJFA',
|
|
444
|
+
workgroupSize: [
|
|
445
|
+
WORKGROUP,
|
|
446
|
+
WORKGROUP,
|
|
447
|
+
1
|
|
448
|
+
],
|
|
449
|
+
compute (pb) {
|
|
450
|
+
// (step, resolution, 0, 0)
|
|
451
|
+
this.step = pb.vec4().uniform(0);
|
|
452
|
+
this.seedIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
|
|
453
|
+
this.seedOut = pb.texStorage2D.rg32float().storage(0);
|
|
454
|
+
pb.main(function() {
|
|
455
|
+
this.$l.id = pb.ivec2(this.$builtins.globalInvocationId.xy);
|
|
456
|
+
this.$l.n = pb.int(this.step.y);
|
|
457
|
+
this.$l.s = pb.int(this.step.x);
|
|
458
|
+
this.$l.p = pb.vec2(this.id);
|
|
459
|
+
this.$l.best = pb.textureLoad(this.seedIn, this.id, 0).xy;
|
|
460
|
+
this.$l.bestD = pb.dot(pb.sub(this.best, this.p), pb.sub(this.best, this.p));
|
|
461
|
+
for(let dy = -1; dy <= 1; dy++){
|
|
462
|
+
for(let dx = -1; dx <= 1; dx++){
|
|
463
|
+
if (dx === 0 && dy === 0) {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
this.$l.q = pb.add(this.id, pb.mul(pb.ivec2(dx, dy), this.s));
|
|
467
|
+
this.$if(pb.and(pb.all(pb.greaterThanEqual(this.q, pb.ivec2(0))), pb.all(pb.lessThan(this.q, pb.ivec2(this.n)))), function() {
|
|
468
|
+
this.$l.c = pb.textureLoad(this.seedIn, this.q, 0).xy;
|
|
469
|
+
this.$l.cd = pb.dot(pb.sub(this.c, this.p), pb.sub(this.c, this.p));
|
|
470
|
+
this.$if(pb.lessThan(this.cd, this.bestD), function() {
|
|
471
|
+
this.best = this.c;
|
|
472
|
+
this.bestD = this.cd;
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
pb.textureStore(this.seedOut, pb.uvec2(this.id), pb.vec4(this.best, 0, 0));
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
this._resolveProgram = buildSDFProgram({
|
|
482
|
+
label: 'WaterlineResolve',
|
|
483
|
+
workgroupSize: [
|
|
484
|
+
WORKGROUP,
|
|
485
|
+
WORKGROUP,
|
|
486
|
+
1
|
|
487
|
+
],
|
|
488
|
+
compute (pb) {
|
|
489
|
+
// (origin x, origin z, cell size, resolution)
|
|
490
|
+
this.grid = pb.vec4().uniform(0);
|
|
491
|
+
this.seedIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
|
|
492
|
+
this.probeIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
|
|
493
|
+
this.result = pb.texStorage2D.rgba16float().storage(0);
|
|
494
|
+
pb.main(function() {
|
|
495
|
+
this.$l.id = this.$builtins.globalInvocationId.xy;
|
|
496
|
+
this.$l.p = pb.vec2(this.id);
|
|
497
|
+
this.$l.seed = pb.textureLoad(this.seedIn, pb.ivec2(this.id), 0).xy;
|
|
498
|
+
this.$l.v = pb.sub(this.p, this.seed);
|
|
499
|
+
this.$l.len = pb.length(this.v);
|
|
500
|
+
// A seed is a whole solid cell: the shore is half a cell nearer than its centre
|
|
501
|
+
this.$l.dist = pb.mul(pb.max(pb.sub(this.len, 0.5), 0), this.grid.z);
|
|
502
|
+
// No shore anywhere on the grid: as far as the grid reaches
|
|
503
|
+
this.dist = this.$choice(pb.lessThan(this.seed.x, NO_SEED * 0.5), pb.mul(this.grid.w, this.grid.z), this.dist);
|
|
504
|
+
// Gradient of the field at the rest level: horizontally from the neighbouring
|
|
505
|
+
// cells (one-sided at the grid edge), vertically from the probe above
|
|
506
|
+
this.$l.ip = pb.ivec2(this.id);
|
|
507
|
+
this.$l.last = pb.sub(pb.int(this.grid.w), 1);
|
|
508
|
+
this.$l.probe = pb.textureLoad(this.probeIn, this.ip, 0).xy;
|
|
509
|
+
this.$l.xl = pb.max(pb.sub(this.ip.x, 1), 0);
|
|
510
|
+
this.$l.xr = pb.min(pb.add(this.ip.x, 1), this.last);
|
|
511
|
+
this.$l.zl = pb.max(pb.sub(this.ip.y, 1), 0);
|
|
512
|
+
this.$l.zr = pb.min(pb.add(this.ip.y, 1), this.last);
|
|
513
|
+
this.$l.gx = pb.div(pb.sub(pb.textureLoad(this.probeIn, pb.ivec2(this.xr, this.ip.y), 0).x, pb.textureLoad(this.probeIn, pb.ivec2(this.xl, this.ip.y), 0).x), pb.mul(pb.float(pb.sub(this.xr, this.xl)), this.grid.z));
|
|
514
|
+
this.$l.gz = pb.div(pb.sub(pb.textureLoad(this.probeIn, pb.ivec2(this.ip.x, this.zr), 0).x, pb.textureLoad(this.probeIn, pb.ivec2(this.ip.x, this.zl), 0).x), pb.mul(pb.float(pb.sub(this.zr, this.zl)), this.grid.z));
|
|
515
|
+
this.$l.gy = pb.div(pb.sub(this.probe.y, this.probe.x), pb.mul(this.grid.z, 0.5));
|
|
516
|
+
// A flat bed never meets the water: the model then says far away
|
|
517
|
+
this.$l.gh = pb.max(pb.length(pb.vec2(this.gx, this.gz)), WATERLINE_MIN_SLOPE);
|
|
518
|
+
this.$l.a = pb.clamp(pb.div(this.probe.x, this.gh), -1e4, WATERLINE_MODEL_CLAMP);
|
|
519
|
+
this.$l.b = pb.clamp(pb.div(this.gy, this.gh), -1e4, WATERLINE_MODEL_CLAMP);
|
|
520
|
+
pb.textureStore(this.result, this.id, pb.vec4(this.dist, this.a, this.b, this.probe.x));
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
this._smoothHProgram = buildSmoothProgram(false);
|
|
525
|
+
this._smoothVProgram = buildSmoothProgram(true);
|
|
526
|
+
const passes = Math.log2(n);
|
|
527
|
+
for(let i = 0; i < this.levels; i++){
|
|
528
|
+
this._bindGroups.push({
|
|
529
|
+
seed: device.createBindGroup(this._seedProgram.bindGroupLayouts[0]),
|
|
530
|
+
jfa: Array.from({
|
|
531
|
+
length: passes
|
|
532
|
+
}, ()=>device.createBindGroup(this._jfaProgram.bindGroupLayouts[0])),
|
|
533
|
+
wetJfa: Array.from({
|
|
534
|
+
length: passes
|
|
535
|
+
}, ()=>device.createBindGroup(this._jfaProgram.bindGroupLayouts[0])),
|
|
536
|
+
resolve: device.createBindGroup(this._resolveProgram.bindGroupLayouts[0]),
|
|
537
|
+
smooth: [
|
|
538
|
+
device.createBindGroup(this._smoothHProgram.bindGroupLayouts[0]),
|
|
539
|
+
device.createBindGroup(this._smoothVProgram.bindGroupLayouts[0])
|
|
540
|
+
]
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* One pass of the separable smoothing: horizontal from the resolved field
|
|
547
|
+
* into a scratch texture, or vertical from it into a level's layer.
|
|
548
|
+
*/ function buildSmoothProgram(toArray) {
|
|
549
|
+
return buildSDFProgram({
|
|
550
|
+
label: toArray ? 'WaterlineSmoothV' : 'WaterlineSmoothH',
|
|
551
|
+
workgroupSize: [
|
|
552
|
+
WORKGROUP,
|
|
553
|
+
WORKGROUP,
|
|
554
|
+
1
|
|
555
|
+
],
|
|
556
|
+
compute (pb) {
|
|
557
|
+
// (pass: 0 horizontal from the resolved field, 1 vertical; resolution; cell size; layer)
|
|
558
|
+
this.smoothPass = pb.vec4().uniform(0);
|
|
559
|
+
this.src = pb.tex2D().sampleType('unfilterable-float').uniform(0);
|
|
560
|
+
// Nearest cell in the water, for the distance inland
|
|
561
|
+
this.wetIn = pb.tex2D().sampleType('unfilterable-float').uniform(0);
|
|
562
|
+
this.dst = toArray ? pb.texStorage2DArray.rgba16float().storage(0) : pb.texStorage2D.rgba16float().storage(0);
|
|
563
|
+
// Signed distance and B of a resolved texel: the bed model near the
|
|
564
|
+
// shore, the jump-flooded distance farther out, blended over a couple
|
|
565
|
+
// of metres. Inland, away from the model, the negated jump-flooded
|
|
566
|
+
// distance from the water side (the resolved distance is 0 on land).
|
|
567
|
+
pb.func('wlSigned', [
|
|
568
|
+
pb.vec4('t'),
|
|
569
|
+
pb.ivec2('q')
|
|
570
|
+
], function() {
|
|
571
|
+
this.$l.model = pb.and(pb.lessThan(pb.abs(this.t.w), SMOOTH_MODEL_REACH), pb.lessThan(pb.abs(this.t.y), SMOOTH_MODEL_CLAMP));
|
|
572
|
+
this.$l.wet = pb.textureLoad(this.wetIn, this.q, 0).xy;
|
|
573
|
+
this.$l.inland = this.$choice(pb.lessThan(this.wet.x, NO_SEED * 0.5), pb.mul(this.smoothPass.y, this.smoothPass.z), pb.mul(pb.max(pb.sub(pb.length(pb.sub(pb.vec2(this.q), this.wet)), 0.5), 0), this.smoothPass.z));
|
|
574
|
+
this.$l.far = this.$choice(pb.lessThan(this.t.w, 0), pb.neg(this.inland), this.t.x);
|
|
575
|
+
this.$l.w = this.$choice(this.model, pb.smoothStep(SMOOTH_BLEND_START, SMOOTH_BLEND_END, pb.abs(this.far)), 1);
|
|
576
|
+
this.$return(pb.vec2(pb.mix(this.t.y, this.far, this.w), this.$choice(this.model, this.t.z, 0)));
|
|
577
|
+
});
|
|
578
|
+
pb.main(function() {
|
|
579
|
+
this.$l.id = pb.ivec2(this.$builtins.globalInvocationId.xy);
|
|
580
|
+
this.$l.last = pb.sub(pb.int(this.smoothPass.y), 1);
|
|
581
|
+
this.$l.axis = toArray ? pb.ivec2(0, 1) : pb.ivec2(1, 0);
|
|
582
|
+
this.$l.acc = pb.vec2(0);
|
|
583
|
+
this.$l.wsum = pb.float(0);
|
|
584
|
+
for(let k = -4; k <= SMOOTH_RADIUS; k++){
|
|
585
|
+
const w = Math.exp(-(k * k) / (2 * SMOOTH_SIGMA * SMOOTH_SIGMA));
|
|
586
|
+
this.$l.q = pb.clamp(pb.add(this.id, pb.mul(this.axis, k)), pb.ivec2(0), pb.ivec2(this.last));
|
|
587
|
+
this.$l.t = pb.textureLoad(this.src, this.q, 0);
|
|
588
|
+
this.$l.v = toArray ? this.t.xy : this.wlSigned(this.t, this.q);
|
|
589
|
+
this.acc = pb.add(this.acc, pb.mul(this.v, w));
|
|
590
|
+
this.wsum = pb.add(this.wsum, w);
|
|
591
|
+
}
|
|
592
|
+
// Keep the bed unfiltered; the second pass carries its height through.
|
|
593
|
+
this.$l.own = pb.textureLoad(this.src, this.id, 0);
|
|
594
|
+
if (toArray) {
|
|
595
|
+
pb.textureArrayStore(this.dst, pb.uvec2(this.id), pb.int(this.smoothPass.w), pb.vec4(pb.div(this.acc, this.wsum), this.own.z, 0));
|
|
596
|
+
} else {
|
|
597
|
+
this.$l.bed = pb.neg(this.own.w);
|
|
598
|
+
this.$if(pb.and(pb.lessThan(pb.abs(this.own.w), SMOOTH_MODEL_REACH), pb.and(pb.lessThan(pb.abs(this.own.y), SMOOTH_MODEL_CLAMP), pb.and(pb.greaterThan(this.own.z, 1e-3), pb.lessThan(this.own.z, WATERLINE_MODEL_CLAMP)))), function() {
|
|
599
|
+
// A + B * dy = 0 gives vertical bed height; -SDF is a normal distance.
|
|
600
|
+
this.bed = pb.div(pb.neg(this.own.y), this.own.z);
|
|
601
|
+
});
|
|
602
|
+
pb.textureStore(this.dst, pb.uvec2(this.id), pb.vec4(pb.div(this.acc, this.wsum), this.bed, 0));
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export { SDFWaterlineSource, TerrainWaterlineSource, WaterlineField };
|
|
610
|
+
//# sourceMappingURL=waterline.js.map
|