@woosh/meep-engine 3.42.0 → 3.44.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/editor/prototypeEditorShell.d.ts.map +1 -1
- package/editor/prototypeEditorShell.js +4 -2
- package/package.json +91 -96
- package/src/engine/Clock.d.ts +15 -0
- package/src/engine/Clock.d.ts.map +1 -1
- package/src/engine/Clock.js +29 -5
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +11 -19
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +23 -13
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +61 -64
- package/src/engine/graphics3/AnimationSystem.d.ts +24 -15
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem.js +67 -61
- package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
- package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
- package/src/engine/graphics3/MeshSkinSystem.js +317 -0
- package/src/engine/graphics3/MeshSystem.d.ts +15 -35
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +21 -298
- package/src/engine/graphics3/RowChains.d.ts +76 -0
- package/src/engine/graphics3/RowChains.d.ts.map +1 -0
- package/src/engine/graphics3/RowChains.js +347 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
- package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
- package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
- package/src/engine/graphics3/animation/AnimationClips.js +79 -0
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
- package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
- package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
- package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
- package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
- package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_place.js +175 -130
- package/src/engine/graphics3/register_clips.d.ts +64 -0
- package/src/engine/graphics3/register_clips.d.ts.map +1 -0
- package/src/engine/graphics3/register_clips.js +114 -0
- package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
- package/src/engine/physics/cloth/PLAN.md +339 -9
- package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
- package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +22 -0
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +75 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +357 -284
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +280 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +1 -1
- package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
- package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
- package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
- package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
- package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
- package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +816 -179
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +321 -84
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +9 -7
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +30 -30
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_geodesic.js +142 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.js +608 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +160 -9
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +44 -15
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +60 -16
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
- package/src/engine/physics/cloth/playground/collide_main.js +1 -1
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/garment_build.js +17 -5
- package/src/engine/physics/cloth/playground/garment_main.js +1 -1
- package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/rig_build.js +302 -296
- package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/ClothState.js +63 -7
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +7 -2
- package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
- package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_hold_line.js +362 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_self_find.js +13 -13
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step.js +183 -20
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step_instance.js +10 -3
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +9 -9
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +26 -26
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/simulation/Ticker.d.ts +13 -0
- package/src/engine/simulation/Ticker.d.ts.map +1 -1
- package/src/engine/simulation/Ticker.js +43 -8
- package/src/shade/RENDERER_CONTRACT.md +8 -2
- package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
- package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/main.js +11 -19
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
- package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
- package/src/shade/playground/texture_encode/README.md +129 -109
- package/src/shade/playground/texture_encode/main.js +1430 -1430
- package/src/shade/playground/vgeo_runtime/README.md +5 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +6 -5
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
- package/src/shade/renderer/atmosphere/GPUSky.d.ts +12 -0
- package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/GPUSky.js +162 -147
- package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
- package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
- package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
- package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
- package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
- package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
- package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
- package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
- package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
- package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
- package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
- package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
- package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
- package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
- package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +10 -3
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/particles/DESIGN.md +13 -9
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +6 -2
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +1 -1
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +23 -1
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
- package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
- package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +4 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +74 -3
- package/src/shade/renderer/volumetrics/NOTES.md +1023 -957
- package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +5 -4
- package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +5 -4
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +1 -1
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +1 -1
- package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +1 -1
- package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +1 -1
- package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +41 -0
- package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +112 -0
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +9 -23
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +18 -126
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +22 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +228 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +0 -53
- package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
- package/src/shade/renderer/water/chunk_water_transport.js +7 -5
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +3 -1
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +4 -3
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +17 -7
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +93 -30
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +13 -5
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +29 -8
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +155 -30
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +6 -1
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +157 -39
- package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +91 -21
- package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/shader_water_particles.js +442 -70
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +11 -3
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +3 -0
- package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
- package/src/shade/wgsl/validate_wgsl_source.js +74 -3
- package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
- package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
- package/src/engine/graphics3/register_instance_animation.js +0 -201
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { assert } from "../../../../../core/assert.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
graph_prefix_scan_csdldf,
|
|
4
|
+
prefix_scan_csdldf_output_descriptor
|
|
5
|
+
} from "../../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
|
|
3
6
|
import {
|
|
4
7
|
build_indirect_compute_dispatch_command,
|
|
5
8
|
INDIRECT_COMPUTE_COMMAND_DESCRIPTOR
|
|
@@ -10,15 +13,23 @@ import { WATER_PARTICLE_ENTRY_STRUCT, WATER_PARTICLE_STRUCT } from "./WATER_PART
|
|
|
10
13
|
import {
|
|
11
14
|
shader_water_particles_bin,
|
|
12
15
|
shader_water_particles_bounds,
|
|
16
|
+
shader_water_particles_clear,
|
|
13
17
|
shader_water_particles_emit,
|
|
14
18
|
shader_water_particles_finalize,
|
|
19
|
+
shader_water_particles_fronts,
|
|
20
|
+
shader_water_particles_groups,
|
|
21
|
+
shader_water_particles_nest,
|
|
15
22
|
shader_water_particles_rank,
|
|
23
|
+
shader_water_particles_runs,
|
|
16
24
|
shader_water_particles_scatter,
|
|
25
|
+
shader_water_particles_share,
|
|
17
26
|
shader_water_particles_split,
|
|
18
27
|
shader_water_particles_total,
|
|
19
28
|
shader_water_particles_update,
|
|
20
29
|
shader_water_particles_weigh,
|
|
21
|
-
WATER_PARTICLE_CORNERS
|
|
30
|
+
WATER_PARTICLE_CORNERS,
|
|
31
|
+
WATER_PARTICLE_CROWD_WORDS,
|
|
32
|
+
WATER_PARTICLE_NEST_WORDS
|
|
22
33
|
} from "./shader_water_particles.js";
|
|
23
34
|
|
|
24
35
|
/** The longest step a particle takes in one frame, seconds: a stalled tab does not fling fronts across a lake. */
|
|
@@ -45,10 +56,18 @@ export class GPUWaterParticles {
|
|
|
45
56
|
#parity = 0;
|
|
46
57
|
#particles = [];
|
|
47
58
|
#children = null;
|
|
59
|
+
#child_sums = null;
|
|
60
|
+
#images = null;
|
|
61
|
+
#fronts = null;
|
|
62
|
+
#front_sums = null;
|
|
63
|
+
#runs = null;
|
|
64
|
+
#draw = null;
|
|
48
65
|
#buckets = null;
|
|
66
|
+
#offsets = null;
|
|
49
67
|
#slots = null;
|
|
50
68
|
#bucket_amplitude = null;
|
|
51
69
|
#bucket_weight = null;
|
|
70
|
+
#bucket_nest = null;
|
|
52
71
|
#visible = null;
|
|
53
72
|
#staging = null;
|
|
54
73
|
#entries = null;
|
|
@@ -56,7 +75,7 @@ export class GPUWaterParticles {
|
|
|
56
75
|
#commands = null;
|
|
57
76
|
|
|
58
77
|
/** @returns {GPUBuffer} the frame's hash: table size, then inclusive bucket offsets */
|
|
59
|
-
get offsets() { return this.#
|
|
78
|
+
get offsets() { return this.#offsets; }
|
|
60
79
|
/** @returns {GPUBuffer} the frame's entries, bucket by bucket, each bucket ordered by particle */
|
|
61
80
|
get entries() { return this.#entries; }
|
|
62
81
|
/** @returns {GPUBuffer} per wave row: occupied-level mask, then a height bound per level (f32 bits) */
|
|
@@ -89,16 +108,33 @@ export class GPUWaterParticles {
|
|
|
89
108
|
size: Math.max(16, size), usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC | usage });
|
|
90
109
|
const array_size = 16 + capacity * WATER_PARTICLE_STRUCT.size;
|
|
91
110
|
this.#particles = [buffer('a', array_size), buffer('b', array_size)];
|
|
111
|
+
// a scan reads one buffer and writes another: per particle how many it leaves, then where they end
|
|
112
|
+
const sums = elements => prefix_scan_csdldf_output_descriptor(elements).size;
|
|
92
113
|
this.#children = buffer('children', 16 + capacity * 4);
|
|
114
|
+
this.#child_sums = buffer('child sums', sums(capacity));
|
|
115
|
+
// per particle the mirror image the step left beside it at the outline
|
|
116
|
+
this.#images = buffer('images', capacity * WATER_PARTICLE_STRUCT.size);
|
|
117
|
+
// per particle whether it starts a run, then the scanned run it is in; per run its first particle and its
|
|
118
|
+
// share; per particle its run and how it is drawn
|
|
119
|
+
this.#fronts = buffer('fronts', 16 + capacity * 4);
|
|
120
|
+
this.#front_sums = buffer('front sums', sums(capacity));
|
|
121
|
+
this.#runs = buffer('runs', capacity * 8);
|
|
122
|
+
this.#draw = buffer('draw', capacity * 8);
|
|
123
|
+
// per bucket its entries, then the hash: table size and inclusive offsets
|
|
93
124
|
this.#buckets = buffer('buckets', 16 + this.#table_limit * 4);
|
|
125
|
+
this.#offsets = buffer('offsets', sums(this.#table_limit));
|
|
94
126
|
this.#slots = buffer('slots', capacity * WATER_PARTICLE_CORNERS * 4);
|
|
95
127
|
this.#bucket_amplitude = buffer('bucket amplitude', this.#table_limit * 4);
|
|
96
|
-
|
|
128
|
+
// the summed steepness, the largest front and front complement entered, and the entries; then the most a point
|
|
129
|
+
// under it reads, and its entries by key
|
|
130
|
+
this.#bucket_weight = buffer('bucket weight', this.#table_limit * WATER_PARTICLE_CROWD_WORDS * 4);
|
|
131
|
+
this.#bucket_nest = buffer('bucket nest', this.#table_limit * WATER_PARTICLE_NEST_WORDS * 4);
|
|
97
132
|
this.#visible = buffer('visible', capacity * 4);
|
|
98
133
|
const entries = capacity * WATER_PARTICLE_CORNERS * WATER_PARTICLE_ENTRY_STRUCT.size;
|
|
99
134
|
this.#staging = buffer('staging', entries);
|
|
100
135
|
this.#entries = buffer('entries', entries);
|
|
101
|
-
this
|
|
136
|
+
// the particles' this frame and next, and the clear of the frame's table
|
|
137
|
+
this.#commands = [0, 1, 2].map(i => device.createBuffer({ label: `Water / particles command ${i}`,
|
|
102
138
|
size: INDIRECT_COMPUTE_COMMAND_DESCRIPTOR.size, usage: INDIRECT_COMPUTE_COMMAND_DESCRIPTOR.usage }));
|
|
103
139
|
this.#rows = 0;
|
|
104
140
|
this.#parity = 0;
|
|
@@ -121,11 +157,16 @@ export class GPUWaterParticles {
|
|
|
121
157
|
}
|
|
122
158
|
|
|
123
159
|
dispose() {
|
|
124
|
-
for (const buffer of [...this.#particles, this.#children, this.#
|
|
125
|
-
this.#
|
|
160
|
+
for (const buffer of [...this.#particles, this.#children, this.#child_sums, this.#images, this.#fronts, this.#front_sums, this.#runs,
|
|
161
|
+
this.#draw, this.#buckets, this.#offsets, this.#slots, this.#bucket_amplitude, this.#bucket_weight, this.#bucket_nest, this.#visible,
|
|
162
|
+
this.#staging, this.#entries, this.#body_bounds, ...(this.#commands ?? [])]) {
|
|
163
|
+
buffer?.destroy();
|
|
164
|
+
}
|
|
126
165
|
this.#particles = [];
|
|
127
|
-
this.#children = this.#
|
|
128
|
-
this.#
|
|
166
|
+
this.#children = this.#child_sums = this.#images = this.#buckets = this.#offsets = this.#slots = this.#bucket_amplitude = null;
|
|
167
|
+
this.#staging = this.#entries = null;
|
|
168
|
+
this.#fronts = this.#front_sums = this.#runs = this.#draw = null;
|
|
169
|
+
this.#bucket_weight = this.#bucket_nest = this.#visible = null;
|
|
129
170
|
this.#body_bounds = null;
|
|
130
171
|
this.#commands = null;
|
|
131
172
|
this.#device = null;
|
|
@@ -158,10 +199,14 @@ export class GPUWaterParticles {
|
|
|
158
199
|
// a frame that does not step bins the particles where they are
|
|
159
200
|
const next = stepping ? this.#particles[1 - this.#parity] : current;
|
|
160
201
|
if (stepping) { this.#parity = 1 - this.#parity; }
|
|
161
|
-
const [command_current, command_next] = this.#commands;
|
|
202
|
+
const [command_current, command_next, command_table] = this.#commands;
|
|
162
203
|
const geometries = scene.geometries;
|
|
163
204
|
let children = graph_import_buffer(graph, this.#children, 'Water / particle children');
|
|
205
|
+
let child_sums = graph_import_buffer(graph, this.#child_sums, 'Water / particle child sums');
|
|
164
206
|
let buckets = graph_import_buffer(graph, this.#buckets, 'Water / particle buckets');
|
|
207
|
+
let offsets = graph_import_buffer(graph, this.#offsets, 'Water / particle offsets');
|
|
208
|
+
let fronts = graph_import_buffer(graph, this.#fronts, 'Water / particle fronts');
|
|
209
|
+
let front_sums = graph_import_buffer(graph, this.#front_sums, 'Water / particle front sums');
|
|
165
210
|
const node = (name, execute, reads, writes) => {
|
|
166
211
|
const data = {};
|
|
167
212
|
const pass = graph.add(name, data, (d, resources, context) => execute(resources, context, d));
|
|
@@ -177,52 +222,70 @@ export class GPUWaterParticles {
|
|
|
177
222
|
encoder.copyBufferToBuffer(current, 0, this.#children, 0, 4);
|
|
178
223
|
build_indirect_compute_dispatch_command(64, encoder, current, 0, command_current, 0, true);
|
|
179
224
|
shader_water_particles_update.dispatchIndirect({ encoder, command: command_current, bindings: {
|
|
180
|
-
frame: { dt: step, capacity }, particles: current, children: this.#children, activity,
|
|
225
|
+
frame: { dt: step, capacity }, particles: current, children: this.#children, images: this.#images, activity,
|
|
181
226
|
scene_database: scene.scene_database_buffer, geometries: geometries.buffer_metadata,
|
|
182
227
|
blas_lookup: geometries.blas.buffer_metadata, blas_data: geometries.blas.buffer_data,
|
|
183
228
|
meshlet_metadata: geometries.meshlets.buffer_metadata, meshlet_data: geometries.meshlets.buffer_data,
|
|
184
229
|
} });
|
|
185
230
|
}, {}, { children }).children;
|
|
186
|
-
|
|
231
|
+
child_sums = graph_prefix_scan_csdldf({ graph, input: children, output: child_sums, element_max_count: capacity });
|
|
187
232
|
|
|
188
233
|
// What they leave into the next array, then the frame's splashes after them.
|
|
189
234
|
node('Water / particles split and emit', (resources, { encoder }) => {
|
|
190
235
|
shader_water_particles_split.dispatchIndirect({ encoder, command: command_current, bindings: {
|
|
191
|
-
capacity, particles: current, children: this.#
|
|
192
|
-
shader_water_particles_total.dispatch({ encoder, bindings: { capacity, children: this.#
|
|
236
|
+
capacity, particles: current, children: this.#child_sums, images: this.#images, next } });
|
|
237
|
+
shader_water_particles_total.dispatch({ encoder, bindings: { capacity, children: this.#child_sums, next } });
|
|
193
238
|
shader_water_particles_emit.dispatchIndirect({ encoder, command: commands, command_offset: emit_command,
|
|
194
239
|
bindings: { capacity, scene_database: scene.scene_database_buffer, emit_rows, steep, activity,
|
|
195
240
|
particle_bounds: this.#body_bounds, next } });
|
|
196
|
-
shader_water_particles_finalize.dispatch({ encoder, bindings: { limits: { capacity, table_limit }, next, offsets: this.#buckets
|
|
197
|
-
|
|
241
|
+
shader_water_particles_finalize.dispatch({ encoder, bindings: { limits: { capacity, table_limit }, next, offsets: this.#buckets,
|
|
242
|
+
table_command: command_table } });
|
|
243
|
+
}, { child_sums }, {});
|
|
198
244
|
}
|
|
199
245
|
|
|
200
|
-
//
|
|
201
|
-
|
|
202
|
-
buckets = node('Water / particles bin', (resources, { encoder }) => {
|
|
246
|
+
// Each front's run of particles, so that a whole one is drawn as the seven it was emitted as.
|
|
247
|
+
fronts = node('Water / particles fronts', (resources, { encoder }) => {
|
|
203
248
|
if (!stepping) {
|
|
204
249
|
// the table size the last stepping frame chose for these particles
|
|
205
|
-
shader_water_particles_finalize.dispatch({ encoder, bindings: { limits: { capacity, table_limit }, next, offsets: this.#buckets
|
|
250
|
+
shader_water_particles_finalize.dispatch({ encoder, bindings: { limits: { capacity, table_limit }, next, offsets: this.#buckets,
|
|
251
|
+
table_command: command_table } });
|
|
206
252
|
}
|
|
207
253
|
build_indirect_compute_dispatch_command(64, encoder, next, 0, command_next, 0, true);
|
|
208
|
-
encoder.
|
|
209
|
-
|
|
210
|
-
|
|
254
|
+
encoder.copyBufferToBuffer(next, 0, this.#fronts, 0, 4);
|
|
255
|
+
shader_water_particles_fronts.dispatchIndirect({ encoder, command: command_next, bindings: { next, fronts: this.#fronts } });
|
|
256
|
+
}, {}, { fronts }).fronts;
|
|
257
|
+
front_sums = graph_prefix_scan_csdldf({ graph, input: fronts, output: front_sums, element_max_count: capacity });
|
|
258
|
+
|
|
259
|
+
// The frame's hash: how each particle is drawn, how crowded each cell is and so how much of each run its crowd
|
|
260
|
+
// leaves drawn, then each packet drawn into the cells its support overlaps, offsets, entries in order.
|
|
261
|
+
buckets = node('Water / particles bin', (resources, { encoder }) => {
|
|
262
|
+
const draw = this.#draw, runs = this.#runs;
|
|
263
|
+
shader_water_particles_runs.dispatchIndirect({ encoder, command: command_next, bindings: { next, fronts: this.#front_sums, runs } });
|
|
264
|
+
shader_water_particles_groups.dispatchIndirect({ encoder, command: command_next, bindings: { next, fronts: this.#front_sums, runs, draw } });
|
|
265
|
+
shader_water_particles_clear.dispatchIndirect({ encoder, command: command_table, bindings: {
|
|
266
|
+
buckets: this.#buckets, bucket_amplitude: this.#bucket_amplitude, bucket_weight: this.#bucket_weight,
|
|
267
|
+
bucket_nest: this.#bucket_nest } });
|
|
211
268
|
shader_water_particles_weigh.dispatchIndirect({ encoder, command: command_next, bindings: {
|
|
212
|
-
next, activity, offsets: this.#buckets, bucket_weight: this.#bucket_weight } });
|
|
269
|
+
next, activity, offsets: this.#buckets, draw, bucket_weight: this.#bucket_weight, body_bounds: this.#body_bounds } });
|
|
270
|
+
shader_water_particles_nest.dispatchIndirect({ encoder, command: command_next, bindings: {
|
|
271
|
+
next, activity, offsets: this.#buckets, draw, body_bounds: this.#body_bounds, bucket_weight: this.#bucket_weight,
|
|
272
|
+
bucket_nest: this.#bucket_nest } });
|
|
273
|
+
shader_water_particles_share.dispatchIndirect({ encoder, command: command_next, bindings: {
|
|
274
|
+
next, activity, offsets: this.#buckets, bucket_weight: this.#bucket_weight, bucket_nest: this.#bucket_nest,
|
|
275
|
+
body_bounds: this.#body_bounds, draw, runs } });
|
|
213
276
|
shader_water_particles_bin.dispatchIndirect({ encoder, command: command_next, bindings: {
|
|
214
277
|
next, activity, buckets: this.#buckets, slots: this.#slots, bucket_amplitude: this.#bucket_amplitude,
|
|
215
|
-
body_bounds: this.#body_bounds,
|
|
216
|
-
}, {}, { buckets }).buckets;
|
|
217
|
-
|
|
278
|
+
body_bounds: this.#body_bounds, draw, runs, visible: this.#visible } });
|
|
279
|
+
}, { front_sums }, { buckets }).buckets;
|
|
280
|
+
offsets = graph_prefix_scan_csdldf({ graph, input: buckets, output: offsets, element_max_count: table_limit });
|
|
218
281
|
node('Water / particles order and bound', (resources, { encoder }) => {
|
|
219
|
-
const bindings = { next, offsets: this.#
|
|
282
|
+
const bindings = { next, offsets: this.#offsets, slots: this.#slots, draw: this.#draw };
|
|
220
283
|
shader_water_particles_scatter.dispatchIndirect({ encoder, command: command_next, bindings: { ...bindings,
|
|
221
284
|
visible: this.#visible, staging: this.#staging } });
|
|
222
285
|
shader_water_particles_rank.dispatchIndirect({ encoder, command: command_next, bindings: { ...bindings,
|
|
223
286
|
staging: this.#staging, entries: this.#entries } });
|
|
224
287
|
shader_water_particles_bounds.dispatchIndirect({ encoder, command: command_next, bindings: { next, activity,
|
|
225
|
-
offsets: this.#
|
|
226
|
-
}, {
|
|
288
|
+
offsets: this.#offsets, bucket_amplitude: this.#bucket_amplitude, draw: this.#draw, body_bounds: this.#body_bounds } });
|
|
289
|
+
}, { offsets }, {});
|
|
227
290
|
}
|
|
228
291
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WATER_PARTICLE_STRUCT.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,
|
|
1
|
+
{"version":3,"file":"WATER_PARTICLE_STRUCT.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,iDAoBoB;AAEpB;;;;GAIG;AACH,uDAkByB;6BAvDI,sCAAsC"}
|
|
@@ -10,7 +10,7 @@ import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
|
10
10
|
* without integration error and every particle of one front shares the origin and the age.
|
|
11
11
|
*/
|
|
12
12
|
export const WATER_PARTICLE_STRUCT = WebGPUStruct.from({
|
|
13
|
-
/** Centre of the front, or
|
|
13
|
+
/** Centre of the front, or the mirror image of it for a reflection; metric local xz. */
|
|
14
14
|
origin: vec2f,
|
|
15
15
|
/** Propagation direction, radians from local +x towards +z. */
|
|
16
16
|
angle: f32,
|
|
@@ -24,6 +24,11 @@ export const WATER_PARTICLE_STRUCT = WebGPUStruct.from({
|
|
|
24
24
|
dispersion: f32,
|
|
25
25
|
/** The water_waves row of the body it lives on. */
|
|
26
26
|
body: u32,
|
|
27
|
+
/**
|
|
28
|
+
* 1 once the first of its support has left its body's outline, or that of the particle it split from: its mirror
|
|
29
|
+
* image was emitted then, and it dies once the last of it has left too. 0 from emission.
|
|
30
|
+
*/
|
|
31
|
+
reflected: u32,
|
|
27
32
|
}, 'WaterParticle');
|
|
28
33
|
|
|
29
34
|
/**
|
|
@@ -37,13 +42,16 @@ export const WATER_PARTICLE_ENTRY_STRUCT = WebGPUStruct.from({
|
|
|
37
42
|
angle: f32,
|
|
38
43
|
amplitude: f32,
|
|
39
44
|
radius: f32,
|
|
40
|
-
/**
|
|
41
|
-
|
|
45
|
+
/** Half-angle of the window around the front's centre: the angle to the front's neighbouring particle. */
|
|
46
|
+
dispersion: f32,
|
|
42
47
|
/** Carrier phase lag of the crests behind the envelope, radians. */
|
|
43
48
|
phase: f32,
|
|
44
|
-
/** water_waves row
|
|
49
|
+
/** water_waves row and level, as water_particle_key packs them */
|
|
45
50
|
key: u32,
|
|
46
51
|
/** Index of the particle, which orders a bucket. */
|
|
47
52
|
source: u32,
|
|
48
|
-
|
|
53
|
+
/** How far the particle stands from its front's centre, metres. */
|
|
54
|
+
distance: f32,
|
|
55
|
+
/** Half the length of its envelope across its front, metres. */
|
|
56
|
+
half_length: f32,
|
|
49
57
|
}, 'WaterParticleEntry');
|
|
@@ -1,19 +1,40 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Levels of the particle hash: cell sizes 4 mm · 2^level, so supports up to 256 m, which a 2 m splash's stretched
|
|
3
|
+
* packets reach before they die.
|
|
4
|
+
*/
|
|
5
|
+
export const WATER_PARTICLE_LEVELS: 18;
|
|
3
6
|
/** Cell size of level 0, metres. A particle sits at the smallest level whose cell is at least its support's diameter. */
|
|
4
7
|
export const WATER_PARTICLE_LEVEL0_CELL: number;
|
|
8
|
+
/**
|
|
9
|
+
* How fast a packet's envelope stretches as it disperses, as a fraction κ of its group speed, by its wavenumber k against
|
|
10
|
+
* k_m = √(g/(σ/ρ)), the wavenumber of the slowest crests (λ = 1.71 cm): from x = log₂(k/k_m) = -7 in steps of a quarter,
|
|
11
|
+
* held at both ends.
|
|
12
|
+
*
|
|
13
|
+
* Its half-length h, 2r when emitted, grows as h² = (2r)² + (κD/2)² over the distance D its front has travelled since:
|
|
14
|
+
* the spread of an unchirped packet's energy grows as the spread of its group speeds times time, in quadrature with
|
|
15
|
+
* where it began (Jeschke & Wojtan 2017 grow it linearly, eq. 14, its far limit). Each κ is the one whose peak
|
|
16
|
+
* √(2r/h) best matches exact linear theory, ω² = gk + (σ/ρ)k³, for the emitted packet at 5 to 225 wavelengths (FFT,
|
|
17
|
+
* worst ratio minimised): within 2% for capillary waves up to r = 8.5 mm and gravity waves from r = 6 cm, where κ
|
|
18
|
+
* tends to 1 and 0.9, and 5% from 4 cm. Between, around the slowest group speed (λ = 4.4 cm), a broad band's energy
|
|
19
|
+
* gathers at that speed and the peak falls as t^(−1/3), which no κ draws: up to 16% below r = 12 mm, 27% at 3 cm.
|
|
20
|
+
*/
|
|
21
|
+
export const WATER_PARTICLE_STRETCH: number[];
|
|
5
22
|
/**
|
|
6
23
|
* The physics of one wave particle as pure functions (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §5).
|
|
7
24
|
*
|
|
8
25
|
* A particle of radius r carries a packet of wavelength 2r, k = π/r. Under the gravity–capillary
|
|
9
26
|
* dispersion relation the packet's envelope travels at the group speed and its crests at the phase speed
|
|
10
|
-
* (Jeschke & Wojtan 2017; Xue et al. 2025 give wave particles their own wavelength's dispersion).
|
|
11
|
-
*
|
|
12
|
-
*
|
|
27
|
+
* (Jeschke & Wojtan 2017; Xue et al. 2025 give wave particles their own wavelength's dispersion). The packet holds a
|
|
28
|
+
* band of wavelengths around 2r, which the same relation moves apart: its envelope, two radii either side when emitted,
|
|
29
|
+
* stretches as it travels and its height falls to keep its energy (WATER_PARTICLE_STRETCH), as a splash's single ring
|
|
30
|
+
* becomes a widening train of ripples. It loses amplitude at the clean-surface viscous rate 2νk² plus the surface-film
|
|
31
|
+
* rate k√(νω)/(2√2) of natural water — so a raindrop's ripple is gone in a fraction of a second while a big splash
|
|
32
|
+
* crosses a bay.
|
|
13
33
|
*
|
|
14
|
-
* The particles of a front are
|
|
15
|
-
*
|
|
16
|
-
* whatever the spacing,
|
|
34
|
+
* The particles of a front are β apart in angle around its centre, and a packet's crests are arcs around that
|
|
35
|
+
* centre; a cosine window of half-angle β is a partition of unity over them at every radius, so the front's
|
|
36
|
+
* height is the packet's amplitude whatever the spacing, splitting a front changes none of it, and one front
|
|
37
|
+
* adds at most two particles at any point.
|
|
17
38
|
*
|
|
18
39
|
* @type {CodeChunk}
|
|
19
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_water_particle.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/chunk_water_particle.js"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"chunk_water_particle.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/chunk_water_particle.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH,uCAAwC;AAKxC,yHAAyH;AACzH,gDAAkD;AAElD;;;;;;;;;;;;GAYG;AACH,8CAIE;AAKF;;;;;;;;;;;;;;;;;;GAkBG;AACH,mCAFU,SAAS,CAmN6G;0BA3QtG,uCAAuC"}
|
|
@@ -3,30 +3,65 @@ import { chunk_pcg3d } from "../../../shader/chunk/random/pcg/chunk_pcg3d.js";
|
|
|
3
3
|
import { WATER_PARTICLE_ENTRY_STRUCT, WATER_PARTICLE_STRUCT } from "./WATER_PARTICLE_STRUCT.js";
|
|
4
4
|
import { chunk_water_spectrum } from "../spectrum/chunk_water_spectrum.js";
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Levels of the particle hash: cell sizes 4 mm · 2^level, so supports up to 256 m, which a 2 m splash's stretched
|
|
8
|
+
* packets reach before they die.
|
|
9
|
+
*/
|
|
10
|
+
export const WATER_PARTICLE_LEVELS = 18;
|
|
11
|
+
|
|
12
|
+
/** Bits of a hash key that hold the level, below the body's row. */
|
|
13
|
+
const WATER_PARTICLE_LEVEL_BITS = Math.ceil(Math.log2(WATER_PARTICLE_LEVELS));
|
|
8
14
|
|
|
9
15
|
/** Cell size of level 0, metres. A particle sits at the smallest level whose cell is at least its support's diameter. */
|
|
10
16
|
export const WATER_PARTICLE_LEVEL0_CELL = 1 / 256;
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* How fast a packet's envelope stretches as it disperses, as a fraction κ of its group speed, by its wavenumber k against
|
|
20
|
+
* k_m = √(g/(σ/ρ)), the wavenumber of the slowest crests (λ = 1.71 cm): from x = log₂(k/k_m) = -7 in steps of a quarter,
|
|
21
|
+
* held at both ends.
|
|
22
|
+
*
|
|
23
|
+
* Its half-length h, 2r when emitted, grows as h² = (2r)² + (κD/2)² over the distance D its front has travelled since:
|
|
24
|
+
* the spread of an unchirped packet's energy grows as the spread of its group speeds times time, in quadrature with
|
|
25
|
+
* where it began (Jeschke & Wojtan 2017 grow it linearly, eq. 14, its far limit). Each κ is the one whose peak
|
|
26
|
+
* √(2r/h) best matches exact linear theory, ω² = gk + (σ/ρ)k³, for the emitted packet at 5 to 225 wavelengths (FFT,
|
|
27
|
+
* worst ratio minimised): within 2% for capillary waves up to r = 8.5 mm and gravity waves from r = 6 cm, where κ
|
|
28
|
+
* tends to 1 and 0.9, and 5% from 4 cm. Between, around the slowest group speed (λ = 4.4 cm), a broad band's energy
|
|
29
|
+
* gathers at that speed and the peak falls as t^(−1/3), which no κ draws: up to 16% below r = 12 mm, 27% at 3 cm.
|
|
30
|
+
*/
|
|
31
|
+
export const WATER_PARTICLE_STRETCH = [
|
|
32
|
+
0.9002, 0.9002, 0.8998, 0.8993, 0.8984, 0.8971, 0.8957, 0.8935, 0.8904, 0.8859, 0.8798, 0.8706, 0.8585, 0.8411, 0.8166,
|
|
33
|
+
0.7819, 0.7323, 0.6669, 0.5795, 0.461, 0.216, 0.0922, 0.064, 0.0723, 0.1089, 0.1877, 0.3427, 0.6145, 0.9295, 1.0417,
|
|
34
|
+
1.0734, 1.0739, 1.0622, 1.0469, 1.0313, 1.0175, 1.0059, 0.9969, 0.9899,
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
/** log₂(k/k_m) of the stretch table's first entry; entries are a quarter apart. */
|
|
38
|
+
const WATER_PARTICLE_STRETCH_FIRST = -7;
|
|
39
|
+
|
|
12
40
|
/**
|
|
13
41
|
* The physics of one wave particle as pure functions (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §5).
|
|
14
42
|
*
|
|
15
43
|
* A particle of radius r carries a packet of wavelength 2r, k = π/r. Under the gravity–capillary
|
|
16
44
|
* dispersion relation the packet's envelope travels at the group speed and its crests at the phase speed
|
|
17
|
-
* (Jeschke & Wojtan 2017; Xue et al. 2025 give wave particles their own wavelength's dispersion).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
45
|
+
* (Jeschke & Wojtan 2017; Xue et al. 2025 give wave particles their own wavelength's dispersion). The packet holds a
|
|
46
|
+
* band of wavelengths around 2r, which the same relation moves apart: its envelope, two radii either side when emitted,
|
|
47
|
+
* stretches as it travels and its height falls to keep its energy (WATER_PARTICLE_STRETCH), as a splash's single ring
|
|
48
|
+
* becomes a widening train of ripples. It loses amplitude at the clean-surface viscous rate 2νk² plus the surface-film
|
|
49
|
+
* rate k√(νω)/(2√2) of natural water — so a raindrop's ripple is gone in a fraction of a second while a big splash
|
|
50
|
+
* crosses a bay.
|
|
20
51
|
*
|
|
21
|
-
* The particles of a front are
|
|
22
|
-
*
|
|
23
|
-
* whatever the spacing,
|
|
52
|
+
* The particles of a front are β apart in angle around its centre, and a packet's crests are arcs around that
|
|
53
|
+
* centre; a cosine window of half-angle β is a partition of unity over them at every radius, so the front's
|
|
54
|
+
* height is the packet's amplitude whatever the spacing, splitting a front changes none of it, and one front
|
|
55
|
+
* adds at most two particles at any point.
|
|
24
56
|
*
|
|
25
57
|
* @type {CodeChunk}
|
|
26
58
|
*/
|
|
27
59
|
export const chunk_water_particle = CodeChunk.from(/* language=WGSL */ `
|
|
28
60
|
const WATER_PARTICLE_LEVELS: u32 = ${WATER_PARTICLE_LEVELS}u;
|
|
61
|
+
const WATER_PARTICLE_LEVEL_BITS: u32 = ${WATER_PARTICLE_LEVEL_BITS}u;
|
|
29
62
|
const WATER_PARTICLE_LEVEL0_CELL: f32 = ${WATER_PARTICLE_LEVEL0_CELL};
|
|
63
|
+
const WATER_PARTICLE_STRETCH = array<f32, ${WATER_PARTICLE_STRETCH.length}>(${WATER_PARTICLE_STRETCH.join(', ')});
|
|
64
|
+
const WATER_PARTICLE_STRETCH_FIRST: f32 = ${WATER_PARTICLE_STRETCH_FIRST}.0;
|
|
30
65
|
// kinematic viscosity of water, m²/s
|
|
31
66
|
const WATER_VISCOSITY: f32 = 1e-6;
|
|
32
67
|
const WATER_PI: f32 = 3.14159265358979;
|
|
@@ -66,7 +101,7 @@ fn water_particle_position(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> vec2<
|
|
|
66
101
|
return particle.origin + water_particle_direction(particle.angle) * water_particle_distance(particle);
|
|
67
102
|
}
|
|
68
103
|
|
|
69
|
-
// The front's arc between neighbouring particles
|
|
104
|
+
// The front's arc between neighbouring particles, at the particle's own radius: what the window spans there.
|
|
70
105
|
fn water_particle_width(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> f32 {
|
|
71
106
|
return max(particle.dispersion * water_particle_distance(particle), 1e-3 * particle.radius);
|
|
72
107
|
}
|
|
@@ -77,9 +112,79 @@ fn water_particle_phase(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> f32 {
|
|
|
77
112
|
return water_particle_wavenumber(particle.radius) * lag;
|
|
78
113
|
}
|
|
79
114
|
|
|
80
|
-
//
|
|
81
|
-
fn
|
|
82
|
-
return
|
|
115
|
+
// How far from a splash's centre its ring starts: two radii, the packet's half-length, so it starts clear of the centre.
|
|
116
|
+
fn water_particle_launch_distance(radius: f32) -> f32 {
|
|
117
|
+
return 2.0 * radius;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// How fast the packet's envelope stretches, as a fraction of its group speed (WATER_PARTICLE_STRETCH): interpolated in
|
|
121
|
+
// log κ between quarter octaves of k against the wavenumber of the slowest crests.
|
|
122
|
+
fn water_particle_stretch(radius: f32) -> f32 {
|
|
123
|
+
let octave = log2(water_particle_wavenumber(radius) * sqrt(WATER_SURFACE_TENSION / WATER_GRAVITY));
|
|
124
|
+
let last = f32(${WATER_PARTICLE_STRETCH.length}u - 1u);
|
|
125
|
+
let t = clamp(4.0 * (octave - WATER_PARTICLE_STRETCH_FIRST), 0.0, last);
|
|
126
|
+
let i = u32(min(floor(t), last - 1.0));
|
|
127
|
+
return exp2(mix(log2(WATER_PARTICLE_STRETCH[i]), log2(WATER_PARTICLE_STRETCH[i + 1u]), t - f32(i)));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Half the length of the packet's envelope across its front, for a front that stands distance from its centre: 2r when
|
|
131
|
+
// emitted, growing in quadrature with half the stretch over the distance travelled since. Held to half the largest support
|
|
132
|
+
// the hash holds, so a window no wider keeps the packet within the coarsest cells.
|
|
133
|
+
fn water_particle_half_length_at(radius: f32, distance: f32) -> f32 {
|
|
134
|
+
let travelled = max(distance - water_particle_launch_distance(radius), 0.0);
|
|
135
|
+
let stretched = length(vec2<f32>(2.0 * radius, 0.5 * water_particle_stretch(radius) * travelled));
|
|
136
|
+
return min(stretched, 0.5 * water_particle_support_limit());
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fn water_particle_half_length(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> f32 {
|
|
140
|
+
return water_particle_half_length_at(particle.radius, water_particle_distance(particle));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Radius of a circle around the particle holding its whole kernel: the envelope's half-length h across the front, and
|
|
144
|
+
// along it the front's arc of half-angle β plus its outer edge's overhang. A point at radius ρ = D + u and angle ψ from
|
|
145
|
+
// a particle at distance D lies |d|² = u² + 4ρD·sin²(ψ/2) ≤ h² + (D + h)Dβ² ≤ h² + ((D + h/2)β)² from it, and
|
|
146
|
+
// width ≥ Dβ.
|
|
147
|
+
fn water_particle_support(half_length: f32, width: f32, dispersion: f32) -> f32 {
|
|
148
|
+
return length(vec2<f32>(half_length, width + 0.5 * half_length * dispersion));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// The largest support the hash holds: half its coarsest cell.
|
|
152
|
+
fn water_particle_support_limit() -> f32 {
|
|
153
|
+
return 0.5 * water_particle_cell_size(WATER_PARTICLE_LEVELS - 1u);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Whether two particles are of one front: one splash's, neither reflected or faded apart, alike in all but angle.
|
|
157
|
+
fn water_particle_same_front(a: ${WATER_PARTICLE_STRUCT.wgsl_ref}, b: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> bool {
|
|
158
|
+
return a.body == b.body && all(a.origin == b.origin) && a.age == b.age && a.amplitude == b.amplitude
|
|
159
|
+
&& a.radius == b.radius && a.dispersion == b.dispersion;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// How a particle is drawn, given its front's run of particles in the array and its place in it: 1 as itself; 0 not at
|
|
163
|
+
// all, or a group of 3^g as one packet with 3^g times its window, when its front is whole. Whole is every particle
|
|
164
|
+
// the front split into still there, in order and alike: as many as fill its circle. The step puts a particle's three
|
|
165
|
+
// in its place, the middle at its own angle, so a group of 3^g is 3^g in a row and its middle stands at the angle
|
|
166
|
+
// the group was emitted at; with curved crests the groups draw what the particles do. The largest group whose packet
|
|
167
|
+
// the hash holds: the seven a front was emitted as, until their windows outgrow the coarsest cell.
|
|
168
|
+
fn water_particle_group(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}, members: u32, offset: u32) -> u32 {
|
|
169
|
+
if (members != u32(round(WATER_TAU / particle.dispersion))) { return 1u; }
|
|
170
|
+
var group = 1u;
|
|
171
|
+
for (var g = 0u; g < 20u && members % (3u * group) == 0u; g++) { group *= 3u; }
|
|
172
|
+
let distance = water_particle_distance(particle);
|
|
173
|
+
let half_length = water_particle_half_length_at(particle.radius, distance);
|
|
174
|
+
for (var g = 0u; g < 20u && group > 1u; g++) {
|
|
175
|
+
let dispersion = particle.dispersion * f32(group);
|
|
176
|
+
let width = max(dispersion * distance, 1e-3 * particle.radius);
|
|
177
|
+
if (water_particle_support(half_length, width, dispersion) <= water_particle_support_limit()) { break; }
|
|
178
|
+
group /= 3u;
|
|
179
|
+
}
|
|
180
|
+
return select(0u, group, offset % group == group / 2u);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// The particle as its group draws it: one packet with the group's window.
|
|
184
|
+
fn water_particle_drawn(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}, group: u32) -> ${WATER_PARTICLE_STRUCT.wgsl_ref} {
|
|
185
|
+
var drawn = particle;
|
|
186
|
+
drawn.dispersion *= f32(group);
|
|
187
|
+
return drawn;
|
|
83
188
|
}
|
|
84
189
|
|
|
85
190
|
// The smallest hash level whose cell is at least the support's diameter, so the support overlaps at most
|
|
@@ -93,8 +198,13 @@ fn water_particle_cell_size(level: u32) -> f32 {
|
|
|
93
198
|
return WATER_PARTICLE_LEVEL0_CELL * exp2(f32(level));
|
|
94
199
|
}
|
|
95
200
|
|
|
201
|
+
// A hash entry's body and level in one word.
|
|
202
|
+
fn water_particle_key(body: u32, level: u32) -> u32 {
|
|
203
|
+
return (body << WATER_PARTICLE_LEVEL_BITS) | level;
|
|
204
|
+
}
|
|
205
|
+
|
|
96
206
|
fn water_particle_bucket(body: u32, level: u32, cell: vec2<i32>, table_size: u32) -> u32 {
|
|
97
|
-
let bits = pcg3d(vec3<u32>((body
|
|
207
|
+
let bits = pcg3d(vec3<u32>(water_particle_key(body, level), bitcast<u32>(cell.x), bitcast<u32>(cell.y)));
|
|
98
208
|
return bits.x & (table_size - 1u);
|
|
99
209
|
}
|
|
100
210
|
|
|
@@ -105,39 +215,54 @@ struct WaterParticleField {
|
|
|
105
215
|
displacement: vec2<f32>,
|
|
106
216
|
// columns ∂D/∂x and ∂D/∂z: (∂Dx/∂x, ∂Dz/∂x), (∂Dx/∂z, ∂Dz/∂z)
|
|
107
217
|
jacobian: mat2x2<f32>,
|
|
218
|
+
// the gradient of the displacement's signed length along the radius: the slope a quarter carrier cycle on, so that
|
|
219
|
+
// ½(|slope|² + |this|²) is the slope's mean square over a cycle
|
|
220
|
+
displacement_gradient: vec2<f32>,
|
|
108
221
|
}
|
|
109
222
|
|
|
110
|
-
// The packet at offset d from its particle
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
223
|
+
// The packet at offset d from its particle, which stands distance from its front's centre. ρ the radius from the
|
|
224
|
+
// centre and u = ρ − distance across the front, ψ the angle around the centre from the particle's direction:
|
|
225
|
+
// envelope E(u) over half_length either side, window T(ψ) over the dispersion β either side, carrier phase πu/r − phase.
|
|
226
|
+
// Height a·E·T·cos; horizontal displacement −a·E·T·sin along the radius (Gerstner-like orbits, Yuksel's longitudinal
|
|
227
|
+
// sign); with derivatives, ∇ψ = e_ψ/ρ.
|
|
228
|
+
fn water_particle_field(d: vec2<f32>, angle: f32, amplitude: f32, radius: f32, half_length: f32, dispersion: f32, distance: f32,
|
|
229
|
+
phase: f32) -> WaterParticleField {
|
|
114
230
|
var field: WaterParticleField;
|
|
115
231
|
let direction = water_particle_direction(angle);
|
|
116
232
|
let tangent = vec2<f32>(-direction.y, direction.x);
|
|
117
|
-
let
|
|
118
|
-
let
|
|
119
|
-
|
|
120
|
-
let
|
|
233
|
+
let q = d + direction * distance;
|
|
234
|
+
let rho = length(q);
|
|
235
|
+
// ρ − distance, without the cancellation
|
|
236
|
+
let u = (dot(d, d) + 2.0 * distance * dot(d, direction)) / max(rho + distance, 1e-30);
|
|
237
|
+
if (abs(u) >= half_length || !(rho > 0.0)) { return field; }
|
|
238
|
+
let psi = atan2(dot(d, tangent), distance + dot(d, direction));
|
|
239
|
+
if (abs(psi) >= dispersion) { return field; }
|
|
240
|
+
let radial = q / rho;
|
|
241
|
+
let around = vec2<f32>(-radial.y, radial.x);
|
|
242
|
+
let eu = WATER_PI * u / half_length;
|
|
121
243
|
let envelope = 0.5 * (1.0 + cos(eu));
|
|
122
|
-
let envelope_du = -0.
|
|
123
|
-
let tv = WATER_PI *
|
|
244
|
+
let envelope_du = -0.5 * WATER_PI / half_length * sin(eu);
|
|
245
|
+
let tv = WATER_PI * psi / dispersion;
|
|
124
246
|
let window = 0.5 * (1.0 + cos(tv));
|
|
125
|
-
let
|
|
247
|
+
let window_dpsi = -0.5 * WATER_PI / dispersion * sin(tv);
|
|
126
248
|
let carrier = WATER_PI * u / radius - phase;
|
|
127
249
|
let c = cos(carrier);
|
|
128
250
|
let s = sin(carrier);
|
|
129
251
|
let k = WATER_PI / radius;
|
|
130
252
|
let z = amplitude * envelope * window * c;
|
|
131
253
|
let z_u = amplitude * window * (envelope_du * c - envelope * s * k);
|
|
132
|
-
let
|
|
254
|
+
let z_psi = amplitude * envelope * window_dpsi * c;
|
|
133
255
|
let h = -amplitude * envelope * window * s;
|
|
134
256
|
let h_u = -amplitude * window * (envelope_du * s + envelope * c * k);
|
|
135
|
-
let
|
|
136
|
-
let gradient_h = h_u *
|
|
257
|
+
let h_psi = -amplitude * envelope * window_dpsi * s;
|
|
258
|
+
let gradient_h = h_u * radial + (h_psi / rho) * around;
|
|
259
|
+
// the radius turns as the point moves around the centre: ∂e_ρ/∂x_j = e_ψ (e_ψ)_j / ρ
|
|
260
|
+
let turn = (h / rho) * around;
|
|
137
261
|
field.height = z;
|
|
138
|
-
field.slope = z_u *
|
|
139
|
-
field.displacement = h *
|
|
140
|
-
field.jacobian = mat2x2<f32>(
|
|
262
|
+
field.slope = z_u * radial + (z_psi / rho) * around;
|
|
263
|
+
field.displacement = h * radial;
|
|
264
|
+
field.jacobian = mat2x2<f32>(radial * gradient_h.x + turn * around.x, radial * gradient_h.y + turn * around.y);
|
|
265
|
+
field.displacement_gradient = gradient_h;
|
|
141
266
|
return field;
|
|
142
267
|
}
|
|
143
268
|
`, [chunk_water_spectrum, chunk_pcg3d, WATER_PARTICLE_STRUCT.declaration_chunk, WATER_PARTICLE_ENTRY_STRUCT.declaration_chunk]);
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
export const WATER_PARTICLE_FADE_SECONDS: 0.15;
|
|
3
3
|
/**
|
|
4
4
|
* One frame of one wave particle (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §5.1): it ages, spreads over its
|
|
5
|
-
* widening front, damps,
|
|
5
|
+
* widening front, damps, meets its body's authored outline, and dies or splits.
|
|
6
|
+
*
|
|
7
|
+
* At the outline the water shows the packet plus the shore's share of its mirror image in the outline (the image
|
|
8
|
+
* method, as Jeschke & Wojtan 2017 §4.4 keep a "ghost" of a reflected packet): the image is emitted the step the first
|
|
9
|
+
* of the packet's support leaves the body, and the packet carries on until the last of it has left it too. The body's
|
|
10
|
+
* outline clips what of either lies beyond it, so the water changes only as the two move.
|
|
6
11
|
*
|
|
7
12
|
* Whether a point is over the body is a down-ray into the body's own BLAS, so the outline is exactly the
|
|
8
13
|
* authored mesh's, holes for islands included. Bindings: `geometries`, `blas_lookup`, `blas_data`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_water_particle_step.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/chunk_water_particle_step.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_water_particle_step.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/chunk_water_particle_step.js"],"names":[],"mappings":"AAQA,qHAAqH;AACrH,+CAAgD;AAEhD;;;;;;;;;;;;;;GAcG;AACH,wCAFU,SAAS,CAsN8E;0BA9OvE,uCAAuC"}
|