@woosh/meep-engine 3.41.0 → 3.42.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/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/selection/editor_pick.d.ts.map +1 -1
- package/editor/selection/editor_pick.js +2 -1
- package/editor/tools/TransformToolV2.d.ts.map +1 -1
- package/editor/tools/TransformToolV2.js +7 -1
- package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
- package/editor/tools/engine/ToolEngine.js +10 -0
- package/editor/tools/v2/TransformControls.d.ts.map +1 -1
- package/editor/tools/v2/TransformControls.js +7 -20
- package/editor/tools/v2/handle/gizmo_drag_plane.d.ts.map +1 -1
- package/editor/tools/v2/handle/gizmo_drag_plane.js +4 -0
- package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
- package/editor/view/ecs/EntityEditor.js +3 -1
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.js +28 -12
- package/package.json +1 -1
- package/samples/engine/first-scene/index.html +4 -1
- package/samples/engine/first-scene/main.js +14 -9
- package/src/core/binary/utf8/utf8_decode.js +3 -3
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.d.ts.map +1 -1
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +112 -113
- package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js +2 -2
- package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +14 -14
- package/src/core/collection/RingBuffer.d.ts.map +1 -1
- package/src/core/collection/RingBuffer.js +4 -0
- package/src/core/collection/array/array_contains_duplicates.d.ts.map +1 -1
- package/src/core/collection/array/array_contains_duplicates.js +2 -1
- package/src/core/collection/array/array_copy.d.ts.map +1 -1
- package/src/core/collection/array/array_copy.js +23 -0
- package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts +2 -2
- package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts.map +1 -1
- package/src/core/collection/array/typed/sparse_typed_array_hash.js +9 -8
- package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -2
- package/src/core/collection/array/typed/uint16_array_hash.js +4 -4
- package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -2
- package/src/core/collection/array/typed/uint8_array_hash.js +4 -4
- package/src/core/collection/array/weightedRandomFromArray.d.ts +1 -0
- package/src/core/collection/array/weightedRandomFromArray.d.ts.map +1 -1
- package/src/core/collection/array/weightedRandomFromArray.js +9 -1
- package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
- package/src/core/collection/heap/BinaryHeap.js +4 -0
- package/src/core/collection/list/List.d.ts.map +1 -1
- package/src/core/collection/list/List.js +4 -2
- package/src/core/collection/set/ArraySet.js +1 -1
- package/src/core/collection/set/HashSet.d.ts +1 -1
- package/src/core/collection/set/HashSet.d.ts.map +1 -1
- package/src/core/collection/set/HashSet.js +4 -2
- package/src/core/debug/matchers/IsEqual.js +1 -1
- package/src/core/debug/matchers/IsIterableContaining.d.ts.map +1 -1
- package/src/core/debug/matchers/IsIterableContaining.js +61 -74
- package/src/core/events/signal/SignalBinding.js +101 -101
- package/src/core/function/extractFunctionBody.js +13 -13
- package/src/core/function/objectsEqual.d.ts.map +1 -1
- package/src/core/function/objectsEqual.js +15 -14
- package/src/core/geom/3d/frustum/frustum3_compute_closest_point.d.ts.map +1 -1
- package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +207 -172
- package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -1
- package/src/core/geom/3d/gjk/gjk_epa_penetration.js +5 -4
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +8 -2
- package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts +20 -0
- package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
- package/src/core/geom/3d/triangle/tri3_ray_intersection.js +182 -0
- package/src/core/math/noise/curl_noise_3dt.d.ts.map +1 -1
- package/src/core/math/noise/curl_noise_3dt.js +20 -10
- package/src/core/math/noise/sdnoise.d.ts +16 -5
- package/src/core/math/noise/sdnoise.d.ts.map +1 -1
- package/src/core/math/noise/sdnoise.js +43 -9
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -1
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_nearest_point.js +44 -3
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +6 -2
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +9 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +26 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +2 -0
- package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/AbilitySet.js +9 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/LedgeGrab.js +6 -0
- package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/Slide.js +1 -0
- package/src/engine/control/first-person/abilities/WallRun.d.ts +4 -1
- package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/WallRun.js +13 -1
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +1 -1
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -1
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +6 -5
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +3 -3
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -1
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +9 -8
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +13 -4
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +18 -15
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.js +2 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.js +1 -0
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +3 -0
- package/src/engine/ecs/parent/EntityNode.js +3 -3
- package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
- package/src/engine/ecs/speaker/VoiceSystem.js +4 -0
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +5 -5
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +3 -2
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +1 -1
- package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +8 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +8 -0
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +5 -2
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +3 -0
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -0
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +13 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +1 -0
- package/src/engine/graphics/ecs/light/LightSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/light/LightSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts +5 -0
- package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.js +27 -0
- package/src/engine/graphics/ecs/water/Water.d.ts +11 -0
- package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/Water.js +17 -0
- package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +3 -1
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts +9 -0
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts.map +1 -0
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.js +24 -0
- package/src/engine/graphics/ecs/water/WaterWaves.d.ts +30 -9
- package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterWaves.js +41 -9
- package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +30 -26
- package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts +6 -0
- package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.js +22 -0
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.d.ts.map +1 -1
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +3 -5
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +20 -0
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -1
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +36 -0
- package/src/engine/graphics3/WaterSystem.d.ts +12 -3
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +78 -46
- package/src/engine/input/devices/PointerDevice.d.ts.map +1 -1
- package/src/engine/input/devices/PointerDevice.js +29 -4
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts +1 -0
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +14 -3
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +12 -3
- package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +8 -2
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts +19 -0
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +41 -2
- package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +9 -3
- package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +26 -10
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +3 -6
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +22 -9
- package/src/engine/ui/DraggableAspect.d.ts +5 -1
- package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
- package/src/engine/ui/DraggableAspect.js +61 -4
- package/src/format/image/avif/heif/ItemProperty.d.ts +1 -1
- package/src/format/image/avif/heif/ItemProperty.js +1 -1
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +17 -6
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts +2 -4
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUDevice.js +20 -13
- package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/sweep_views.js +2 -1
- package/src/shade/playground/water_refraction/README.md +10 -11
- package/src/shade/playground/water_refraction/main.js +9 -8
- package/src/shade/playground/water_refraction/world.js +1 -1
- package/src/shade/playground/water_surface/README.md +43 -0
- package/src/shade/playground/water_surface/index.html +30 -0
- package/src/shade/playground/water_surface/main.d.ts +2 -0
- package/src/shade/playground/water_surface/main.d.ts.map +1 -0
- package/src/shade/playground/water_surface/main.js +154 -0
- package/src/shade/playground/water_surface/world.d.ts +44 -0
- package/src/shade/playground/water_surface/world.d.ts.map +1 -0
- package/src/shade/playground/water_surface/world.js +160 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +5 -0
- package/src/shade/renderer/binding/BufferBinding.js +2 -2
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +5 -3
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +10 -3
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +17 -9
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +3 -0
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +16 -0
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +2 -0
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +11 -0
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +9 -3
- package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.d.ts.map +1 -1
- package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.js +2 -2
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +85 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +12 -6
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +7 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +3 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +2 -1
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.js +42 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts +15 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.js +39 -0
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +2 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts +15 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +110 -30
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +16 -8
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +31 -26
- package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts +0 -1
- package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/shader_water_meshlets.js +1 -39
- package/src/shade/renderer/water/shader_water.d.ts +0 -1
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +201 -72
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts +70 -0
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/GPUWaterSurface.js +199 -0
- package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +5 -2
- package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +32 -12
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +22 -0
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +217 -0
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +65 -11
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +163 -28
- package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts +51 -0
- package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/WATER_LOD.js +95 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts +10 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod.js +127 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts +17 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.js +246 -0
- package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts +118 -0
- package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/shader_water_lod.js +727 -0
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts +60 -0
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +228 -0
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts +17 -0
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +49 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +22 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +143 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +15 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +121 -0
- package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +83 -0
- package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/shader_water_particles.js +502 -0
- package/src/shade/renderer/water/surface/shader_water_cull.d.ts +42 -0
- package/src/shade/renderer/water/surface/shader_water_cull.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/shader_water_cull.js +269 -0
- package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts +15 -0
- package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/shader_water_waves_combine.js +73 -0
- package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts +11 -0
- package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/shader_water_waves_derive.js +78 -0
- package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts +35 -0
- package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.js +103 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts +22 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.js +57 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts +22 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.js +25 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts +14 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.js +48 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts +23 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.js +169 -0
- package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts +26 -0
- package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.js +161 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +18 -6
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +11 -3
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts +0 -28
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts.map +0 -1
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +0 -86
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts +0 -29
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts.map +0 -1
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +0 -44
- package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +0 -4
- package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +0 -1
- package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +0 -32
- package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +0 -25
- package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +0 -128
- package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts +0 -9
- package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/chunk_water_tessellation.js +0 -144
- package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +0 -13
- package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/chunk_water_wave.js +0 -40
- package/src/shade/renderer/water/surface/shader_water_tiles.d.ts +0 -4
- package/src/shade/renderer/water/surface/shader_water_tiles.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/shader_water_tiles.js +0 -123
- package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts +0 -6
- package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/shader_water_wave_batch.js +0 -85
- package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts +0 -6
- package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/shader_water_wave_domain.js +0 -83
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** A view's water bodies: which the view draws and how, and their meshlets in row order. */
|
|
2
2
|
export class GPUWaterBodies {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Draw culling over the frame's visible list (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §4.3), each drawn
|
|
5
|
+
* body's lattice frame at its row, and the drawn bodies' meshlets. The expansion is an ordered prefix scan over the
|
|
6
|
+
* rows, which preserves equal-depth ownership, including after holes and reuse.
|
|
7
|
+
*
|
|
8
|
+
* @returns {{meshlets: number, lod_bodies: number}} resources
|
|
9
|
+
*/
|
|
10
|
+
meshlets({ graph, view, camera, meshlet_capacity, visible_rows, lod, steep }: {
|
|
9
11
|
graph: any;
|
|
10
12
|
view: any;
|
|
11
13
|
camera: any;
|
|
12
14
|
meshlet_capacity: any;
|
|
13
|
-
|
|
15
|
+
visible_rows: any;
|
|
16
|
+
lod: any;
|
|
17
|
+
steep: any;
|
|
18
|
+
}): {
|
|
19
|
+
meshlets: number;
|
|
20
|
+
lod_bodies: number;
|
|
21
|
+
};
|
|
14
22
|
}
|
|
15
23
|
//# sourceMappingURL=GPUWaterBodies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUWaterBodies.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/medium/GPUWaterBodies.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUWaterBodies.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/medium/GPUWaterBodies.js"],"names":[],"mappings":"AAcA,4FAA4F;AAC5F;IACI;;;;;;OAMG;IACH;;;;;;;;QAFa;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,CA8ClD;CACJ"}
|
|
@@ -1,42 +1,47 @@
|
|
|
1
1
|
import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
|
|
2
2
|
import { round_up } from "../../../../core/math/round_up.js";
|
|
3
3
|
import { graph_prefix_scan_csdldf } from "../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
build_indirect_compute_dispatch_command,
|
|
6
|
+
INDIRECT_COMPUTE_COMMAND_DESCRIPTOR
|
|
7
|
+
} from "../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
|
|
5
8
|
import { shader_prefix_sum_to_command } from "../../rasterize/expand/mesh/shader_prefix_sum_to_command.js";
|
|
6
9
|
import { shader_increment_count_by_prefix_sum } from "../../rasterize/expand/mesh/shader_increment_count_by_prefix_sum.js";
|
|
7
10
|
import { graph_compute_pass } from "../../shader/graph/compute/graph_compute_pass.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
11
|
+
import { shader_water_meshlets_expand } from "./shader_water_meshlets.js";
|
|
12
|
+
import { shader_water_lod_bodies } from "../surface/lod/shader_water_lod.js";
|
|
13
|
+
import { WATER_LOD_BODY_STRUCT, WATER_LOD_VIEW_STRUCT } from "../surface/lod/WATER_LOD.js";
|
|
10
14
|
|
|
11
|
-
/**
|
|
15
|
+
/** A view's water bodies: which the view draws and how, and their meshlets in row order. */
|
|
12
16
|
export class GPUWaterBodies {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
pass.make_side_effect();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Ordered prefix expansion preserves equal-depth ownership, including after holes and reuse. */
|
|
25
|
-
meshlets({ graph, view, camera, meshlet_capacity }) {
|
|
17
|
+
/**
|
|
18
|
+
* Draw culling over the frame's visible list (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §4.3), each drawn
|
|
19
|
+
* body's lattice frame at its row, and the drawn bodies' meshlets. The expansion is an ordered prefix scan over the
|
|
20
|
+
* rows, which preserves equal-depth ownership, including after holes and reuse.
|
|
21
|
+
*
|
|
22
|
+
* @returns {{meshlets: number, lod_bodies: number}} resources
|
|
23
|
+
*/
|
|
24
|
+
meshlets({ graph, view, camera, meshlet_capacity, visible_rows, lod, steep }) {
|
|
26
25
|
const scene = view.scene, table = scene.scene_database.get('water_bodies');
|
|
27
|
-
const capacity = table.element_capacity;
|
|
26
|
+
const capacity = Math.max(table.element_capacity, 1);
|
|
28
27
|
const data = {};
|
|
29
|
-
const pass = graph.add('Water /
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
const pass = graph.add('Water / lod bodies', data, (d, resources, { encoder }) => {
|
|
29
|
+
const command = resources.get(d.command);
|
|
30
|
+
build_indirect_compute_dispatch_command(64, encoder, visible_rows, 0, command, 0, true);
|
|
31
|
+
shader_water_lod_bodies.dispatchIndirect({ encoder, command, bindings: {
|
|
32
|
+
capacity: round_up(capacity, 4), lod: encoder.allocateTransientValueBuffer(WATER_LOD_VIEW_STRUCT, lod),
|
|
33
|
+
camera: resources.get(d.camera), scene_database: scene.scene_database_buffer,
|
|
34
|
+
geometries: scene.geometries.buffer_metadata, visible_rows, steep,
|
|
35
|
+
lod_bodies: resources.get(d.lod_bodies), counts: resources.get(d.counts),
|
|
36
|
+
} });
|
|
35
37
|
});
|
|
36
38
|
data.camera = pass.read(camera);
|
|
37
39
|
// The shared scan reads vec4u blocks, including the padded final block.
|
|
38
40
|
const bytes = 16 + round_up(capacity, 4) * 4;
|
|
39
41
|
data.counts = pass.create('counts', BufferResourceDescriptor.from(bytes, GPUBufferUsage.STORAGE, 0, bytes));
|
|
42
|
+
data.command = pass.create('Water lod bodies command', INDIRECT_COMPUTE_COMMAND_DESCRIPTOR);
|
|
43
|
+
data.lod_bodies = pass.create('Water lod bodies', BufferResourceDescriptor.from(capacity * WATER_LOD_BODY_STRUCT.size,
|
|
44
|
+
GPUBufferUsage.STORAGE));
|
|
40
45
|
const sums = graph_prefix_scan_csdldf({ graph, data: data.counts, element_max_count: capacity });
|
|
41
46
|
const command_data = {};
|
|
42
47
|
const command_pass = graph.add('Water / expand command', command_data, (d, resources, { encoder }) => {
|
|
@@ -55,10 +60,10 @@ export class GPUWaterBodies {
|
|
|
55
60
|
});
|
|
56
61
|
expand_data.command = expand.read(command);
|
|
57
62
|
expand_data.sums = expand.read(sums);
|
|
58
|
-
expand_data.output = expand.create('meshlets', BufferResourceDescriptor.from(16 + meshlet_capacity * 8,
|
|
63
|
+
expand_data.output = expand.create('meshlets', BufferResourceDescriptor.from(16 + Math.max(meshlet_capacity, 1) * 8,
|
|
59
64
|
GPUBufferUsage.STORAGE, 0, 16));
|
|
60
65
|
const { output } = graph_compute_pass({ graph, shader: shader_increment_count_by_prefix_sum,
|
|
61
66
|
bindings: { prefix_sums: sums, output: expand_data.output } });
|
|
62
|
-
return output;
|
|
67
|
+
return { meshlets: output, lod_bodies: data.lod_bodies };
|
|
63
68
|
}
|
|
64
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_water_meshlets.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/medium/shader_water_meshlets.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_water_meshlets.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/medium/shader_water_meshlets.js"],"names":[],"mappings":"AAgBA,yDAcsF;8BA3BxD,+BAA+B"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
2
1
|
import { GEOMETRY_METADATA_STRUCT } from "../../geometry/GEOMETRY_METADATA_STRUCT.js";
|
|
3
2
|
import { MESHLET_COLLECTION_STRUCT } from "../../rasterize/MESHLET_COLLECTION_STRUCT.js";
|
|
4
3
|
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
@@ -6,46 +5,9 @@ import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
|
6
5
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
7
6
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
8
7
|
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
9
|
-
import { chunk_scene_database_access } from "../../scene/chunk_scene_database_access.js";
|
|
10
8
|
import { chunk_folded_workgroup_index } from "../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
11
9
|
import { chunk_lower_bound_branchless } from "../../shader/chunk/math/chunk_lower_bound_branchless.js";
|
|
12
|
-
import { WATER_BODIES_TABLE as table
|
|
13
|
-
import { chunk_aabb3_project } from "../../shader/chunk/geometry/aabb3/chunk_aabb3_project.js";
|
|
14
|
-
import { chunk_aabb3_intersects_frustum } from "../../shader/chunk/geometry/aabb3/chunk_aabb3_intersects_frustum.js";
|
|
15
|
-
import { chunk_array_to_aabb3 } from "../../shader/chunk/geometry/aabb3/chunk_array_to_aabb3.js";
|
|
16
|
-
import { chunk_mat4_linear_determinant } from "../../shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js";
|
|
17
|
-
import { u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
18
|
-
|
|
19
|
-
const pg = table.page_iterator_symbol_prefix(64);
|
|
20
|
-
const counts_resources = new ShaderResourceSetDescriptor();
|
|
21
|
-
counts_resources.setImmediate('capacity', u32);
|
|
22
|
-
counts_resources.createGroup().addUniform('camera', CAMERA_UNIFORM_STRUCT)
|
|
23
|
-
.addStorageBuffer('scene_database', WebGPUArray.u32)
|
|
24
|
-
.addStorageBuffer('geometries', WebGPUArray.from(GEOMETRY_METADATA_STRUCT))
|
|
25
|
-
.addStorageBuffer('counts', COLLECTION_U32_STRUCT_READ, true);
|
|
26
|
-
export const shader_water_meshlet_counts = ComputeShader.from({ label: 'Water / meshlet counts', resources: counts_resources,
|
|
27
|
-
body: CodeChunk.from(/* language=WGSL */ `
|
|
28
|
-
@compute @workgroup_size(64)
|
|
29
|
-
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
30
|
-
if (all(group == vec3u(0)) && lane == 0u) { counts.count = capacity; }
|
|
31
|
-
if (!${pg}_setup(&scene_database, folded_workgroup_index(group), lane)) { return; }
|
|
32
|
-
let slot = ${pg}_slot_in_page(lane);
|
|
33
|
-
if (slot >= ${pg}_ELEMENTS_PER_PAGE || !${pg}_is_occupied(slot)) { return; }
|
|
34
|
-
let body = ${pg}_read(&scene_database, slot);
|
|
35
|
-
let geometry = geometries[body.geometry];
|
|
36
|
-
let node = scene_read_node(&scene_database, body.node);
|
|
37
|
-
if (abs(mat4_linear_determinant(node.global)) < 1e-20) { return; }
|
|
38
|
-
var box = geometry.bounding_box;
|
|
39
|
-
if (body.wave != ~0u) {
|
|
40
|
-
let displacement = ${WATER_WAVES_TABLE.marshalling_method_read}(&scene_database, body.wave).displacement_bounds;
|
|
41
|
-
box[1] += displacement.x; box[4] += displacement.y;
|
|
42
|
-
}
|
|
43
|
-
let bounds = aabb3_project(array_to_aabb3(box), node.global);
|
|
44
|
-
if (!aabb3_intersects_frustum(bounds, camera.frustum)) { return; }
|
|
45
|
-
counts.elements[${pg}_slot_to_index(slot)] = geometry.meshlets_count;
|
|
46
|
-
}
|
|
47
|
-
`, [table.chunk_iterate(64), WATER_WAVES_TABLE.chunk_read, chunk_scene_database_access, chunk_folded_workgroup_index,
|
|
48
|
-
chunk_aabb3_project, chunk_array_to_aabb3, chunk_aabb3_intersects_frustum, chunk_mat4_linear_determinant]) });
|
|
10
|
+
import { WATER_BODIES_TABLE as table } from "./chunk_water_bodies.js";
|
|
49
11
|
|
|
50
12
|
const expand_resources = new ShaderResourceSetDescriptor();
|
|
51
13
|
expand_resources.createGroup().addStorageBuffer('prefix_sums', COLLECTION_U32_STRUCT_READ)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export function create_water_pipeline(): RenderPipelineDescriptor;
|
|
2
2
|
export function create_water_finalize_pipeline_ibl(): RenderPipelineDescriptor;
|
|
3
3
|
export function create_water_finalize_pipeline_brick4(): RenderPipelineDescriptor;
|
|
4
|
-
export const WATER_GRID_STRUCT: WebGPUStruct;
|
|
5
4
|
export const WATER_TRACE_STRUCT: WebGPUStruct;
|
|
6
5
|
/** Optics under IBL (and LPV, which has no transparent variant): the lights and the environment. */
|
|
7
6
|
export const WATER_FINALIZE_RESOURCES_IBL: ShaderResourceSetDescriptor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_water.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/water/shader_water.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_water.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/water/shader_water.js"],"names":[],"mappings":"AAwmBA,kEAAuH;AACvH,+EAA+J;AAC/J,kFAAqK;AA/jBrK,8CAKwB;AAiCxB,oGAAoG;AACpG,uEAAkE;AAGlE,gGAAgG;AAChG,0EAAqE;AAqOrE,+CA+EmB;AA6LnB,4CAAmG;AACnG,kFAAkF;AAClF,yDAC8G;AAC9G,oCAAoC;AACpC,4DACoH;AACpH,0DAAyC;yCA5kBA,8DAA8D;6BAmB1E,gCAAgC;4CAJjB,mDAAmD;0BADrE,iCAAiC;iCAE1B,+BAA+B"}
|
|
@@ -25,8 +25,12 @@ import { chunk_water_gi_brick4, chunk_water_gi_ibl } from "./chunk_water_gi.js";
|
|
|
25
25
|
import { WATER_BODIES_TABLE, WATER_WAVES_TABLE } from "./medium/chunk_water_bodies.js";
|
|
26
26
|
import { MESHLET_METADATA_STRUCT } from "../geometry/meshlet/encoding/MESHLET_METADATA_STRUCT.js";
|
|
27
27
|
import { COLLECTION_U32_STRUCT_READ } from "../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
28
|
+
import { chunk_water_surface_sample } from "./surface/chunk_water_surface_sample.js";
|
|
29
|
+
import { WATER_PARTICLE_ENTRY_STRUCT } from "./surface/particles/WATER_PARTICLE_STRUCT.js";
|
|
30
|
+
import { WATER_LOD_BODY_STRUCT, WATER_LOD_VIEW_STRUCT, WaterLodMode } from "./surface/lod/WATER_LOD.js";
|
|
31
|
+
import { chunk_water_lod_candidate, chunk_water_lod_layout, WATER_LOD_BOUNDARY_FIRST_VERTEX, WATER_LOD_CANDIDATE_STRUCT,
|
|
32
|
+
WATER_LOD_CELL_LOCAL_BITS, WATER_LOD_LIMITS_STRUCT, WATER_LOD_PATCH_FIRST_VERTEX, WATER_LOD_PATCH_SIDE, WATER_LOD_POLYGON_WORDS,
|
|
33
|
+
WATER_LOD_TRIANGLE_FIRST_VERTEX, WaterLodList } from "./surface/lod/shader_water_lod.js";
|
|
30
34
|
import { chunk_read_meshlet_vertex_by_draw_index } from "../shader/chunk/geometry/meshlet/chunk_read_meshlet_vertex_by_draw_index.js";
|
|
31
35
|
import { chunk_scene_database_access } from "../scene/chunk_scene_database_access.js";
|
|
32
36
|
import { chunk_mat3_inverse } from "../shader/chunk/geometry/mat3/chunk_mat3_inverse.js";
|
|
@@ -37,8 +41,6 @@ import { chunk_water_optics } from "./optics/chunk_water_optics.js";
|
|
|
37
41
|
import { chunk_water_receiver_radiance, chunk_water_receiver_texel, chunk_water_refraction_confidence,
|
|
38
42
|
chunk_water_transport, WATER_LEVEL_TOLERANCE_DECLARATION } from './chunk_water_transport.js';
|
|
39
43
|
|
|
40
|
-
export const WATER_GRID_STRUCT = WebGPUStruct.from({ resolution: u32 }, 'WaterGrid');
|
|
41
|
-
|
|
42
44
|
export const WATER_TRACE_STRUCT = WebGPUStruct.from({
|
|
43
45
|
max_distance: f32, distance_tolerance: f32, max_updates: u32, fallback_steps: u32,
|
|
44
46
|
mode: u32, reflections: u32,
|
|
@@ -56,13 +58,20 @@ function water_resources(finalize = false) {
|
|
|
56
58
|
.addTexture("tHZB")
|
|
57
59
|
.addTexture("tScene")
|
|
58
60
|
.addStorageBuffer('scene_database', WebGPUArray.u32)
|
|
59
|
-
|
|
60
|
-
.
|
|
61
|
-
.addUniform('
|
|
61
|
+
// the view's lattice (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §4.3)
|
|
62
|
+
.addUniform('lod', WATER_LOD_VIEW_STRUCT)
|
|
63
|
+
.addUniform('lod_limits', WATER_LOD_LIMITS_STRUCT)
|
|
64
|
+
.addStorageBuffer('water_lod_bodies', WebGPUArray.from(WATER_LOD_BODY_STRUCT))
|
|
65
|
+
.addStorageBuffer('water_lod_candidates', WebGPUArray.from(WATER_LOD_CANDIDATE_STRUCT))
|
|
66
|
+
.addStorageBuffer('water_lod_cells', WebGPUArray.u32)
|
|
62
67
|
.addStorageBuffer('meshlet_metadata', WebGPUArray.from(MESHLET_METADATA_STRUCT))
|
|
63
68
|
.addStorageBuffer('meshlet_data', WebGPUArray.from(f32))
|
|
64
|
-
|
|
65
|
-
.
|
|
69
|
+
// the surface interface: the spectral bands and the frame's binned wave particles
|
|
70
|
+
.addTexture('water_band_displacement', 'float', '2d-array')
|
|
71
|
+
.addTexture('water_band_derivatives', 'float', '2d-array')
|
|
72
|
+
.addSampler('water_band_sampler')
|
|
73
|
+
.addStorageBuffer('water_particle_offsets', COLLECTION_U32_STRUCT_READ)
|
|
74
|
+
.addStorageBuffer('water_particle_entries', WebGPUArray.from(WATER_PARTICLE_ENTRY_STRUCT));
|
|
66
75
|
if (finalize) {
|
|
67
76
|
group.addTexture('receiver').addTexture('trace_metadata').addTexture('visibility_distance');
|
|
68
77
|
}
|
|
@@ -88,79 +97,194 @@ struct WaterVertexOut {
|
|
|
88
97
|
// makes the position bit-identical across programs.
|
|
89
98
|
@invariant @builtin(position) clip: vec4<f32>,
|
|
90
99
|
@location(0) world: vec3<f32>,
|
|
100
|
+
// the normal of the waves the mesh carries
|
|
91
101
|
@location(1) normal: vec3<f32>,
|
|
92
|
-
// slope variance of the
|
|
102
|
+
// slope variance of the wave packets the mesh does not resolve; the bands' is the pixel's to work out
|
|
93
103
|
@location(2) unresolved_variance: f32,
|
|
94
104
|
@location(3) @interpolate(flat) body_index: u32,
|
|
95
105
|
@location(4) rest_normal: vec3<f32>,
|
|
106
|
+
// where on the body's rest surface this is, metric local xz, and the footprint its waves were filtered to there:
|
|
107
|
+
// what the pixel samples the bands the mesh could not carry at; 0 where no waves move the surface
|
|
108
|
+
@location(5) metric: vec2<f32>,
|
|
109
|
+
@location(6) footprint: f32,
|
|
110
|
+
@location(7) @interpolate(flat) wave: u32,
|
|
111
|
+
// the body's metric x and z axes in the world, to tilt the normal along
|
|
112
|
+
@location(8) @interpolate(flat) axis_x: vec3<f32>,
|
|
113
|
+
@location(9) @interpolate(flat) axis_z: vec3<f32>,
|
|
114
|
+
// the metres a pixel spans on the rest surface: its distance times its angle, stretched where the surface is seen
|
|
115
|
+
// at a slant (the mean of its two axes)
|
|
116
|
+
@location(10) pixel_footprint: f32,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fn water_vertex_out_none(body_index: u32) -> WaterVertexOut {
|
|
120
|
+
return WaterVertexOut(vec4f(0, 0, 0, 1), vec3f(0), vec3f(0, 1, 0), 0.0, body_index, vec3f(0, 1, 0), vec2f(0), 0.0, 0u,
|
|
121
|
+
vec3f(1, 0, 0), vec3f(0, 0, 1), 0.0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
struct WaterPixelSurface {
|
|
125
|
+
normal: vec3<f32>,
|
|
126
|
+
variance: f32,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// The surface a pixel shades: the mesh's normal tilted by the bands the pixel resolves and the mesh could not carry;
|
|
130
|
+
// the slope variance of the bands neither resolves, and of the packets the mesh did not draw.
|
|
131
|
+
fn water_pixel_surface(in: WaterVertexOut, pixel_footprint: f32) -> WaterPixelSurface {
|
|
132
|
+
if (!(in.footprint > 0.0)) { return WaterPixelSurface(in.normal, in.unresolved_variance); }
|
|
133
|
+
let detail = water_surface_detail(in.wave, in.metric, in.footprint, pixel_footprint);
|
|
134
|
+
let normal = normalize(in.normal - detail.slope.x * in.axis_x - detail.slope.y * in.axis_z);
|
|
135
|
+
return WaterPixelSurface(normal, in.unresolved_variance + detail.variance);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// The rest point a vertex of the view's lattice stands for, and how it is drawn.
|
|
139
|
+
struct WaterLodVertex {
|
|
140
|
+
// local units
|
|
141
|
+
rest: WaterLodRest,
|
|
142
|
+
// metric local xz, where the waves are sampled
|
|
143
|
+
metric: vec2<f32>,
|
|
144
|
+
// metres between samples the waves are filtered to; 0 for a vertex the waves do not move
|
|
145
|
+
footprint: f32,
|
|
146
|
+
present: bool,
|
|
96
147
|
}
|
|
97
148
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
149
|
+
const WATER_LOD_QUAD: array<u32, 6> = array<u32, 6>(0u, 1u, 2u, 0u, 2u, 3u);
|
|
150
|
+
const WATER_LOD_QUAD_REVERSED: array<u32, 6> = array<u32, 6>(0u, 2u, 1u, 0u, 3u, 2u);
|
|
151
|
+
|
|
152
|
+
// A lattice point of a cell drawn whole: on the triangle's surface, along an authored edge where it lies on one.
|
|
153
|
+
fn water_lod_whole_point(level: u32, point: vec2<i32>, frame: ${WATER_LOD_BODY_STRUCT.wgsl_ref}, tri: WaterLodTriangle) -> WaterLodVertex {
|
|
154
|
+
var out: WaterLodVertex;
|
|
155
|
+
let p = water_lod_lattice_point(lod, frame, level, point);
|
|
156
|
+
out.rest = water_lod_rest(tri, water_lod_edge_bits(tri, p), p, frame.scale);
|
|
157
|
+
out.metric = p;
|
|
158
|
+
out.footprint = water_lod_footprint(lod, frame, level, p);
|
|
159
|
+
out.present = true;
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
fn water_lod_vertex(list: u32, corner: u32, candidate: ${WATER_LOD_CANDIDATE_STRUCT.wgsl_ref}, place: u32,
|
|
164
|
+
frame: ${WATER_LOD_BODY_STRUCT.wgsl_ref}, tri: WaterLodTriangle, mirrored: bool, polygon: vec2<u32>) -> WaterLodVertex {
|
|
165
|
+
var out: WaterLodVertex;
|
|
166
|
+
let packed = candidate.packed;
|
|
167
|
+
if (list == ${WaterLodList.Triangle}u) {
|
|
168
|
+
// the authored triangle itself, wound as authored
|
|
169
|
+
let k = select(corner, 2u - corner, mirrored);
|
|
170
|
+
out.rest = WaterLodRest(tri.local[k], tri.normal[k]);
|
|
171
|
+
out.metric = tri.p[k];
|
|
172
|
+
out.present = true;
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
let level = water_lod_candidate_level(packed);
|
|
176
|
+
if (place >= 256u) { return out; }
|
|
177
|
+
// the cell's place in its node: quadrant · 64 + row · 8 + column
|
|
178
|
+
let cell = water_lod_quadrant_origin(candidate.node, place >> 6u) + vec2<i32>(i32(place & 7u), i32((place >> 3u) & 7u));
|
|
179
|
+
// a cell's corners run counter-clockwise from x towards z; the authored triangle may run the other way, and a
|
|
180
|
+
// mirroring placement turns both
|
|
181
|
+
let reversed = tri.ccw == mirrored;
|
|
182
|
+
if (list == ${WaterLodList.Patch}u) {
|
|
183
|
+
// the patch's indices run its points row by row; read across instead, they turn every cell the other way
|
|
184
|
+
var grid = vec2<i32>(i32(corner % ${WATER_LOD_PATCH_SIDE}u), i32(corner / ${WATER_LOD_PATCH_SIDE}u));
|
|
185
|
+
if (reversed) { grid = grid.yx; }
|
|
186
|
+
return water_lod_whole_point(level, cell + grid, frame, tri);
|
|
187
|
+
}
|
|
188
|
+
if (list == ${WaterLodList.Interior}u) {
|
|
189
|
+
let k = select(WATER_LOD_QUAD[corner], WATER_LOD_QUAD_REVERSED[corner], reversed);
|
|
190
|
+
return water_lod_whole_point(level, cell + vec2<i32>(i32(k == 1u || k == 2u), i32(k >= 2u)), frame, tri);
|
|
191
|
+
}
|
|
192
|
+
// a boundary cell's point, rebuilt from what the cells pass found it to lie on
|
|
193
|
+
let corners = array<vec2<f32>, 4>(
|
|
194
|
+
water_lod_lattice_point(lod, frame, level, cell),
|
|
195
|
+
water_lod_lattice_point(lod, frame, level, cell + vec2<i32>(1, 0)),
|
|
196
|
+
water_lod_lattice_point(lod, frame, level, cell + vec2<i32>(1, 1)),
|
|
197
|
+
water_lod_lattice_point(lod, frame, level, cell + vec2<i32>(0, 1)));
|
|
198
|
+
let fan = corner / 3u;
|
|
199
|
+
let at = corner % 3u;
|
|
200
|
+
var index = 0u;
|
|
201
|
+
if (at != 0u) { index = select(fan + at, fan + 3u - at, reversed); }
|
|
202
|
+
let bits = water_lod_polygon_bits(polygon, index);
|
|
203
|
+
out.metric = water_lod_point(tri, corners, bits);
|
|
204
|
+
out.rest = water_lod_rest(tri, bits, out.metric, frame.scale);
|
|
205
|
+
out.footprint = water_lod_footprint(lod, frame, level, out.metric);
|
|
206
|
+
out.present = true;
|
|
207
|
+
return out;
|
|
102
208
|
}
|
|
103
209
|
|
|
104
|
-
// One instance
|
|
105
|
-
// classification; receiver depth selects the nearest displaced interface.
|
|
210
|
+
// One instance a record of one of the view's lists; the list is told by the draw's first vertex.
|
|
106
211
|
@vertex
|
|
107
212
|
fn vs_main(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> WaterVertexOut {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
213
|
+
var list = ${WaterLodList.Interior}u;
|
|
214
|
+
var corner = vi;
|
|
215
|
+
var candidate: ${WATER_LOD_CANDIDATE_STRUCT.wgsl_ref};
|
|
216
|
+
var place = 0u;
|
|
217
|
+
var polygon = vec2<u32>(0u);
|
|
218
|
+
if (vi >= ${WATER_LOD_PATCH_FIRST_VERTEX}u) {
|
|
219
|
+
// a patch: its candidate and its quadrant's first cell; the index names the point
|
|
220
|
+
list = ${WaterLodList.Patch}u; corner = vi - ${WATER_LOD_PATCH_FIRST_VERTEX}u;
|
|
221
|
+
let record = water_lod_cells[water_lod_patches_base(lod_limits) + ii];
|
|
222
|
+
candidate = water_lod_candidates[record >> ${WATER_LOD_CELL_LOCAL_BITS}u];
|
|
223
|
+
place = record & ${(1 << WATER_LOD_CELL_LOCAL_BITS) - 1}u;
|
|
224
|
+
} else if (vi >= ${WATER_LOD_TRIANGLE_FIRST_VERTEX}u) {
|
|
225
|
+
// a triangle drawn as itself: its meshlet, then its body row and its triangle
|
|
226
|
+
list = ${WaterLodList.Triangle}u; corner = vi - ${WATER_LOD_TRIANGLE_FIRST_VERTEX}u;
|
|
227
|
+
let at = water_lod_triangles_base(lod_limits) + 2u * ii;
|
|
228
|
+
candidate.meshlet = water_lod_cells[at];
|
|
229
|
+
candidate.body = water_lod_cells[at + 1u] >> 7u;
|
|
230
|
+
candidate.packed = water_lod_cells[at + 1u] & 127u;
|
|
231
|
+
} else {
|
|
232
|
+
var base = 0u;
|
|
233
|
+
if (vi >= ${WATER_LOD_BOUNDARY_FIRST_VERTEX}u) {
|
|
234
|
+
list = ${WaterLodList.Boundary}u; corner = vi - ${WATER_LOD_BOUNDARY_FIRST_VERTEX}u; base = lod_limits.interior;
|
|
235
|
+
// a fan triangle past the cell's polygon draws nothing, decided before anything else is read
|
|
236
|
+
let at = water_lod_polygons_base(lod_limits) + ${WATER_LOD_POLYGON_WORDS}u * ii;
|
|
237
|
+
polygon = vec2<u32>(water_lod_cells[at], water_lod_cells[at + 1u]);
|
|
238
|
+
if (water_lod_polygon_count(polygon) < corner / 3u + 3u) { return water_vertex_out_none(0u); }
|
|
239
|
+
}
|
|
240
|
+
let record = water_lod_cells[base + ii];
|
|
241
|
+
candidate = water_lod_candidates[record >> ${WATER_LOD_CELL_LOCAL_BITS}u];
|
|
242
|
+
place = record & ${(1 << WATER_LOD_CELL_LOCAL_BITS) - 1}u;
|
|
243
|
+
}
|
|
244
|
+
let body = ${WATER_BODIES_TABLE.marshalling_method_read}(&scene_database, candidate.body);
|
|
245
|
+
let frame = water_lod_bodies[candidate.body];
|
|
112
246
|
let node = scene_read_node(&scene_database, body.node);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
let
|
|
116
|
-
let
|
|
117
|
-
let
|
|
118
|
-
let
|
|
119
|
-
let
|
|
120
|
-
let
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let a = read_meshlet_vertex_by_draw_index(header, definition.triangle * 3u);
|
|
125
|
-
let b = read_meshlet_vertex_by_draw_index(header, definition.triangle * 3u + 1u);
|
|
126
|
-
let c = read_meshlet_vertex_by_draw_index(header, definition.triangle * 3u + 2u);
|
|
127
|
-
let simulated = body.wave != ~0u;
|
|
128
|
-
let ca = tessellation.view_projection_matrix * (node.global * vec4f(water_reference_position(a.position, definition.anchor, simulated), 1));
|
|
129
|
-
let cb = tessellation.view_projection_matrix * (node.global * vec4f(water_reference_position(b.position, definition.anchor, simulated), 1));
|
|
130
|
-
let cc = tessellation.view_projection_matrix * (node.global * vec4f(water_reference_position(c.position, definition.anchor, simulated), 1));
|
|
131
|
-
let polygon = water_cell_polygon(ca, cb, cc, min(ndc0,ndc1), max(ndc0,ndc1));
|
|
132
|
-
let fan = (vi % 18u) / 3u;
|
|
133
|
-
if (polygon.count < fan + 3u) { return WaterVertexOut(vec4f(0,0,0,1),vec3f(0),vec3f(0,1,0),0,definition.body,vec3f(0,1,0)); }
|
|
134
|
-
let corner = select(vi % 3u, 2u - vi % 3u, (node.global_flags & ${NODE3D_GLOBAL_FLAG_MIRRORED}u) != 0u);
|
|
135
|
-
var index = 0u;
|
|
136
|
-
if (corner != 0u) { index = fan + corner; }
|
|
137
|
-
let barycentric = polygon.points[index];
|
|
138
|
-
var position = water_corner_position(a.position,b.position,c.position,ca,cb,cc,barycentric,
|
|
139
|
-
polygon.boundaries[index],min(ndc0,ndc1),max(ndc0,ndc1));
|
|
140
|
-
var normal = normalize(a.normal * barycentric.x + b.normal * barycentric.y + c.normal * barycentric.z);
|
|
247
|
+
let header = meshlet_metadata[candidate.meshlet];
|
|
248
|
+
let triangle = water_lod_candidate_triangle(candidate.packed);
|
|
249
|
+
let a = read_meshlet_vertex_by_draw_index(header, triangle * 3u);
|
|
250
|
+
let b = read_meshlet_vertex_by_draw_index(header, triangle * 3u + 1u);
|
|
251
|
+
let c = read_meshlet_vertex_by_draw_index(header, triangle * 3u + 2u);
|
|
252
|
+
let tri = water_lod_triangle(a.position, b.position, c.position, a.normal, b.normal, c.normal, frame.scale);
|
|
253
|
+
let mirrored = (node.global_flags & ${NODE3D_GLOBAL_FLAG_MIRRORED}u) != 0u;
|
|
254
|
+
let vertex = water_lod_vertex(list, corner, candidate, place, frame, tri, mirrored, polygon);
|
|
255
|
+
if (!vertex.present) { return water_vertex_out_none(candidate.body); }
|
|
256
|
+
var position = vertex.rest.position;
|
|
257
|
+
var normal = normalize(vertex.rest.normal);
|
|
141
258
|
let rest_normal = normal;
|
|
142
259
|
var variance = 0.0;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
let
|
|
148
|
-
let
|
|
149
|
-
|
|
150
|
-
let
|
|
151
|
-
let
|
|
152
|
-
|
|
153
|
-
position.y += mix(mix(h00, h10, blend.x), mix(h01, h11, blend.x), blend.y);
|
|
154
|
-
let slope = vec2f(mix(h10 - h00, h11 - h01, blend.y), mix(h01 - h00, h11 - h10, blend.x)) / spacing;
|
|
260
|
+
var footprint = 0.0;
|
|
261
|
+
if (frame.mode != ${WaterLodMode.Hidden}u && any(frame.bounds != vec2<f32>(0.0))) {
|
|
262
|
+
// a vertex the waves do not move carries none of them: its pixels shade what they resolve
|
|
263
|
+
footprint = select(1e30, vertex.footprint, vertex.footprint > 0.0);
|
|
264
|
+
let sum = water_surface_sum(body.wave, vertex.metric, footprint);
|
|
265
|
+
let surface = water_surface_finish(sum, 1.0);
|
|
266
|
+
// the metric frame's normal in the local frame is S·n
|
|
267
|
+
let tilted = surface.normal * frame.scale;
|
|
268
|
+
let slope = -tilted.xz / tilted.y;
|
|
269
|
+
if (vertex.footprint > 0.0) { position += surface.offset / frame.scale; }
|
|
155
270
|
normal = normalize(vec3f(normal.x - normal.y * slope.x, normal.y, normal.z - normal.y * slope.y));
|
|
156
|
-
|
|
271
|
+
if (vertex.footprint <= 0.0) { normal = rest_normal; }
|
|
272
|
+
variance = sum.particle_variance;
|
|
157
273
|
}
|
|
158
274
|
let world = (node.global * vec4f(position, 1.0)).xyz;
|
|
159
275
|
let linear = mat3x3f(node.global[0].xyz, node.global[1].xyz, node.global[2].xyz);
|
|
160
276
|
let inverse_transpose = transpose(mat3_inverse(linear));
|
|
161
277
|
let normal_ws = normalize(inverse_transpose * normal);
|
|
162
278
|
let rest_normal_ws = normalize(inverse_transpose * rest_normal);
|
|
163
|
-
|
|
279
|
+
// a pixel's footprint on the rest surface: distance times angle (an orthographic pixel's own size) across the view,
|
|
280
|
+
// that over the cosine at which the surface is seen along it; their geometric mean, as anisotropic filtering takes
|
|
281
|
+
let to_eye = camera.view_matrix_inverse[3].xyz - world;
|
|
282
|
+
let orthographic = lod.orthographic != 0u;
|
|
283
|
+
let across = select(length(to_eye) * lod.pixel, lod.pixel, orthographic);
|
|
284
|
+
let view = select(normalize(to_eye), normalize(camera.view_matrix_inverse[2].xyz), orthographic);
|
|
285
|
+
let pixel_footprint = across / sqrt(max(abs(dot(view, rest_normal_ws)), 0.05));
|
|
286
|
+
return WaterVertexOut(camera.view_projection_matrix * vec4f(world, 1.0), world, normal_ws, variance, candidate.body, rest_normal_ws,
|
|
287
|
+
vertex.metric, footprint, body.wave, normalize(node.global[0].xyz), normalize(node.global[2].xyz), pixel_footprint);
|
|
164
288
|
}
|
|
165
289
|
|
|
166
290
|
// The interface at one water fragment, in view space. Receivers trace through it and optics
|
|
@@ -185,9 +309,9 @@ fn water_interface(world: vec3<f32>, surface_normal: vec3<f32>, ior: f32, above:
|
|
|
185
309
|
return WaterInterface(origin, normalize(origin), normalize(direction_world_to_view(normal_ws, camera)),
|
|
186
310
|
max(ior, 1.0), min(max(trace.max_distance, 0.1), camera.clip_near_far.y));
|
|
187
311
|
}
|
|
188
|
-
`, [chunk_direction_world_to_view, WATER_BODIES_TABLE.chunk_read,
|
|
189
|
-
|
|
190
|
-
|
|
312
|
+
`, [chunk_direction_world_to_view, WATER_BODIES_TABLE.chunk_read, chunk_read_meshlet_vertex_by_draw_index,
|
|
313
|
+
chunk_scene_database_access, chunk_mat3_inverse, chunk_water_lod_candidate, chunk_water_lod_layout,
|
|
314
|
+
WATER_LOD_CANDIDATE_STRUCT.declaration_chunk, chunk_water_surface_sample]);
|
|
191
315
|
|
|
192
316
|
export const chunk_water_screen_ray = CodeChunk.from(/* language=WGSL */ `
|
|
193
317
|
fn water_hzb_mip_size(depth_size: vec2f, hzb_size: vec2f, mip: i32) -> vec2f {
|
|
@@ -287,6 +411,7 @@ fn water_receiver_submerged(uv: vec2f, surface: vec3f, normal: vec3f) -> bool {
|
|
|
287
411
|
|
|
288
412
|
@fragment
|
|
289
413
|
fn fs_main(in: WaterVertexOut, @builtin(front_facing) above: bool) -> WaterReceiver {
|
|
414
|
+
let pixel = water_pixel_surface(in, in.pixel_footprint);
|
|
290
415
|
let water = ${WATER_BODIES_TABLE.marshalling_method_read}(&scene_database, in.body_index);
|
|
291
416
|
let coord = vec2<i32>(in.clip.xy);
|
|
292
417
|
let dimensions = vec2f(textureDimensions(tDepth, 0));
|
|
@@ -305,7 +430,7 @@ fn fs_main(in: WaterVertexOut, @builtin(front_facing) above: bool) -> WaterRecei
|
|
|
305
430
|
water_depth = abs(dot(in.world - (camera.view_matrix_inverse * vec4f(behind_vs, 1.0)).xyz, normalize(in.rest_normal)));
|
|
306
431
|
}
|
|
307
432
|
let coverage = smoothstep(0.0, 0.1, water_depth);
|
|
308
|
-
let surface = water_interface(in.world,
|
|
433
|
+
let surface = water_interface(in.world, pixel.normal, water.ior, above);
|
|
309
434
|
let interface_normal = direction_view_to_world(surface.normal, camera);
|
|
310
435
|
let limit = surface.limit;
|
|
311
436
|
let direction = refract(surface.incident, surface.normal, 1.0 / surface.ior);
|
|
@@ -364,6 +489,7 @@ struct WaterOptics {
|
|
|
364
489
|
}
|
|
365
490
|
@fragment
|
|
366
491
|
fn fs_main(in: WaterVertexOut, @builtin(front_facing) above: bool) -> WaterOptics {
|
|
492
|
+
let pixel = water_pixel_surface(in, in.pixel_footprint);
|
|
367
493
|
let water = ${WATER_BODIES_TABLE.marshalling_method_read}(&scene_database, in.body_index);
|
|
368
494
|
let coord = vec2i(in.clip.xy);
|
|
369
495
|
let metadata = textureLoad(trace_metadata, coord, 0);
|
|
@@ -372,7 +498,7 @@ fn fs_main(in: WaterVertexOut, @builtin(front_facing) above: bool) -> WaterOptic
|
|
|
372
498
|
let dimensions = vec2f(textureDimensions(tDepth, 0));
|
|
373
499
|
let uv = in.clip.xy / dimensions;
|
|
374
500
|
let receiver_data = textureLoad(receiver, coord, 0);
|
|
375
|
-
let surface = water_interface(in.world,
|
|
501
|
+
let surface = water_interface(in.world, pixel.normal, water.ior, above);
|
|
376
502
|
let interface_normal = direction_view_to_world(surface.normal, camera);
|
|
377
503
|
let body = water;
|
|
378
504
|
let origin = surface.origin;
|
|
@@ -384,7 +510,7 @@ fn fs_main(in: WaterVertexOut, @builtin(front_facing) above: bool) -> WaterOptic
|
|
|
384
510
|
let reflection_direction = reflect(surface.incident, surface.normal);
|
|
385
511
|
// a reflection that misses on screen falls back to the GI mode, as SSR's resolve does
|
|
386
512
|
var reflection = water_gi_specular(in.world, direction_view_to_world(surface.normal, camera),
|
|
387
|
-
direction_view_to_world(-surface.incident, camera), clamp(sqrt(water.roughness * water.roughness +
|
|
513
|
+
direction_view_to_world(-surface.incident, camera), clamp(sqrt(water.roughness * water.roughness + pixel.variance), 0.0, 1.0));
|
|
388
514
|
if (trace.reflections != 0u && above) {
|
|
389
515
|
let reflected = water_hzb_hit(Ray(ray_at(origin, reflection_direction, 0.02), reflection_direction, limit),
|
|
390
516
|
trace.fallback_steps);
|
|
@@ -468,12 +594,15 @@ export const WATER_RESOURCES = resources;
|
|
|
468
594
|
function water_pipeline(shader, targets, finalize) {
|
|
469
595
|
const code = shader.source;
|
|
470
596
|
const layout = shader.resources.generatePipelineLayout(GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT);
|
|
471
|
-
//
|
|
472
|
-
// Keep their visibility precise so the Brick4 variant fits
|
|
473
|
-
const vertex_only = new Set(['
|
|
597
|
+
// The lattice spends eight storage slots in the vertex stage, the guaranteed budget. Lighting spends four in the
|
|
598
|
+
// fragment stage. Keep their visibility precise so the Brick4 variant fits it there.
|
|
599
|
+
const vertex_only = new Set(['lod', 'lod_limits', 'water_lod_bodies', 'water_lod_candidates', 'water_lod_cells',
|
|
600
|
+
'meshlet_metadata', 'meshlet_data', 'water_band_displacement', 'water_particle_offsets', 'water_particle_entries']);
|
|
601
|
+
// the fragment stage shades the bands the mesh could not carry
|
|
602
|
+
const both = new Set(['camera', 'scene_database', 'water_band_derivatives', 'water_band_sampler']);
|
|
474
603
|
shader.resources.groups.forEach((group, gi) => group.resources.forEach((resource, ri) => {
|
|
475
604
|
layout.bindGroupLayouts[gi].entries[ri].visibility = vertex_only.has(resource.name) ? GPUShaderStage.VERTEX
|
|
476
|
-
:
|
|
605
|
+
: both.has(resource.name) ? GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT
|
|
477
606
|
: GPUShaderStage.FRAGMENT;
|
|
478
607
|
}));
|
|
479
608
|
return RenderPipelineDescriptor.from({
|