@woosh/meep-engine 3.64.0 → 3.65.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/CHANGELOG.md +85 -0
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts +5 -0
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +39 -5
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
- package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts +27 -0
- package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts.map +1 -0
- package/src/engine/graphics/texture/sampler/exr_to_sampler2d.js +91 -0
- package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts +23 -0
- package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts.map +1 -0
- package/src/engine/graphics/texture/sampler/sampler2d_to_exr.js +64 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GroundCoverSystem.js +58 -0
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +372 -110
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +65 -9
- package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
- package/src/engine/network/state/PredictionHistory.js +6 -1
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
- package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
- package/src/engine/network/time/RenderPlayout.d.ts +23 -3
- package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
- package/src/engine/network/time/RenderPlayout.js +40 -4
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
- package/src/format/image/exr/ExrCompression.d.ts +22 -0
- package/src/format/image/exr/ExrCompression.d.ts.map +1 -0
- package/src/format/image/exr/ExrCompression.js +27 -0
- package/src/format/image/exr/ExrImage.d.ts +32 -0
- package/src/format/image/exr/ExrImage.d.ts.map +1 -0
- package/src/format/image/exr/ExrImage.js +32 -0
- package/src/format/image/exr/ExrPixelType.d.ts +13 -0
- package/src/format/image/exr/ExrPixelType.d.ts.map +1 -0
- package/src/format/image/exr/ExrPixelType.js +18 -0
- package/src/format/image/exr/exr_compare_names.d.ts +16 -0
- package/src/format/image/exr/exr_compare_names.d.ts.map +1 -0
- package/src/format/image/exr/exr_compare_names.js +25 -0
- package/src/format/image/exr/exr_constants.d.ts +49 -0
- package/src/format/image/exr/exr_constants.d.ts.map +1 -0
- package/src/format/image/exr/exr_constants.js +56 -0
- package/src/format/image/exr/exr_read.d.ts +32 -0
- package/src/format/image/exr/exr_read.d.ts.map +1 -0
- package/src/format/image/exr/exr_read.js +531 -0
- package/src/format/image/exr/exr_sample_bits.d.ts +16 -0
- package/src/format/image/exr/exr_sample_bits.d.ts.map +1 -0
- package/src/format/image/exr/exr_sample_bits.js +21 -0
- package/src/format/image/exr/exr_scanlines_per_chunk.d.ts +17 -0
- package/src/format/image/exr/exr_scanlines_per_chunk.d.ts.map +1 -0
- package/src/format/image/exr/exr_scanlines_per_chunk.js +31 -0
- package/src/format/image/exr/exr_write.d.ts +27 -0
- package/src/format/image/exr/exr_write.d.ts.map +1 -0
- package/src/format/image/exr/exr_write.js +378 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
- package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
- package/src/shade/playground/grass_surfaces/index.html +75 -0
- package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
- package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/main.js +593 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
- package/src/shade/playground/probe_clipmap/index.html +5 -0
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +34 -1
- package/src/shade/playground/probe_clipmap_box/README.md +5 -1
- package/src/shade/playground/probe_clipmap_box/index.html +12 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/main.js +15 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +47 -43
- package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
- package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
- package/src/shade/renderer/extension/ViewTextures.js +19 -5
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -15
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +3 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +18 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +7 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +28 -17
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +18 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +44 -48
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +8 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +21 -3
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
- package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
- package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
- package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
- package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
|
@@ -3,21 +3,18 @@ import { FrameRecord } from "./FrameRecord.js";
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* What the frame knows about where each pixel came from: this frame's depth, last frame's depth,
|
|
6
|
-
* the visibility buffer,
|
|
6
|
+
* the visibility buffer, the visible-meshlet table that resolves it, and how far each pixel moved.
|
|
7
7
|
*
|
|
8
8
|
* Carried from {@link FramePhase.AfterGBuffer} through {@link FramePhase.BeforePresent}, and
|
|
9
9
|
* writable wherever it is carried — an extension that rasterizes geometry which should own depth
|
|
10
10
|
* publishes a replacement here, the same way any other record is published into.
|
|
11
|
-
*
|
|
12
|
-
* `velocity` is deliberately absent: it is one of the frame's optional products, and products are
|
|
13
|
-
* their own delivery step. A field nothing may legally read yet would be a promise with no
|
|
14
|
-
* mechanism behind it.
|
|
15
11
|
*/
|
|
16
12
|
export class ViewTextures extends FrameRecord {
|
|
17
13
|
#depth = -1;
|
|
18
14
|
#depth_previous = -1;
|
|
19
15
|
#visibility = -1;
|
|
20
16
|
#visible_meshlets = -1;
|
|
17
|
+
#velocity = -1;
|
|
21
18
|
|
|
22
19
|
static is_present_at(phase) {
|
|
23
20
|
return phase === FramePhase.AfterGBuffer
|
|
@@ -80,4 +77,21 @@ export class ViewTextures extends FrameRecord {
|
|
|
80
77
|
set visible_meshlets(handle) {
|
|
81
78
|
this.#visible_meshlets = this.publish(handle);
|
|
82
79
|
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* How far each pixel's surface moved on screen since the last frame: `rg16float`, in pixels, this
|
|
83
|
+
* frame's place less last frame's, free of the sub-pixel jitter. The renderer fills it from depth and
|
|
84
|
+
* {@link visibility} before {@link FramePhase.AfterGBuffer}; an extension that draws surfaces the
|
|
85
|
+
* visibility buffer cannot describe writes their pixels' motion over it at that phase and publishes
|
|
86
|
+
* the handle it wrote. What is published later than that phase reaches nothing the renderer runs.
|
|
87
|
+
*
|
|
88
|
+
* @returns {number}
|
|
89
|
+
*/
|
|
90
|
+
get velocity() {
|
|
91
|
+
return this.read(this.#velocity);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
set velocity(handle) {
|
|
95
|
+
this.#velocity = this.publish(handle);
|
|
96
|
+
}
|
|
83
97
|
}
|
|
@@ -170,7 +170,9 @@ export class GPUFluidCascadeStack {
|
|
|
170
170
|
* wind.set_far_velocity(v_far(t))
|
|
171
171
|
*
|
|
172
172
|
* A tile holds `v − v_far(t_s,c)` and `k` is taken for `t`, so a cascade that did not step reads
|
|
173
|
-
* from its old tile through its new decay.
|
|
173
|
+
* from its old tile through its new decay. A cascade that is published takes the field's
|
|
174
|
+
* `publish_slot`, so the tile the frame before read stays as it was. The field's own update uploads
|
|
175
|
+
* the table.
|
|
174
176
|
*
|
|
175
177
|
* @param {object} options
|
|
176
178
|
* @param {FrameGraph} options.graph
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUFluidCascadeStack.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/fluid/GPUFluidCascadeStack.js"],"names":[],"mappings":"AASA;;;;GAIG;AAEH;;;GAGG;AACH,4CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH;IACI;;;;;OAKG;IACH,iCAFW,OAAO,0CAA0C,EAAE,eAAe,QAK5E;
|
|
1
|
+
{"version":3,"file":"GPUFluidCascadeStack.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/fluid/GPUFluidCascadeStack.js"],"names":[],"mappings":"AASA;;;;GAIG;AAEH;;;GAGG;AACH,4CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH;IACI;;;;;OAKG;IACH,iCAFW,OAAO,0CAA0C,EAAE,eAAe,QAK5E;IAgWD;;;;OAIG;IACH,uCAJW,MAAM,4BAEN;QAAC,OAAO,EAAE,OAAO,wCAAwC,EAAE,sBAAsB,CAAA;KAAC,QAkC5F;IArVD;;;;;;;;;;OAUG;IACH;QAT8B,MAAM;QACE,UAAU,EAArC,UAAU,MAAM,CAAC;QAED,SAAS,EAAzB,MAAM;QACU,aAAa,EAA7B,MAAM;QACqB,MAAM,EAAjC,UAAU,MAAM,CAAC;QACc,UAAU,EAAzC,YAAY,GAAC,MAAM,EAAE;QACL,iBAAiB,EAAjC,MAAM;OAwChB;IA/DD;;;;OAIG;IACH,iBAFU,OAAO,CAEM;IAEvB;;;;OAIG;IACH,UAFU,OAAO,CAED;IAqDhB,wBAAwB;IACxB,4BAEC;IAED;;;OAGG;IACH,uCAEC;IAED;;;OAGG;IACH,wBAEC;IAED;;;;OAIG;IACH,WAHW,MAAM,GACJ,eAAe,CAI3B;IAED;;;;;OAKG;IACH,qBAFW,YAAY,GAAC,MAAM,EAAE,QAY/B;IAED;;;;;;OAMG;IACH,wBAHW,YAAY,GAAC,MAAM,EAAE,UACrB,MAAM,QAMhB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH;QAd+B,KAAK,EAAzB,UAAU;QACM,IAAI,EAApB,MAAM;QAEU,EAAE,EAAlB,MAAM;QACqB,MAAM,EAAjC,UAAU,MAAM,CAAC;QACc,UAAU,EAAzC,YAAY,GAAC,MAAM,EAAE;QAEL,iBAAiB,EAAjC,MAAM;QACyB,OAAO,GAAtC,eAAe,GAAC,IAAI;QAEH,qBAAqB,GAAtC,MAAM;aA8FhB;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH;QAN+B,KAAK,EAAzB,UAAU;QACY,IAAI,EAA1B,YAAY;QACmB,UAAU,EAAzC,YAAY,GAAC,MAAM,EAAE;QAEL,iBAAiB,EAAjC,MAAM;aAyDhB;IA4CD;;OAEG;IACH,gBAUC;;CACJ;yBApdY,OAAO,2DAA2D,EAAE,UAAU;2BAC9E,OAAO,yBAAyB,EAAE,YAAY;8BAC9C,OAAO,8BAA8B,EAAE,eAAe;gCARnC,sBAAsB"}
|
|
@@ -352,7 +352,9 @@ export class GPUFluidCascadeStack {
|
|
|
352
352
|
* wind.set_far_velocity(v_far(t))
|
|
353
353
|
*
|
|
354
354
|
* A tile holds `v − v_far(t_s,c)` and `k` is taken for `t`, so a cascade that did not step reads
|
|
355
|
-
* from its old tile through its new decay.
|
|
355
|
+
* from its old tile through its new decay. A cascade that is published takes the field's
|
|
356
|
+
* `publish_slot`, so the tile the frame before read stays as it was. The field's own update uploads
|
|
357
|
+
* the table.
|
|
356
358
|
*
|
|
357
359
|
* @param {object} options
|
|
358
360
|
* @param {FrameGraph} options.graph
|
|
@@ -394,6 +396,9 @@ export class GPUFluidCascadeStack {
|
|
|
394
396
|
record.far_velocity.set(cascade.read_far_velocity);
|
|
395
397
|
cascade.describe_parent(record.parent, record.parent_faces, c + 1 < count ? cascades[c + 1] : null);
|
|
396
398
|
|
|
399
|
+
// its tile is written beside the one the frame before read
|
|
400
|
+
wind.publish_slot(c);
|
|
401
|
+
|
|
397
402
|
pass.order[pending++] = c;
|
|
398
403
|
this.#unpublished[c] = 0;
|
|
399
404
|
}
|
|
@@ -125,6 +125,13 @@ export class GPUFluidForcing {
|
|
|
125
125
|
* @returns {number}
|
|
126
126
|
*/
|
|
127
127
|
get obstacle_count(): number;
|
|
128
|
+
/**
|
|
129
|
+
* A number that changes whenever an effector or obstacle row is added or removed: while it stands, a
|
|
130
|
+
* list of either table's rows is the list it was.
|
|
131
|
+
*
|
|
132
|
+
* @returns {number}
|
|
133
|
+
*/
|
|
134
|
+
get sets_version(): number;
|
|
128
135
|
/**
|
|
129
136
|
* Every obstacle and effector row: the leaves of the finest tree, before its resolution cull.
|
|
130
137
|
* @returns {number}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUFluidForcing.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/fluid/forcing/GPUFluidForcing.js"],"names":[],"mappings":"AAuIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAUzB;IA2ID;;;;;;;;;;;OAWG;IACH,kCAPW,wBAAwB,EAAE,QAC1B,MAAM,QACN,MAAM,SACN,MAAM,cACN,MAAM,GACJ,wBAAwB,CAcpC;
|
|
1
|
+
{"version":3,"file":"GPUFluidForcing.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/fluid/forcing/GPUFluidForcing.js"],"names":[],"mappings":"AAuIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAUzB;IA2ID;;;;;;;;;;;OAWG;IACH,kCAPW,wBAAwB,EAAE,QAC1B,MAAM,QACN,MAAM,SACN,MAAM,cACN,MAAM,GACJ,wBAAwB,CAcpC;IAmmBD;;;;OAIG;IACH,yCAJW,MAAM,0CAEN;QAAC,OAAO,yBAAwB;KAAC,QAc3C;IA+MD,iFAcC;IAWD,gFAiCC;IAWD,kFAsBC;IA+GD,gFA0CC;IA3nCD;;;OAGG;IACH;QAF8B,MAAM;OAwCnC;IA4BD;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,6BAEC;IAED;;;OAGG;IACH,6BAEC;IAED;;;;;OAKG;IACH,2BAEC;IAED;;;OAGG;IACH,yBAEC;IAED;;;;;;;OAOG;IACH,mBAHW,MAAM,GACJ,MAAM,CAiBlB;IAED;;;;;OAKG;IACH,4BAEC;IAED;;;;;OAKG;IACH,2BAEC;IAED;;;;;OAKG;IACH,qBAHW,mBAAmB,GACjB,MAAM,CAQlB;IAED;;;;;OAKG;IACH,kBAHW,MAAM,UACN,mBAAmB,QAQ7B;IAED;;OAEG;IACH,qBAFW,MAAM,QAUhB;IAED;;;;;OAKG;IACH,uBAHW,mBAAmB,EAAE,GACnB,MAAM,CAsBlB;IAED;;;;;OAKG;IACH,kBAHW,MAAM,UACN,mBAAmB,QAgB7B;IAED;;;OAGG;IACH,wBAHW,MAAM,SACN,MAAM,QAYhB;IAED;;;;;OAKG;IACH,kBAHW,MAAM,GACJ,MAAM,CAuBlB;IAED;;;;;OAKG;IACH,kBAHW,MAAM,SACN,MAAM,QAmBhB;IAED;;;OAGG;IACH,qBAHW,MAAM,SACN,MAAM,QAUhB;IAyID;;;;;;;;;;;;;;;;;;;OAmBG;IACH;QAf+B,KAAK,EAAzB,UAAU;QACW,cAAc,EAAnC,WAAW;QAEgB,MAAM,EAAjC,UAAU,MAAM,CAAC;QAID,UAAU,EAA1B,MAAM;QAEU,gBAAgB,EAAhC,MAAM;QAEU,SAAS,EAAzB,MAAM;aA4ChB;IAyND;;;;;;;;;;;;OAYG;IACH;QAJ+B,KAAK,EAAzB,UAAU;QACe,KAAK,EAA9B,eAAe;QACe,MAAM,EAApC,eAAe,GAAC,IAAI;aA8H9B;IAmHD;;;;;;;;;;;OAWG;IACH;QAN+B,KAAK,EAAzB,UAAU;QACe,OAAO,EAAhC,eAAe;QACC,EAAE,EAAlB,MAAM;QACJ,MAAM,GAAC,IAAI,CAuFvB;IAyDD;;;OAGG;IACH,gBAwBC;;CACJ;yBAp7CY,OAAO,8DAA8D,EAAE,UAAU;8BACjF,OAAO,6CAA6C,EAAE,eAAe;8BACrE,OAAO,uBAAuB,EAAE,eAAe;kCAC/C,OAAO,kFAAkF,EAAE,mBAAmB;kCAC9G,OAAO,2EAA2E,EAAE,mBAAmB;4BAtCxF,mCAAmC;yCADtB,mDAAmD"}
|
|
@@ -410,6 +410,16 @@ export class GPUFluidForcing {
|
|
|
410
410
|
return this.#database.get(FLUID_OBSTACLE_TABLE).count;
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
+
/**
|
|
414
|
+
* A number that changes whenever an effector or obstacle row is added or removed: while it stands, a
|
|
415
|
+
* list of either table's rows is the list it was.
|
|
416
|
+
*
|
|
417
|
+
* @returns {number}
|
|
418
|
+
*/
|
|
419
|
+
get sets_version() {
|
|
420
|
+
return this.#sets_version;
|
|
421
|
+
}
|
|
422
|
+
|
|
413
423
|
/**
|
|
414
424
|
* Every obstacle and effector row: the leaves of the finest tree, before its resolution cull.
|
|
415
425
|
* @returns {number}
|
|
@@ -274,11 +274,17 @@ export class GPUGeometrySDFManager {
|
|
|
274
274
|
* `caches`, as the device holds them when the readbacks land: each brick once, however many fields
|
|
275
275
|
* hold it, and each cache naming its field. Read while nothing bakes, it is what was baked.
|
|
276
276
|
*
|
|
277
|
+
* With `morton`, the bundle is laid out for locality (`model_cache_bundle_sort_morton`): each field's
|
|
278
|
+
* bricks numbered in Morton order, its surface blocks with them, and the bricks in that order, which
|
|
279
|
+
* {@link upload_bundle} places them in. Off by default: worth it for assets prepared offline, where it
|
|
280
|
+
* costs nothing at load, and worth about 0.5% to the probe clipmap's material gather there.
|
|
281
|
+
*
|
|
277
282
|
* @param {GPUGeometryMetadata[]} records
|
|
278
283
|
* @param {number[]} caches surface cache ids, each of a geometry of `records`
|
|
284
|
+
* @param {boolean} [morton] lay the bundle out in Morton order
|
|
279
285
|
* @returns {Promise<ModelCacheBundle>}
|
|
280
286
|
*/
|
|
281
|
-
export_bundle(records: GPUGeometryMetadata[], caches: number[]): Promise<ModelCacheBundle>;
|
|
287
|
+
export_bundle(records: GPUGeometryMetadata[], caches: number[], morton?: boolean): Promise<ModelCacheBundle>;
|
|
282
288
|
/**
|
|
283
289
|
* Record the frame's bake: queue again what is held for the other side than it was baked for, free
|
|
284
290
|
* what was given back, classify what is admitted, and take, evaluate and store up to `budget`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUGeometrySDFManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUGeometrySDFManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js"],"names":[],"mappings":"AAoLA;;;;GAIG;AACH,uCAFU,MAAM,CAEuH;AAoEvI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH;IA8QI;;;OAGG;IACH,2CAFW,kBAAkB,EAS5B;IA7QD;;;;OAIG;IACH,aAAuB;IAEvB;;;;OAIG;IACH,iBAA2B;IAE3B;;;;OAIG;IACH,iBAA2B;IA4P3B;;;;;OAKG;IACH,qCAEC;IAED;;;;;;OAMG;IACH,sBAHW,MAAM,cACN,MAAM,QAkChB;IAED;;OAEG;IACH,yBAEC;IAED;;OAEG;IACH,yBAEC;IAED;;;;;OAKG;IACH,gBAHW,mBAAmB,aACnB,OAAO,QAajB;IAiCD;;;;;OAKG;IACH,gBAHW,mBAAmB,aACnB,OAAO,QAqBjB;IAED;;OAEG;IACH,aAYC;IAED;;;;;OAKG;IACH,eAFW,mBAAmB,QAiB7B;IAED;;;;;;;;;;;;OAYG;IACH,aAHW,mBAAmB,UACnB,mBAAmB,QAwD7B;IAcD;;;;;OAKG;IACH,iBAHW,mBAAmB,GACjB,YAAY,CAcxB;IAED;;;;;;OAMG;IACH,qBAHW,mBAAmB,GACjB,OAAO,CAInB;IAED;;;;;OAKG;IACH,wBAHW,mBAAmB,GACjB,OAAO,CAInB;IAED;;;OAGG;IACH,8BAEC;IAED;;OAEG;IACH,6BAEC;IAED;;;OAGG;IACH,2BAEC;IAED;;;OAGG;IACH,2BAUC;IAED;;;OAGG;IACH,6BAEC;IAED;;;OAGG;IACH,+BAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;;OAIG;IACH,8BAEC;IAED;;;OAGG;IACH,yBAEC;IAED;;;OAGG;IACH,6BAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,yBAIC;IAED;;;OAGG;IACH,6BAIC;IAED;;;OAGG;IACH,8EAIC;IAED;;;;;;OAMG;IACH,mCAOC;IAED;;OAEG;IACH,+BAcC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,sBANW,gBAAgB,WAChB,CAAC,mBAAmB,GAAC,IAAI,CAAC,EAAE,aAC5B,CAAC,aAAa,GAAC,IAAI,CAAC,EAAE,eACtB,OAAO,GACL,MAAM,CAiLlB;IA2CD;;;;;;;;;;;;;;OAcG;IACH,uBALW,mBAAmB,EAAE,UACrB,MAAM,EAAE,WACR,OAAO,GACL,QAAQ,gBAAgB,CAAC,CAuIrC;IAED;;;;;;;;;;;;;OAaG;IACH;QAP+B,KAAK,EAAzB,UAAU;QACM,MAAM,EAAtB,MAAM;QACW,cAAc,GAA/B,MAAM;QAEoC,SAAS,GAAnD,0BAA0B,GAAC,IAAI;aA+EzC;IAy+BD,gBAsCC;;CACJ;yBA/7EY,OAAO,8DAA8D,EAAE,UAAU;iCACjF,OAAO,0BAA0B,EAAE,kBAAkB;kCACrD,OAAO,2BAA2B,EAAE,mBAAmB;yCACvD,OAAO,uDAAuD,EAAE,0BAA0B;4BAC1F,OAAO,iCAAiC,EAAE,aAAa;qCAnB/B,mCAAmC;6BAOjE,eAAe;iCAVyD,8BAA8B"}
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
shader_mesh_sdf_upload_store
|
|
60
60
|
} from "./bake/shader_mesh_sdf_upload.js";
|
|
61
61
|
import { ModelCacheBundle, ModelCacheBundleCache, ModelCacheBundleField } from "./bundle/ModelCacheBundle.js";
|
|
62
|
+
import { model_cache_bundle_sort_morton } from "./bundle/model_cache_bundle_sort_morton.js";
|
|
62
63
|
import { download_texture_data } from "../../texture/download_texture_data.js";
|
|
63
64
|
import { GPUMeshSurfaceCaches } from "./surface/GPUMeshSurfaceCaches.js";
|
|
64
65
|
import {
|
|
@@ -1083,8 +1084,10 @@ export class GPUGeometrySDFManager {
|
|
|
1083
1084
|
this.#ensure_headers(this.#geometries.__last_geometry_index);
|
|
1084
1085
|
|
|
1085
1086
|
const layout = this.#layout;
|
|
1086
|
-
/** the bundle's bricks the upload carries, by their place in it */
|
|
1087
|
+
/** the bundle's bricks the upload carries, by their place in it: placed below in the bundle's order */
|
|
1087
1088
|
const place_of = new Map();
|
|
1089
|
+
/** each field taken's offset, entry count and indirection words, its entries naming bundle bricks until placed */
|
|
1090
|
+
const writes = [];
|
|
1088
1091
|
const runs = [];
|
|
1089
1092
|
const fields = [];
|
|
1090
1093
|
|
|
@@ -1133,19 +1136,12 @@ export class GPUGeometrySDFManager {
|
|
|
1133
1136
|
const entry = field.entries[e];
|
|
1134
1137
|
|
|
1135
1138
|
if (entry < MESH_SDF_EMPTY) {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
if (place === undefined) {
|
|
1139
|
-
place = place_of.size;
|
|
1140
|
-
place_of.set(entry, place);
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
// its place in the upload, which link turns into its slot
|
|
1144
|
-
scratch[2 + e] = place;
|
|
1145
|
-
} else {
|
|
1146
|
-
scratch[2 + e] = entry;
|
|
1139
|
+
// the bundle's brick for now: its place in the upload, which link turns into its slot, below
|
|
1140
|
+
place_of.set(entry, 0);
|
|
1147
1141
|
}
|
|
1148
1142
|
|
|
1143
|
+
scratch[2 + e] = entry;
|
|
1144
|
+
|
|
1149
1145
|
scratch[2 + count + e] = MESH_SDF_UNNUMBERED;
|
|
1150
1146
|
}
|
|
1151
1147
|
|
|
@@ -1154,7 +1150,7 @@ export class GPUGeometrySDFManager {
|
|
|
1154
1150
|
scratch[2 + 2 * count + n] = field.numbered[n];
|
|
1155
1151
|
}
|
|
1156
1152
|
|
|
1157
|
-
|
|
1153
|
+
writes.push(range.offset, count, scratch);
|
|
1158
1154
|
|
|
1159
1155
|
this.#records[id] = record;
|
|
1160
1156
|
this.#ranges[id] = range;
|
|
@@ -1184,6 +1180,33 @@ export class GPUGeometrySDFManager {
|
|
|
1184
1180
|
return 0;
|
|
1185
1181
|
}
|
|
1186
1182
|
|
|
1183
|
+
// the bricks placed in the bundle's order, about the order the fresh pass pops their slots in (an atomic a
|
|
1184
|
+
// thread). A sorted bundle's (`model_cache_bundle_sort_morton`) is its own. A whole exported bundle's,
|
|
1185
|
+
// every field taken, is the order its fields first name them; with fields left out, the bricks of
|
|
1186
|
+
// those taken still keep the bundle's order
|
|
1187
|
+
const placed = Array.from(place_of.keys()).sort((a, b) => a - b);
|
|
1188
|
+
|
|
1189
|
+
for (let place = 0; place < placed.length; place++) {
|
|
1190
|
+
place_of.set(placed[place], place);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// after every growth's copy is submitted, so none of these is copied over
|
|
1194
|
+
for (let w = 0; w < writes.length; w += 3) {
|
|
1195
|
+
const offset = writes[w];
|
|
1196
|
+
const count = writes[w + 1];
|
|
1197
|
+
const scratch = writes[w + 2];
|
|
1198
|
+
|
|
1199
|
+
for (let e = 0; e < count; e++) {
|
|
1200
|
+
const entry = scratch[2 + e];
|
|
1201
|
+
|
|
1202
|
+
if (entry < MESH_SDF_EMPTY) {
|
|
1203
|
+
scratch[2 + e] = place_of.get(entry);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
this.#device.queue.writeBuffer(this.#indirection, 4 * offset, scratch);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1187
1210
|
const brick_count = place_of.size;
|
|
1188
1211
|
const bytes = new Uint8Array(Math.max(4, brick_count * MESH_SDF_BRICK_TEXEL_COUNT));
|
|
1189
1212
|
|
|
@@ -1273,11 +1296,19 @@ export class GPUGeometrySDFManager {
|
|
|
1273
1296
|
* `caches`, as the device holds them when the readbacks land: each brick once, however many fields
|
|
1274
1297
|
* hold it, and each cache naming its field. Read while nothing bakes, it is what was baked.
|
|
1275
1298
|
*
|
|
1299
|
+
* With `morton`, the bundle is laid out for locality (`model_cache_bundle_sort_morton`): each field's
|
|
1300
|
+
* bricks numbered in Morton order, its surface blocks with them, and the bricks in that order, which
|
|
1301
|
+
* {@link upload_bundle} places them in. Off by default: worth it for assets prepared offline, where it
|
|
1302
|
+
* costs nothing at load, and worth about 0.5% to the probe clipmap's material gather there.
|
|
1303
|
+
*
|
|
1276
1304
|
* @param {GPUGeometryMetadata[]} records
|
|
1277
1305
|
* @param {number[]} caches surface cache ids, each of a geometry of `records`
|
|
1306
|
+
* @param {boolean} [morton] lay the bundle out in Morton order
|
|
1278
1307
|
* @returns {Promise<ModelCacheBundle>}
|
|
1279
1308
|
*/
|
|
1280
|
-
async export_bundle(records, caches) {
|
|
1309
|
+
async export_bundle(records, caches, morton = false) {
|
|
1310
|
+
assert.isBoolean(morton, 'morton');
|
|
1311
|
+
|
|
1281
1312
|
this.#ensure_device();
|
|
1282
1313
|
|
|
1283
1314
|
for (let i = 0; i < records.length; i++) {
|
|
@@ -1407,7 +1438,7 @@ export class GPUGeometrySDFManager {
|
|
|
1407
1438
|
bundle.caches.push(this.#surfaces.export_cache(caches[i], field, data, new ModelCacheBundleCache()));
|
|
1408
1439
|
}
|
|
1409
1440
|
|
|
1410
|
-
return bundle;
|
|
1441
|
+
return morton ? model_cache_bundle_sort_morton(bundle) : bundle;
|
|
1411
1442
|
}
|
|
1412
1443
|
|
|
1413
1444
|
/**
|
|
@@ -91,8 +91,9 @@ export class ModelCacheBundleCache {
|
|
|
91
91
|
* takes it only at the same.
|
|
92
92
|
*
|
|
93
93
|
* `GPUGeometrySDFManager.export_bundle` makes one of what is resident; `upload_bundle` takes one back,
|
|
94
|
-
* with or without sharing its bricks with those resident
|
|
95
|
-
* `model_cache_bundle_read` keep it as bytes
|
|
94
|
+
* with or without sharing its bricks with those resident, placing them in the order the bundle holds
|
|
95
|
+
* them; `model_cache_bundle_write` and `model_cache_bundle_read` keep it as bytes; and
|
|
96
|
+
* `model_cache_bundle_sort_morton` lays one out in Morton order for offline preparation.
|
|
96
97
|
*/
|
|
97
98
|
export class ModelCacheBundle {
|
|
98
99
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelCacheBundle.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH;IACI;;;OAGG;IACH,QAFU,YAAY,CAEO;IAE7B;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,QAFU,WAAW,CAEO;IAE5B;;OAEG;IACH,aAFU,MAAM,CAEA;IAEhB;;;OAGG;IACH,WAFU,MAAM,CAEF;IAEd;;;;OAIG;IACH,SAFU,WAAW,CAEQ;IAE7B;;;;OAIG;IACH,UAFU,WAAW,CAES;IAE9B;;;OAGG;IACH,QAFU,MAAM,CAEL;IAEX;;;OAGG;IACH,OAFU,WAAW,CAEM;CAC9B;AAED;;;GAGG;AACH;IACI;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,QAFU,MAAM,CAEL;IAEX;;;OAGG;IACH,OAFU,WAAW,CAEM;IAE3B;;;;OAIG;IACH,UAFU,WAAW,CAES;IAE9B;;;;OAIG;IACH,QAFU,WAAW,EAAE,CAE+C;CACzE;AAED
|
|
1
|
+
{"version":3,"file":"ModelCacheBundle.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH;IACI;;;OAGG;IACH,QAFU,YAAY,CAEO;IAE7B;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,QAFU,WAAW,CAEO;IAE5B;;OAEG;IACH,aAFU,MAAM,CAEA;IAEhB;;;OAGG;IACH,WAFU,MAAM,CAEF;IAEd;;;;OAIG;IACH,SAFU,WAAW,CAEQ;IAE7B;;;;OAIG;IACH,UAFU,WAAW,CAES;IAE9B;;;OAGG;IACH,QAFU,MAAM,CAEL;IAEX;;;OAGG;IACH,OAFU,WAAW,CAEM;CAC9B;AAED;;;GAGG;AACH;IACI;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,QAFU,MAAM,CAEL;IAEX;;;OAGG;IACH,OAFU,WAAW,CAEM;IAE3B;;;;OAIG;IACH,UAFU,WAAW,CAES;IAE9B;;;;OAIG;IACH,QAFU,WAAW,EAAE,CAE+C;CACzE;AAED;;;;;;;;;;GAUG;AACH;IACI;;;OAGG;IACH,YAFU,MAAM,CAED;IAEf;;;OAGG;IACH,YAFU,MAAM,CAED;IAEf;;;OAGG;IACH,QAFU,UAAU,CAEO;IAE3B;;OAEG;IACH,QAFU,qBAAqB,EAAE,CAErB;IAEZ;;OAEG;IACH,QAFU,qBAAqB,EAAE,CAErB;IAEZ;;OAEG;IACH,0BAEC;CACJ"}
|
|
@@ -107,8 +107,9 @@ export class ModelCacheBundleCache {
|
|
|
107
107
|
* takes it only at the same.
|
|
108
108
|
*
|
|
109
109
|
* `GPUGeometrySDFManager.export_bundle` makes one of what is resident; `upload_bundle` takes one back,
|
|
110
|
-
* with or without sharing its bricks with those resident
|
|
111
|
-
* `model_cache_bundle_read` keep it as bytes
|
|
110
|
+
* with or without sharing its bricks with those resident, placing them in the order the bundle holds
|
|
111
|
+
* them; `model_cache_bundle_write` and `model_cache_bundle_read` keep it as bytes; and
|
|
112
|
+
* `model_cache_bundle_sort_morton` lays one out in Morton order for offline preparation.
|
|
112
113
|
*/
|
|
113
114
|
export class ModelCacheBundle {
|
|
114
115
|
/**
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A copy of a {@link ModelCacheBundle} laid out for locality, holding the same fields and caches: what
|
|
3
|
+
* every entry reads, the bytes of its brick and its surface blocks, is unchanged.
|
|
4
|
+
*
|
|
5
|
+
* - each field's stored bricks are numbered in (level, Morton code of the brick) order, and its block
|
|
6
|
+
* table and its caches' blocks follow: a brick's blocks keep its mask and come in number order;
|
|
7
|
+
* - the bundle's bricks are ordered as the fields first name them, field by field in that numbering,
|
|
8
|
+
* with bricks no field names after them. `upload_bundle` places a bundle's bricks in that order, and its
|
|
9
|
+
* fresh pass pops their slots in about that order (an atomic a thread), so a field's neighbouring bricks
|
|
10
|
+
* mostly sit in neighbouring slots.
|
|
11
|
+
*
|
|
12
|
+
* Measured (2026-11-11, a 69k-brick library loaded into the probe clipmap on an RTX 4090 and a Radeon
|
|
13
|
+
* RDNA2 iGPU): the SDF batch pass does not change, and the brick material gather is about 0.5% faster.
|
|
14
|
+
* Bake order is already near this one, so the sort is for offline asset preparation, where it costs
|
|
15
|
+
* nothing at load, and is off unless asked for (`GPUGeometrySDFManager.export_bundle`).
|
|
16
|
+
*
|
|
17
|
+
* @param {ModelCacheBundle} bundle
|
|
18
|
+
* @returns {ModelCacheBundle} a new bundle; `bundle` is left as it was
|
|
19
|
+
*/
|
|
20
|
+
export function model_cache_bundle_sort_morton(bundle: ModelCacheBundle): ModelCacheBundle;
|
|
21
|
+
import { ModelCacheBundle } from "./ModelCacheBundle.js";
|
|
22
|
+
//# sourceMappingURL=model_cache_bundle_sort_morton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model_cache_bundle_sort_morton.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js"],"names":[],"mappings":"AA0FA;;;;;;;;;;;;;;;;;;GAkBG;AACH,uDAHW,gBAAgB,GACd,gBAAgB,CA2I5B;iCA9O8E,uBAAuB"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { assert } from "../../../../../core/assert.js";
|
|
2
|
+
import { v3_morton_encode_magicbits } from "../../../../../core/geom/3d/morton/v3_morton_encode_magicbits.js";
|
|
3
|
+
import { MESH_SDF_BRICK_TEXEL_COUNT, MESH_SDF_EMPTY } from "../MESH_SDF.js";
|
|
4
|
+
import {
|
|
5
|
+
MESH_SURFACE_PLANE_BLOCK_WORDS,
|
|
6
|
+
MESH_SURFACE_PRESENCE_BLOCK_WORDS,
|
|
7
|
+
MESH_SURFACE_TABLE_MASK_BITS
|
|
8
|
+
} from "../surface/MESH_SURFACE_BLOCK.js";
|
|
9
|
+
import { ModelCacheBundle, ModelCacheBundleCache, ModelCacheBundleField } from "./ModelCacheBundle.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Bricks along an axis a level's Morton code holds: 10 bits an axis.
|
|
13
|
+
* @type {number}
|
|
14
|
+
*/
|
|
15
|
+
const MORTON_AXIS_LIMIT = 1 << 10;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {number} v
|
|
19
|
+
* @returns {number}
|
|
20
|
+
*/
|
|
21
|
+
function popcount8(v) {
|
|
22
|
+
let c = 0;
|
|
23
|
+
|
|
24
|
+
for (let b = 0; b < 8; b++) {
|
|
25
|
+
c += (v >>> b) & 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return c;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Each entry's place in (level, Morton code of its brick) order, levels coarsening as `MeshSDFLayout`'s
|
|
33
|
+
* do: level k has ⌈bricks / 2^k⌉ along each axis, its entries after every finer level's, x fastest.
|
|
34
|
+
*
|
|
35
|
+
* @param {ModelCacheBundleField} field
|
|
36
|
+
* @returns {Float64Array} a key an entry
|
|
37
|
+
*/
|
|
38
|
+
function entry_keys(field) {
|
|
39
|
+
const keys = new Float64Array(field.entries.length);
|
|
40
|
+
|
|
41
|
+
let e = 0;
|
|
42
|
+
|
|
43
|
+
for (let level = 0; level < field.level_count; level++) {
|
|
44
|
+
const nx = Math.ceil(field.bricks[0] / 2 ** level);
|
|
45
|
+
const ny = Math.ceil(field.bricks[1] / 2 ** level);
|
|
46
|
+
const nz = Math.ceil(field.bricks[2] / 2 ** level);
|
|
47
|
+
|
|
48
|
+
assert.ok(nx <= MORTON_AXIS_LIMIT && ny <= MORTON_AXIS_LIMIT && nz <= MORTON_AXIS_LIMIT, 'field.bricks: past the 10 bits an axis a Morton code holds');
|
|
49
|
+
|
|
50
|
+
for (let z = 0; z < nz; z++) {
|
|
51
|
+
for (let y = 0; y < ny; y++) {
|
|
52
|
+
for (let x = 0; x < nx; x++) {
|
|
53
|
+
// 30 bits of code under the level: exact in a double
|
|
54
|
+
keys[e++] = level * 2 ** 30 + v3_morton_encode_magicbits(x, y, z);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
assert.equal(e, field.entries.length, 'field.entries: one a brick of its levels');
|
|
61
|
+
|
|
62
|
+
return keys;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* `words` holding `per_block` words for each block, its blocks moved: run r of `runs` (old first block,
|
|
67
|
+
* new first block, blocks) from its old place to its new.
|
|
68
|
+
*
|
|
69
|
+
* @param {Uint32Array} words
|
|
70
|
+
* @param {number} per_block
|
|
71
|
+
* @param {number} blocks
|
|
72
|
+
* @param {number[]|null} runs null for a field with no table, whose blocks no brick numbers
|
|
73
|
+
* @returns {Uint32Array}
|
|
74
|
+
*/
|
|
75
|
+
function move_blocks(words, per_block, blocks, runs) {
|
|
76
|
+
if (words.length === 0 || runs === null) {
|
|
77
|
+
return words.slice();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
assert.equal(words.length, blocks * per_block, 'a cache\'s blocks: its field\'s, each of its plane\'s words');
|
|
81
|
+
|
|
82
|
+
const out = new Uint32Array(words.length);
|
|
83
|
+
|
|
84
|
+
for (let r = 0; r < runs.length; r += 3) {
|
|
85
|
+
out.set(words.subarray(runs[r] * per_block, (runs[r] + runs[r + 2]) * per_block), runs[r + 1] * per_block);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* A copy of a {@link ModelCacheBundle} laid out for locality, holding the same fields and caches: what
|
|
93
|
+
* every entry reads, the bytes of its brick and its surface blocks, is unchanged.
|
|
94
|
+
*
|
|
95
|
+
* - each field's stored bricks are numbered in (level, Morton code of the brick) order, and its block
|
|
96
|
+
* table and its caches' blocks follow: a brick's blocks keep its mask and come in number order;
|
|
97
|
+
* - the bundle's bricks are ordered as the fields first name them, field by field in that numbering,
|
|
98
|
+
* with bricks no field names after them. `upload_bundle` places a bundle's bricks in that order, and its
|
|
99
|
+
* fresh pass pops their slots in about that order (an atomic a thread), so a field's neighbouring bricks
|
|
100
|
+
* mostly sit in neighbouring slots.
|
|
101
|
+
*
|
|
102
|
+
* Measured (2026-11-11, a 69k-brick library loaded into the probe clipmap on an RTX 4090 and a Radeon
|
|
103
|
+
* RDNA2 iGPU): the SDF batch pass does not change, and the brick material gather is about 0.5% faster.
|
|
104
|
+
* Bake order is already near this one, so the sort is for offline asset preparation, where it costs
|
|
105
|
+
* nothing at load, and is off unless asked for (`GPUGeometrySDFManager.export_bundle`).
|
|
106
|
+
*
|
|
107
|
+
* @param {ModelCacheBundle} bundle
|
|
108
|
+
* @returns {ModelCacheBundle} a new bundle; `bundle` is left as it was
|
|
109
|
+
*/
|
|
110
|
+
export function model_cache_bundle_sort_morton(bundle) {
|
|
111
|
+
const out = new ModelCacheBundle();
|
|
112
|
+
|
|
113
|
+
out.voxel_size = bundle.voxel_size;
|
|
114
|
+
out.max_bricks = bundle.max_bricks;
|
|
115
|
+
|
|
116
|
+
const brick_count = bundle.brick_count;
|
|
117
|
+
/** the new index of each old brick, -1 until a field names it */
|
|
118
|
+
const brick_to = new Int32Array(brick_count).fill(-1);
|
|
119
|
+
let next_brick = 0;
|
|
120
|
+
|
|
121
|
+
/** each field's runs of moved blocks, for its caches */
|
|
122
|
+
const field_runs = [];
|
|
123
|
+
|
|
124
|
+
for (let f = 0; f < bundle.fields.length; f++) {
|
|
125
|
+
const field = bundle.fields[f];
|
|
126
|
+
const stored = field.numbered.length;
|
|
127
|
+
const keys = entry_keys(field);
|
|
128
|
+
|
|
129
|
+
// brick n's new number is its place in key order; entries are distinct, so no two keys tie
|
|
130
|
+
const order = Array.from({ length: stored }, (_, n) => n);
|
|
131
|
+
|
|
132
|
+
order.sort((a, b) => keys[field.numbered[a]] - keys[field.numbered[b]]);
|
|
133
|
+
|
|
134
|
+
const sorted = new ModelCacheBundleField();
|
|
135
|
+
|
|
136
|
+
sorted.origin.set(field.origin);
|
|
137
|
+
sorted.voxel = field.voxel;
|
|
138
|
+
sorted.bricks.set(field.bricks);
|
|
139
|
+
sorted.level_count = field.level_count;
|
|
140
|
+
sorted.two_sided = field.two_sided;
|
|
141
|
+
sorted.blocks = field.blocks;
|
|
142
|
+
sorted.numbered = new Uint32Array(stored);
|
|
143
|
+
|
|
144
|
+
for (let m = 0; m < stored; m++) {
|
|
145
|
+
sorted.numbered[m] = field.numbered[order[m]];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// without a table no block is numbered by a brick: a cache's blocks, if any, stay where they are
|
|
149
|
+
let runs = null;
|
|
150
|
+
|
|
151
|
+
if (field.table.length > 0) {
|
|
152
|
+
runs = [];
|
|
153
|
+
assert.equal(field.table.length, stored, 'field.table: a word a stored brick, or none');
|
|
154
|
+
|
|
155
|
+
sorted.table = new Uint32Array(stored);
|
|
156
|
+
|
|
157
|
+
// every block in exactly one brick's run, as a survey hands them out: what moves them losslessly
|
|
158
|
+
const covered = new Uint8Array(field.blocks);
|
|
159
|
+
|
|
160
|
+
let first = 0;
|
|
161
|
+
|
|
162
|
+
for (let m = 0; m < stored; m++) {
|
|
163
|
+
const word = field.table[order[m]];
|
|
164
|
+
const mask = word & ((1 << MESH_SURFACE_TABLE_MASK_BITS) - 1);
|
|
165
|
+
const count = popcount8(mask);
|
|
166
|
+
const from = word >>> MESH_SURFACE_TABLE_MASK_BITS;
|
|
167
|
+
|
|
168
|
+
sorted.table[m] = ((first << MESH_SURFACE_TABLE_MASK_BITS) | mask) >>> 0;
|
|
169
|
+
|
|
170
|
+
if (count > 0) {
|
|
171
|
+
assert.lessThanOrEqual(from + count, field.blocks, 'field.table: a run past the field\'s blocks');
|
|
172
|
+
|
|
173
|
+
for (let b = from; b < from + count; b++) {
|
|
174
|
+
assert.equal(covered[b], 0, 'field.table: two bricks\' runs share a block');
|
|
175
|
+
covered[b] = 1;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
runs.push(from, first, count);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
first += count;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
assert.equal(first, field.blocks, 'field.blocks: the blocks its table\'s masks keep');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
field_runs.push(runs);
|
|
188
|
+
|
|
189
|
+
// the bricks as this field first names them, in its new numbering
|
|
190
|
+
for (let m = 0; m < stored; m++) {
|
|
191
|
+
const brick = field.entries[sorted.numbered[m]];
|
|
192
|
+
|
|
193
|
+
assert.lessThan(brick, brick_count, 'a numbered entry names a brick of the bundle');
|
|
194
|
+
|
|
195
|
+
if (brick_to[brick] === -1) {
|
|
196
|
+
brick_to[brick] = next_brick++;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
out.fields.push(sorted);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// bricks no field numbers: after the rest, as they were
|
|
204
|
+
for (let b = 0; b < brick_count; b++) {
|
|
205
|
+
if (brick_to[b] === -1) {
|
|
206
|
+
brick_to[b] = next_brick++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
out.bricks = new Uint8Array(bundle.bricks.length);
|
|
211
|
+
|
|
212
|
+
for (let b = 0; b < brick_count; b++) {
|
|
213
|
+
out.bricks.set(bundle.bricks.subarray(b * MESH_SDF_BRICK_TEXEL_COUNT, (b + 1) * MESH_SDF_BRICK_TEXEL_COUNT), brick_to[b] * MESH_SDF_BRICK_TEXEL_COUNT);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
for (let f = 0; f < bundle.fields.length; f++) {
|
|
217
|
+
const entries = bundle.fields[f].entries;
|
|
218
|
+
const renamed = new Uint32Array(entries.length);
|
|
219
|
+
|
|
220
|
+
for (let e = 0; e < entries.length; e++) {
|
|
221
|
+
const entry = entries[e];
|
|
222
|
+
|
|
223
|
+
renamed[e] = entry < MESH_SDF_EMPTY ? brick_to[entry] : entry;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
out.fields[f].entries = renamed;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (const cache of bundle.caches) {
|
|
230
|
+
const sorted = new ModelCacheBundleCache();
|
|
231
|
+
const runs = field_runs[cache.field];
|
|
232
|
+
const blocks = bundle.fields[cache.field].blocks;
|
|
233
|
+
|
|
234
|
+
sorted.field = cache.field;
|
|
235
|
+
sorted.texels = cache.texels;
|
|
236
|
+
sorted.codes.set(cache.codes);
|
|
237
|
+
sorted.presence = move_blocks(cache.presence, MESH_SURFACE_PRESENCE_BLOCK_WORDS, blocks, runs);
|
|
238
|
+
|
|
239
|
+
for (let p = 0; p < cache.planes.length; p++) {
|
|
240
|
+
sorted.planes[p] = move_blocks(cache.planes[p], MESH_SURFACE_PLANE_BLOCK_WORDS[p], blocks, runs);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
out.caches.push(sorted);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return out;
|
|
247
|
+
}
|
|
@@ -88,6 +88,56 @@ export class GPUProbeClipmapGI {
|
|
|
88
88
|
* @returns {boolean}
|
|
89
89
|
*/
|
|
90
90
|
get has_probes(): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Record the wants of a screen surface drawn apart from the G-buffer whose reader picks the frustum's probes a
|
|
93
|
+
* pixel (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): the water's interface. A pixel of each screen tile wants
|
|
94
|
+
* the cages its pick reads, as the G-buffer's pixels do (`ProbeClipmapScreenWants`).
|
|
95
|
+
*
|
|
96
|
+
* For a pass after this frame's {@link graph_update}, once the surface is drawn. Its wants are taken by the
|
|
97
|
+
* next frame's lifetime, so a probe the surface newly reads is there a frame after the surface is. Records
|
|
98
|
+
* nothing where there are no probes ({@link has_probes}): out of the mode it costs nothing.
|
|
99
|
+
*
|
|
100
|
+
* @param {Object} options
|
|
101
|
+
* @param {FrameGraph} options.graph
|
|
102
|
+
* @param {number} options.depth graph handle of the surface's reverse-Z depth, zero where it has none
|
|
103
|
+
* @param {number} options.normal graph handle of its normals, a `uint` texture: a channel holds a normal
|
|
104
|
+
* octahedral, as the G-buffer packs its own
|
|
105
|
+
* @param {number} [options.normal_channel] the channel that holds the normal, 0 to 3
|
|
106
|
+
* @param {boolean} [options.two_sided] whether the reader turns a normal that faces away from the eye to face it
|
|
107
|
+
* @param {GPUBuffer} options.camera the camera uniform the surface was drawn with
|
|
108
|
+
* @param {ArrayLike<number>} options.resolution the surface's pixels, x and y
|
|
109
|
+
*/
|
|
110
|
+
graph_want_surface({ graph, depth, normal, normal_channel, two_sided, camera, resolution }: {
|
|
111
|
+
graph: FrameGraph;
|
|
112
|
+
depth: number;
|
|
113
|
+
normal: number;
|
|
114
|
+
normal_channel?: number;
|
|
115
|
+
two_sided?: boolean;
|
|
116
|
+
camera: GPUBuffer;
|
|
117
|
+
resolution: ArrayLike<number>;
|
|
118
|
+
}): void;
|
|
119
|
+
/**
|
|
120
|
+
* Record the wants of a list of meshlets a forward pass draws, whose fragments pick the frustum's probes
|
|
121
|
+
* (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): each wants the cages a reader anywhere inside its box can
|
|
122
|
+
* read (`graph_probe_clipmap_want_meshlets`).
|
|
123
|
+
*
|
|
124
|
+
* For a pass after this frame's {@link graph_update}; taken by the next frame's lifetime, as
|
|
125
|
+
* {@link graph_want_surface}'s are. Records nothing where there are no probes ({@link has_probes}).
|
|
126
|
+
*
|
|
127
|
+
* @param {Object} options
|
|
128
|
+
* @param {FrameGraph} options.graph
|
|
129
|
+
* @param {import("../../scene/GPUSceneContext.js").GPUSceneContext} options.scene the meshlets' scene
|
|
130
|
+
* @param {number} options.camera graph handle of the view's camera uniform
|
|
131
|
+
* @param {number} options.meshlet_collection graph handle of the list, `MESHLET_COLLECTION_STRUCT`
|
|
132
|
+
* @param {number} options.meshlet_iterator_command graph handle of the indirect dispatch that walks the list
|
|
133
|
+
*/
|
|
134
|
+
graph_want_meshlets({ graph, scene, camera, meshlet_collection, meshlet_iterator_command }: {
|
|
135
|
+
graph: FrameGraph;
|
|
136
|
+
scene: import("../../scene/GPUSceneContext.js").GPUSceneContext;
|
|
137
|
+
camera: number;
|
|
138
|
+
meshlet_collection: number;
|
|
139
|
+
meshlet_iterator_command: number;
|
|
140
|
+
}): void;
|
|
91
141
|
/**
|
|
92
142
|
* Put what the probes' readers bind into `bindings`, `PROBE_CLIPMAP_SAMPLING_GROUP` but its sampler:
|
|
93
143
|
* once {@link has_probes}, the probes as this frame's {@link graph_update} left them
|