@woosh/meep-engine 3.59.0 → 3.60.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/package.json +1 -1
- package/src/shade/playground/probe_clipmap/index.html +12 -0
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +5 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +4 -6
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +63 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +228 -16
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +27 -4
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +526 -23
- package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.d.ts +11 -0
- package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.js +21 -0
- package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.d.ts +65 -0
- package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +376 -0
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.d.ts +7 -3
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.js +70 -6
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.d.ts +20 -0
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.js +80 -0
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.d.ts +18 -0
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.js +113 -0
- package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +47 -0
- package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +80 -0
- package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +91 -0
- package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +902 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +67 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +145 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +12 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +105 -0
- package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +3 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +13 -31
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +764 -48
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +410 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +3 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +4 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +41 -17
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +57 -33
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts +11 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.js +13 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +9 -18
- 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 +8 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.js +28 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +1 -29
- 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 +1 -74
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts +161 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.js +219 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts +1 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.js +1 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.d.ts +40 -12
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.js +373 -31
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.d.ts +15 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.js +28 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts +23 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.js +66 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.d.ts +29 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.js +210 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.d.ts +29 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.js +86 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts +41 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js +439 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.d.ts +23 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.js +135 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts +3 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js +12 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +21 -18
- 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 +254 -73
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +149 -8
- 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 +181 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +179 -7
- 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 +412 -31
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +4 -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 +4 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +36 -10
- 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 +218 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts +5 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +24 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +15 -6
- 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 +21 -22
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts +36 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.js +257 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts +18 -7
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +157 -51
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts +23 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.js +110 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +24 -2
- 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 +90 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts +45 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.js +205 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts +16 -3
- 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 +55 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +19 -4
- 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 +60 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +4 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +21 -36
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +21 -14
- 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 +100 -30
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts +6 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.js +26 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts +3 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.js +12 -12
- package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.d.ts +10 -0
- package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.js +21 -0
- package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.d.ts +5 -2
- package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.js +31 -23
- package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.d.ts +10 -0
- package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.js +22 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.d.ts +9 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.js +18 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.d.ts +8 -3
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.js +41 -32
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.d.ts +31 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.js +71 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.d.ts +47 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.js +210 -0
- package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +5 -4
- package/src/shade/renderer/gpu_primitive/sort/defs.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/defs.js +5 -4
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +56 -15
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +410 -61
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts +4 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +16 -42
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.d.ts +15 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.js +60 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.d.ts +25 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.js +89 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts +3 -8
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +28 -160
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.d.ts +12 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.js +74 -0
- package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.d.ts +3 -1
- package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.js +387 -188
- package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +1 -1
- package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +90 -72
- package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.d.ts +5 -0
- package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.js +9 -0
- package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.d.ts +13 -0
- package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.d.ts.map +1 -0
- package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.js +14 -0
- package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.d.ts +10 -0
- package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.d.ts.map +1 -0
- package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.js +15 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts +4 -3
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.js +6 -5
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.d.ts +17 -2
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.js +25 -57
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.d.ts +13 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.d.ts.map +1 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.js +70 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.d.ts +10 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.d.ts.map +1 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.js +59 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.d.ts +12 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.d.ts.map +1 -0
- package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.js +49 -0
- package/src/shade/renderer/path_tracer/shader/chunk_ray_hit_to_opacity.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_ray_hit_to_opacity.js +1 -0
- package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +1 -0
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material.js +2 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts +7 -0
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +15 -6
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +7 -1
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +26 -1
- package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts +7 -7
- package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +262 -294
- package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.d.ts +9 -0
- package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.js +21 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +43 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +87 -0
- package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.d.ts +7 -1
- package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.js +1 -1
- package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.d.ts +21 -0
- package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.js +42 -0
- package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
- package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +19 -0
- package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/CPUBitmapData.js +27 -0
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +39 -18
- package/src/view/elements/progress/segmented/GhostTrail.d.ts +56 -0
- package/src/view/elements/progress/segmented/GhostTrail.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/GhostTrail.js +98 -0
- package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.d.ts +3 -1
- package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.js +3 -1
- package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.d.ts +11 -0
- package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.js +15 -0
- package/src/view/elements/progress/segmented/SegmentDefinition.d.ts +3 -0
- package/src/view/elements/progress/segmented/SegmentDefinition.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/SegmentDefinition.js +3 -0
- package/src/view/elements/progress/segmented/SegmentTier.d.ts +38 -0
- package/src/view/elements/progress/segmented/SegmentTier.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/SegmentTier.js +50 -0
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +155 -10
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +427 -101
- package/src/view/elements/progress/segmented/playground/index.html +78 -0
- package/src/view/elements/progress/segmented/playground/main.d.ts +2 -0
- package/src/view/elements/progress/segmented/playground/main.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/playground/main.js +173 -0
- package/src/view/elements/progress/segmented/segment_cell_layout.d.ts +48 -0
- package/src/view/elements/progress/segmented/segment_cell_layout.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/segment_cell_layout.js +75 -0
- package/src/view/elements/progress/segmented/segment_notch_place.d.ts +18 -0
- package/src/view/elements/progress/segmented/segment_notch_place.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/segment_notch_place.js +28 -0
- package/src/view/elements/progress/segmented/segment_tick_positions.d.ts +32 -0
- package/src/view/elements/progress/segmented/segment_tick_positions.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/segment_tick_positions.js +103 -0
- package/src/view/elements/progress/segmented/segmented-resource-bar.css +142 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts +0 -35
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.js +0 -238
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts +0 -99
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.js +0 -139
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts +0 -65
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.js +0 -393
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts +0 -17
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.js +0 -36
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts +0 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.js +0 -108
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts +0 -31
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.js +0 -113
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts +0 -36
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.js +0 -85
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts +0 -23
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.js +0 -273
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts +0 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.js +0 -151
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts +0 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.js +0 -133
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts +0 -22
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.js +0 -135
package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import { WebGPUExtensionType } from "../../../../../descriptor/WebGPUExtensionType.js";
|
|
3
|
+
import { MESH_SDF_HEADERS_RESOURCE } from "../../../../geometry/sdf/MESH_SDF_RESOURCES.js";
|
|
4
|
+
import { BVH2_NODE_STRUCT } from "../../../../shader/chunk/bvh/BVH2_NODE_STRUCT.js";
|
|
5
|
+
import { BVH_NULL_NODE_DEFINITION } from "../../../../shader/chunk/bvh/BVH_NULL_NODE_DEFINITION.js";
|
|
6
|
+
import { BVH_STRUCT } from "../../../../shader/chunk/bvh/BVH_STRUCT.js";
|
|
7
|
+
import {
|
|
8
|
+
BVH_QUERY_AABB_LEVEL_BUDGET,
|
|
9
|
+
chunk_bvh_query_aabb_frontier
|
|
10
|
+
} from "../../../../shader/chunk/bvh/chunk_bvh_query_aabb_frontier.js";
|
|
11
|
+
import { CLIPMAP_LEVEL_ARRAY } from "../../../../shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js";
|
|
12
|
+
import { chunk_folded_workgroup_index } from "../../../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
13
|
+
import { chunk_subgroup_reserve_workgroup } from "../../../../shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.js";
|
|
14
|
+
import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
|
|
15
|
+
import { ComputeShader } from "../../../../shader/ComputeShader.js";
|
|
16
|
+
import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
17
|
+
import { atomic_u32, u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
18
|
+
import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
|
|
19
|
+
import { WebGPUStruct } from "../../../../shader/type/WebGPUStruct.js";
|
|
20
|
+
import { BRICK_CELL_WORKGROUP_SIZE } from "../BRICK_CLIPMAP.js";
|
|
21
|
+
import { chunk_brick_provider } from "../chunk_brick_provider.js";
|
|
22
|
+
import { BRICK_RING_RESOURCE, BRICK_TAKE_RESOURCE, chunk_brick_clipmap } from "../chunk_brick_clipmap.js";
|
|
23
|
+
import { chunk_mesh_brick_instance } from "./chunk_mesh_brick_instance.js";
|
|
24
|
+
import { chunk_mesh_brick_walk } from "./chunk_mesh_brick_walk.js";
|
|
25
|
+
import {
|
|
26
|
+
MESH_BRICK_BATCH,
|
|
27
|
+
MESH_BRICK_COUNTER_BATCHES,
|
|
28
|
+
MESH_BRICK_COUNTER_RESOLVES,
|
|
29
|
+
MESH_BRICK_COUNTER_ROUND_GROUPS,
|
|
30
|
+
MESH_BRICK_COUNTER_TASKS,
|
|
31
|
+
MESH_BRICK_FRONTIER,
|
|
32
|
+
MESH_BRICK_STATISTIC_BATCHES,
|
|
33
|
+
MESH_BRICK_STATISTIC_BATCHES_DROPPED,
|
|
34
|
+
MESH_BRICK_STATISTIC_LEVELS_SHORT,
|
|
35
|
+
MESH_BRICK_STATISTIC_ROUNDS_SHORT,
|
|
36
|
+
MESH_BRICK_STATISTIC_TASKS,
|
|
37
|
+
MESH_BRICK_STATISTIC_TASKS_DROPPED
|
|
38
|
+
} from "./MESH_BRICK.js";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @type {WebGPUStruct}
|
|
42
|
+
*/
|
|
43
|
+
export const MESH_BRICK_GATHER_SETTINGS = WebGPUStruct.from({
|
|
44
|
+
/** keys `brick_ring` holds, a power of two */
|
|
45
|
+
ring_capacity: u32,
|
|
46
|
+
/** cells a cascade's window has a side */
|
|
47
|
+
resolution: u32,
|
|
48
|
+
/** 0 for the walks from the root, one a taken cell; past it, the walks of the tasks the round before handed on */
|
|
49
|
+
round: u32,
|
|
50
|
+
/** 1 for the frame's last round, whose nodes past the frontier have no round to go to */
|
|
51
|
+
last: u32,
|
|
52
|
+
/** task records a half of `mesh_brick_tasks` holds */
|
|
53
|
+
task_capacity: u32,
|
|
54
|
+
/** batch records `mesh_brick_batches` holds */
|
|
55
|
+
batch_capacity: u32,
|
|
56
|
+
}, "MeshBrickGatherSettings");
|
|
57
|
+
|
|
58
|
+
// a walk is a workgroup's, as the cooperative query's is, and its records are a lane an entry
|
|
59
|
+
assert.equal(BRICK_CELL_WORKGROUP_SIZE, MESH_BRICK_BATCH, 'a lane a record entry');
|
|
60
|
+
assert.equal(MESH_BRICK_FRONTIER % MESH_BRICK_BATCH, 0, 'the frontier is expanded in whole rounds of the workgroup');
|
|
61
|
+
|
|
62
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
63
|
+
|
|
64
|
+
resources.setImmediate("settings", MESH_BRICK_GATHER_SETTINGS);
|
|
65
|
+
|
|
66
|
+
resources.createGroup()
|
|
67
|
+
.add(BRICK_TAKE_RESOURCE)
|
|
68
|
+
.add(BRICK_RING_RESOURCE)
|
|
69
|
+
.addUniform("brick_levels", CLIPMAP_LEVEL_ARRAY)
|
|
70
|
+
.addStorageBuffer("mesh_brick_counters", WebGPUArray.from(atomic_u32), true)
|
|
71
|
+
.addStorageBuffer("mesh_brick_tasks", WebGPUArray.u32, true)
|
|
72
|
+
.addStorageBuffer("mesh_brick_batches", WebGPUArray.u32, true)
|
|
73
|
+
.addStorageBuffer("mesh_brick_accumulators", WebGPUArray.from(atomic_u32), true)
|
|
74
|
+
.addStorageBuffer("mesh_brick_resolves", WebGPUArray.u32, true);
|
|
75
|
+
|
|
76
|
+
resources.createGroup()
|
|
77
|
+
.addStorageBuffer("tlas", BVH_STRUCT)
|
|
78
|
+
.addStorageBuffer("scene_database", WebGPUArray.from(u32))
|
|
79
|
+
.add(MESH_SDF_HEADERS_RESOURCE);
|
|
80
|
+
|
|
81
|
+
const body = CodeChunk.from(
|
|
82
|
+
//language=WGSL
|
|
83
|
+
`
|
|
84
|
+
/** children an iteration finds at most: two a lane */
|
|
85
|
+
const MESH_BRICK_WALK_SPILL = ${2 * MESH_BRICK_BATCH}u;
|
|
86
|
+
/** rows waiting for their batch: fewer than a batch, and an iteration's at most */
|
|
87
|
+
const MESH_BRICK_WALK_ROWS = ${2 * MESH_BRICK_BATCH}u;
|
|
88
|
+
|
|
89
|
+
/** what lane 0 hands the workgroup after an iteration */
|
|
90
|
+
struct MeshBrickWalkHandoff {
|
|
91
|
+
/** the next list's appends so far: where the next iteration's start, and once the level is done, its nodes */
|
|
92
|
+
end: u32,
|
|
93
|
+
/** the iteration's children past the frontier, and the task records kept for them: the first, and how many */
|
|
94
|
+
spilled: u32,
|
|
95
|
+
tasks: u32,
|
|
96
|
+
tasks_kept: u32,
|
|
97
|
+
/** rows from 'rows_from' on the ring, and the batch records kept for them: the first, and how many */
|
|
98
|
+
rows: u32,
|
|
99
|
+
rows_from: u32,
|
|
100
|
+
batches: u32,
|
|
101
|
+
batches_kept: u32,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// the frontier: two lists of node indices, alternating by level
|
|
105
|
+
var<workgroup> walk_frontier: array<array<u32, MESH_BRICK_FRONTIER>, 2>;
|
|
106
|
+
// appends asked of each list; past the frontier they were handed on
|
|
107
|
+
var<workgroup> walk_reserved: array<atomic<u32>, 2>;
|
|
108
|
+
// the iteration's children past the frontier, on their way to task records
|
|
109
|
+
var<workgroup> walk_spill: array<u32, MESH_BRICK_WALK_SPILL>;
|
|
110
|
+
// accepted rows, a ring from the first not yet in a batch
|
|
111
|
+
var<workgroup> walk_rows: array<u32, MESH_BRICK_WALK_ROWS>;
|
|
112
|
+
var<workgroup> walk_rows_reserved: atomic<u32>;
|
|
113
|
+
|
|
114
|
+
// lane 0's words, read back through workgroupUniformLoad
|
|
115
|
+
var<workgroup> walk_task: vec3<u32>;
|
|
116
|
+
var<workgroup> walk_handoff: MeshBrickWalkHandoff;
|
|
117
|
+
|
|
118
|
+
fn bvh_node(index: u32) -> ${BVH2_NODE_STRUCT.wgsl_ref} {
|
|
119
|
+
return tlas.nodes[index];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** lane 0: a flag of the cell's for the frame; the first lists the cell for the resolve */
|
|
123
|
+
fn mesh_brick_walk_flag(build: u32, flag: u32) {
|
|
124
|
+
let flags = atomicOr(&mesh_brick_accumulators[mesh_brick_accumulator(build) + MESH_BRICK_ACCUMULATOR_FLAGS], flag);
|
|
125
|
+
|
|
126
|
+
if (flags == 0u) {
|
|
127
|
+
mesh_brick_resolves[atomicAdd(&mesh_brick_counters[${MESH_BRICK_COUNTER_RESOLVES}u], 1u)] = build;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** a task record of the half this round reads */
|
|
132
|
+
fn mesh_brick_task_in(index: u32) -> u32 {
|
|
133
|
+
return mesh_brick_record(((settings.round + 1u) & 1u) * settings.task_capacity + index);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** a task record of the half this round writes */
|
|
137
|
+
fn mesh_brick_task_out(index: u32) -> u32 {
|
|
138
|
+
return mesh_brick_record((settings.round & 1u) * settings.task_capacity + index);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* lane 0: 'records' records of a counter's, the first and how many are kept, those below 'capacity'.
|
|
143
|
+
* Whoever asked for a record below the capacity keeps it, so a command dispatches none that went unwritten.
|
|
144
|
+
*/
|
|
145
|
+
fn mesh_brick_walk_reserve(counter: u32, records: u32, capacity: u32) -> vec2<u32> {
|
|
146
|
+
let at = atomicAdd(&mesh_brick_counters[counter], records);
|
|
147
|
+
|
|
148
|
+
return vec2<u32>(at, min(records, capacity - min(at, capacity)));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** lane 0: batch records for 'rows' rows */
|
|
152
|
+
fn mesh_brick_walk_batches(build: u32, rows: u32) -> vec2<u32> {
|
|
153
|
+
if (rows == 0u) {
|
|
154
|
+
return vec2<u32>(0u);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let records = mesh_brick_records(rows);
|
|
158
|
+
let batches = mesh_brick_walk_reserve(${MESH_BRICK_COUNTER_BATCHES}u, records, settings.batch_capacity);
|
|
159
|
+
|
|
160
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_BATCHES}u], records);
|
|
161
|
+
|
|
162
|
+
if (batches.y != 0u) {
|
|
163
|
+
// the resolve merges this cell's accumulators
|
|
164
|
+
mesh_brick_walk_flag(build, MESH_BRICK_FLAG_TOUCHED);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (batches.y != records) {
|
|
168
|
+
// rows not sampled this frame: the cell is asked for again, and the capacity grows
|
|
169
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_BATCHES_DROPPED}u], records - batches.y);
|
|
170
|
+
mesh_brick_walk_flag(build, MESH_BRICK_FLAG_UNFINISHED);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return batches;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** lane 0: task records for an iteration's 'spilled' children */
|
|
177
|
+
fn mesh_brick_walk_tasks(build: u32, spilled: u32) -> vec2<u32> {
|
|
178
|
+
if (spilled == 0u) {
|
|
179
|
+
return vec2<u32>(0u);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (settings.last != 0u) {
|
|
183
|
+
// no round to hand them on to: the cell is asked for again, and the rounds grow
|
|
184
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_ROUNDS_SHORT}u], 1u);
|
|
185
|
+
mesh_brick_walk_flag(build, MESH_BRICK_FLAG_UNFINISHED);
|
|
186
|
+
|
|
187
|
+
return vec2<u32>(0u);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let records = mesh_brick_records(spilled);
|
|
191
|
+
let tasks = mesh_brick_walk_reserve(${MESH_BRICK_COUNTER_TASKS}u + (settings.round & 1u), records, settings.task_capacity);
|
|
192
|
+
|
|
193
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_TASKS}u], records);
|
|
194
|
+
|
|
195
|
+
if (tasks.y != records) {
|
|
196
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_TASKS_DROPPED}u], records - tasks.y);
|
|
197
|
+
mesh_brick_walk_flag(build, MESH_BRICK_FLAG_UNFINISHED);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return tasks;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
fn mesh_brick_walk_place(next: u32, slot: u32, start: u32, child: u32) {
|
|
204
|
+
if (slot < MESH_BRICK_FRONTIER) {
|
|
205
|
+
walk_frontier[next][slot] = child;
|
|
206
|
+
} else {
|
|
207
|
+
walk_spill[mesh_brick_walk_spill_index(slot, start)] = child;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@compute @workgroup_size(${BRICK_CELL_WORKGROUP_SIZE})
|
|
212
|
+
fn main(
|
|
213
|
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
|
214
|
+
@builtin(local_invocation_index) lane: u32,
|
|
215
|
+
) {
|
|
216
|
+
let index = folded_workgroup_index(workgroup_id);
|
|
217
|
+
|
|
218
|
+
// the round's walks: the taken cells from the root, or the tasks the round before handed on
|
|
219
|
+
if (lane == 0u) {
|
|
220
|
+
var walks: u32;
|
|
221
|
+
var build = index;
|
|
222
|
+
var roots = select(1u, 0u, tlas.root == BVH_NULL_NODE);
|
|
223
|
+
|
|
224
|
+
if (settings.round == 0u) {
|
|
225
|
+
walks = brick_take[BRICK_TAKE_COUNT];
|
|
226
|
+
|
|
227
|
+
if (index < walks) {
|
|
228
|
+
// the walk from the root opens the cell's frame, before any walk of it flags it
|
|
229
|
+
atomicStore(&mesh_brick_accumulators[mesh_brick_accumulator(build) + MESH_BRICK_ACCUMULATOR_FLAGS], 0u);
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
walks = atomicLoad(&mesh_brick_counters[${MESH_BRICK_COUNTER_ROUND_GROUPS}u]);
|
|
233
|
+
|
|
234
|
+
if (index < walks) {
|
|
235
|
+
build = mesh_brick_tasks[mesh_brick_task_in(index)];
|
|
236
|
+
roots = mesh_brick_tasks[mesh_brick_task_in(index) + 1u];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
walk_task = vec3<u32>(walks, build, roots);
|
|
241
|
+
|
|
242
|
+
// the first level appends to the second list, and no row is in yet
|
|
243
|
+
atomicStore(&walk_reserved[1], 0u);
|
|
244
|
+
atomicStore(&walk_rows_reserved, 0u);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let task = workgroupUniformLoad(&walk_task);
|
|
248
|
+
|
|
249
|
+
// a folded dispatch's tail leaves whole
|
|
250
|
+
if (index >= task.x) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
let build = task.y;
|
|
255
|
+
let at = brick_provider_cell(brick_provider_key(build, settings.ring_capacity), settings.resolution);
|
|
256
|
+
|
|
257
|
+
// every instance whose box comes within the band of the cell
|
|
258
|
+
let query = array<f32, 6>(at.corner.x - at.band, at.corner.y - at.band, at.corner.z - at.band, at.far.x + at.band, at.far.y + at.band, at.far.z + at.band);
|
|
259
|
+
|
|
260
|
+
// the first level's nodes, each read back by the lane that wrote it
|
|
261
|
+
if (settings.round == 0u) {
|
|
262
|
+
if (lane == 0u) {
|
|
263
|
+
walk_frontier[0][0] = tlas.root;
|
|
264
|
+
}
|
|
265
|
+
} else if (lane < task.z) {
|
|
266
|
+
walk_frontier[0][lane] = mesh_brick_tasks[mesh_brick_task_in(index) + MESH_BRICK_RECORD_HEADER_WORDS + lane];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
var expand_count = task.z;
|
|
270
|
+
// lane 0's: the rows handed to batches so far
|
|
271
|
+
var rows_taken = 0u;
|
|
272
|
+
// the last hand-off copied out of the spill and the ring, which the next iteration fills again
|
|
273
|
+
var copied = false;
|
|
274
|
+
|
|
275
|
+
for (var level = 0u; level < ${BVH_QUERY_AABB_LEVEL_BUDGET}u && expand_count != 0u; level++) {
|
|
276
|
+
let list = level & 1u;
|
|
277
|
+
let next = list ^ 1u;
|
|
278
|
+
let iterations = (expand_count + MESH_BRICK_BATCH - 1u) / MESH_BRICK_BATCH;
|
|
279
|
+
|
|
280
|
+
// where this iteration's children start on the next list
|
|
281
|
+
var start = 0u;
|
|
282
|
+
|
|
283
|
+
for (var iteration = 0u; iteration < iterations; iteration++) {
|
|
284
|
+
let slot = iteration * MESH_BRICK_BATCH + lane;
|
|
285
|
+
|
|
286
|
+
var node: ${BVH2_NODE_STRUCT.wgsl_ref};
|
|
287
|
+
var kind = BVH_QUERY_AABB_SKIP;
|
|
288
|
+
|
|
289
|
+
if (slot < expand_count) {
|
|
290
|
+
node = bvh_node(walk_frontier[list][slot]);
|
|
291
|
+
kind = bvh_query_aabb_classify(node.bounds, node.child_1, query);
|
|
292
|
+
|
|
293
|
+
if (kind == BVH_QUERY_AABB_LEAF && !mesh_brick_accept(node.child_2, node.bounds, at.voxel)) {
|
|
294
|
+
kind = BVH_QUERY_AABB_SKIP;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (copied) {
|
|
299
|
+
workgroupBarrier();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// every lane reserves, asking or not, so the subgroup operations stay uniform
|
|
303
|
+
let child = subgroup_reserve_workgroup(&walk_reserved[next], select(0u, 2u, kind == BVH_QUERY_AABB_DESCEND));
|
|
304
|
+
let row = subgroup_reserve_workgroup(&walk_rows_reserved, select(0u, 1u, kind == BVH_QUERY_AABB_LEAF));
|
|
305
|
+
|
|
306
|
+
if (kind == BVH_QUERY_AABB_DESCEND) {
|
|
307
|
+
mesh_brick_walk_place(next, child, start, node.child_1);
|
|
308
|
+
mesh_brick_walk_place(next, child + 1u, start, node.child_2);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (kind == BVH_QUERY_AABB_LEAF) {
|
|
312
|
+
walk_rows[row % MESH_BRICK_WALK_ROWS] = node.child_2;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// every append of the iteration has landed
|
|
316
|
+
workgroupBarrier();
|
|
317
|
+
|
|
318
|
+
// the level's last iteration settles the next level: no node on it ends the walk, and the rows left go
|
|
319
|
+
let settles = iteration + 1u == iterations;
|
|
320
|
+
|
|
321
|
+
if (lane == 0u) {
|
|
322
|
+
let end = atomicLoad(&walk_reserved[next]);
|
|
323
|
+
var ends = false;
|
|
324
|
+
|
|
325
|
+
if (settles) {
|
|
326
|
+
// the list this level read is the next level's to append to
|
|
327
|
+
atomicStore(&walk_reserved[list], 0u);
|
|
328
|
+
|
|
329
|
+
ends = end == 0u || level + 1u == ${BVH_QUERY_AABB_LEVEL_BUDGET}u;
|
|
330
|
+
|
|
331
|
+
if (end != 0u && level + 1u == ${BVH_QUERY_AABB_LEVEL_BUDGET}u) {
|
|
332
|
+
// deeper than an LBVH over 2^20 leaves goes: what is left is not walked, and the cell is asked for again
|
|
333
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_LEVELS_SHORT}u], 1u);
|
|
334
|
+
mesh_brick_walk_flag(build, MESH_BRICK_FLAG_UNFINISHED);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
let spilled = mesh_brick_walk_spilled(start, end);
|
|
339
|
+
let waiting = atomicLoad(&walk_rows_reserved) - rows_taken;
|
|
340
|
+
// whole batches as they fill, and every row left when the walk ends
|
|
341
|
+
let rows = select((waiting / MESH_BRICK_BATCH) * MESH_BRICK_BATCH, waiting, ends);
|
|
342
|
+
let tasks = mesh_brick_walk_tasks(build, spilled);
|
|
343
|
+
let batches = mesh_brick_walk_batches(build, rows);
|
|
344
|
+
|
|
345
|
+
walk_handoff = MeshBrickWalkHandoff(end, spilled, tasks.x, tasks.y, rows, rows_taken, batches.x, batches.y);
|
|
346
|
+
rows_taken += rows;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
let handoff = workgroupUniformLoad(&walk_handoff);
|
|
350
|
+
|
|
351
|
+
for (var k = 0u; k < handoff.tasks_kept; k++) {
|
|
352
|
+
let i = k * MESH_BRICK_BATCH + lane;
|
|
353
|
+
let record = mesh_brick_task_out(handoff.tasks + k);
|
|
354
|
+
|
|
355
|
+
if (i < handoff.spilled) {
|
|
356
|
+
mesh_brick_tasks[record + MESH_BRICK_RECORD_HEADER_WORDS + lane] = walk_spill[i];
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (lane == 0u) {
|
|
360
|
+
mesh_brick_tasks[record] = build;
|
|
361
|
+
mesh_brick_tasks[record + 1u] = min(MESH_BRICK_BATCH, handoff.spilled - k * MESH_BRICK_BATCH);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
for (var k = 0u; k < handoff.batches_kept; k++) {
|
|
366
|
+
let i = k * MESH_BRICK_BATCH + lane;
|
|
367
|
+
let record = mesh_brick_record(handoff.batches + k);
|
|
368
|
+
|
|
369
|
+
if (i < handoff.rows) {
|
|
370
|
+
mesh_brick_batches[record + MESH_BRICK_RECORD_HEADER_WORDS + lane] = walk_rows[(handoff.rows_from + i) % MESH_BRICK_WALK_ROWS];
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (lane == 0u) {
|
|
374
|
+
mesh_brick_batches[record] = build;
|
|
375
|
+
mesh_brick_batches[record + 1u] = min(MESH_BRICK_BATCH, handoff.rows - k * MESH_BRICK_BATCH);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
start = handoff.end;
|
|
380
|
+
copied = handoff.tasks_kept + handoff.batches_kept != 0u;
|
|
381
|
+
|
|
382
|
+
if (settles) {
|
|
383
|
+
expand_count = min(handoff.end, MESH_BRICK_FRONTIER);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
`, [
|
|
389
|
+
chunk_brick_clipmap,
|
|
390
|
+
chunk_brick_provider,
|
|
391
|
+
chunk_folded_workgroup_index,
|
|
392
|
+
chunk_bvh_query_aabb_frontier,
|
|
393
|
+
BVH_NULL_NODE_DEFINITION,
|
|
394
|
+
BVH2_NODE_STRUCT.declaration_chunk,
|
|
395
|
+
chunk_subgroup_reserve_workgroup,
|
|
396
|
+
chunk_mesh_brick_instance,
|
|
397
|
+
chunk_mesh_brick_walk,
|
|
398
|
+
]);
|
|
399
|
+
|
|
400
|
+
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* The mesh provider's walk (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §7.7, as S9 built it): every instance
|
|
404
|
+
* whose box comes within the band of a taken cell, gathered whole, a workgroup a walk.
|
|
405
|
+
*
|
|
406
|
+
* A walk expands the TLAS a level at a time, as the cooperative query does (`chunk_bvh_query_aabb_cooperative`):
|
|
407
|
+
* each node of the level is tested by a lane against the cell grown by the cascade's band, the children
|
|
408
|
+
* of an overlapping internal node go on the next level, and an overlapping leaf is a row when
|
|
409
|
+
* `mesh_brick_accept` takes it. Nothing is dropped:
|
|
410
|
+
* - a level keeps {@link MESH_BRICK_FRONTIER} nodes, and the children that fall past them are handed on in
|
|
411
|
+
* task records of up to {@link MESH_BRICK_BATCH} nodes, each a walk of the next round, which this same
|
|
412
|
+
* kernel runs from them;
|
|
413
|
+
* - rows leave in batch records of {@link MESH_BRICK_BATCH}, and the rows left when the walk ends in one
|
|
414
|
+
* more.
|
|
415
|
+
*
|
|
416
|
+
* Round 0 walks from the root, a workgroup a taken cell, dispatched by take; a later round's
|
|
417
|
+
* dispatch comes from its command (`shader_mesh_brick_command`). Round 0's walk of a cell opens the
|
|
418
|
+
* cell's frame by clearing its flags; the walk that first flags it lists it for the resolve
|
|
419
|
+
* (`mesh_brick_resolves`), so the resolve runs on the cells a batch reached or a walk could not finish,
|
|
420
|
+
* and on no other. A record the capacity cannot hold, a level past the walk's budget, or a hand-off in
|
|
421
|
+
* the frame's last round leaves the walk unfinished: it is counted, and the resolve asks for the cell
|
|
422
|
+
* again. Of the records a walk asks for at once, those below the capacity are kept, so that every record
|
|
423
|
+
* a command dispatches was written this frame.
|
|
424
|
+
*
|
|
425
|
+
* An iteration of a level costs the workgroup a barrier and a `workgroupUniformLoad`, and a barrier
|
|
426
|
+
* more after one whose hand-off copied records out: lane 0 hands every lane where the next iteration's
|
|
427
|
+
* children start and, on the level's last, how many nodes the next level holds.
|
|
428
|
+
*
|
|
429
|
+
* Per lane and level, at most {@link MESH_BRICK_FRONTIER} / {@link MESH_BRICK_BATCH} node reads, accepts
|
|
430
|
+
* and appends, over at most {@link BVH_QUERY_AABB_LEVEL_BUDGET} levels; per iteration, two task entries
|
|
431
|
+
* and two batch entries copied at most.
|
|
432
|
+
*
|
|
433
|
+
* @type {ComputeShader}
|
|
434
|
+
*/
|
|
435
|
+
export const shader_mesh_brick_gather = ComputeShader.from({
|
|
436
|
+
label: "Brick Clipmap Mesh Gather",
|
|
437
|
+
resources,
|
|
438
|
+
body,
|
|
439
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The mesh provider's resolve (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §7.7, as S9 built it): a workgroup
|
|
3
|
+
* a cell the walks listed, dispatched by its command after the batches. It merges the cell's
|
|
4
|
+
* accumulators into the staging as any provider merges (§7.6), and leaves its texel and object words
|
|
5
|
+
* at 0 for the next frame. A taken cell no walk listed, most of them, had no batch and finished its
|
|
6
|
+
* walks: its staging stays as it is, and the resolve spends nothing on it.
|
|
7
|
+
*
|
|
8
|
+
* - A cell a walk of which did not finish sets its retry word (contract 7): free puts its key back on
|
|
9
|
+
* the ring, and the cell is built again.
|
|
10
|
+
* - Contract 2, per texel of a cell a batch reached: the staged byte becomes the least of itself and
|
|
11
|
+
* the batches' byte.
|
|
12
|
+
* - Contract 3, per 2³ object cell: the batches' nearest row replaces the staged object when its byte
|
|
13
|
+
* is below the staged cell minimum taken before the merge; ties keep the staged object. The cell's
|
|
14
|
+
* four lanes fold their staged texels in through workgroup atomics, and the last of them decides, so
|
|
15
|
+
* that no lane waits on another.
|
|
16
|
+
*
|
|
17
|
+
* Eight texels a lane: the staging's two words and the accumulators' eight.
|
|
18
|
+
*
|
|
19
|
+
* @type {ComputeShader}
|
|
20
|
+
*/
|
|
21
|
+
export const shader_mesh_brick_resolve: ComputeShader;
|
|
22
|
+
import { ComputeShader } from "../../../../shader/ComputeShader.js";
|
|
23
|
+
//# sourceMappingURL=shader_mesh_brick_resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_mesh_brick_resolve.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.js"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wCAFU,aAAa,CAgGpB;8BApI2B,qCAAqC"}
|
package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { chunk_folded_workgroup_index } from "../../../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
2
|
+
import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
|
|
3
|
+
import { ComputeShader } from "../../../../shader/ComputeShader.js";
|
|
4
|
+
import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
5
|
+
import { atomic_u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
6
|
+
import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
|
|
7
|
+
import { BRICK_CELL_WORKGROUP_SIZE, BRICK_OBJECT_CELLS_PER_AXIS } from "../BRICK_CLIPMAP.js";
|
|
8
|
+
import { chunk_brick_object } from "../chunk_brick_object.js";
|
|
9
|
+
import { BRICK_STAGING_RESOURCE, chunk_brick_clipmap } from "../chunk_brick_clipmap.js";
|
|
10
|
+
import { chunk_mesh_brick_walk } from "./chunk_mesh_brick_walk.js";
|
|
11
|
+
import { MESH_BRICK_COUNTER_RESOLVE_GROUPS, MESH_BRICK_STATISTIC_CELLS_RETRIED } from "./MESH_BRICK.js";
|
|
12
|
+
|
|
13
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
14
|
+
|
|
15
|
+
resources.createGroup()
|
|
16
|
+
.add(BRICK_STAGING_RESOURCE)
|
|
17
|
+
.addStorageBuffer("mesh_brick_counters", WebGPUArray.from(atomic_u32), true)
|
|
18
|
+
.addStorageBuffer("mesh_brick_accumulators", WebGPUArray.u32, true)
|
|
19
|
+
.addStorageBuffer("mesh_brick_resolves", WebGPUArray.u32);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The mesh provider's resolve (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §7.7, as S9 built it): a workgroup
|
|
23
|
+
* a cell the walks listed, dispatched by its command after the batches. It merges the cell's
|
|
24
|
+
* accumulators into the staging as any provider merges (§7.6), and leaves its texel and object words
|
|
25
|
+
* at 0 for the next frame. A taken cell no walk listed, most of them, had no batch and finished its
|
|
26
|
+
* walks: its staging stays as it is, and the resolve spends nothing on it.
|
|
27
|
+
*
|
|
28
|
+
* - A cell a walk of which did not finish sets its retry word (contract 7): free puts its key back on
|
|
29
|
+
* the ring, and the cell is built again.
|
|
30
|
+
* - Contract 2, per texel of a cell a batch reached: the staged byte becomes the least of itself and
|
|
31
|
+
* the batches' byte.
|
|
32
|
+
* - Contract 3, per 2³ object cell: the batches' nearest row replaces the staged object when its byte
|
|
33
|
+
* is below the staged cell minimum taken before the merge; ties keep the staged object. The cell's
|
|
34
|
+
* four lanes fold their staged texels in through workgroup atomics, and the last of them decides, so
|
|
35
|
+
* that no lane waits on another.
|
|
36
|
+
*
|
|
37
|
+
* Eight texels a lane: the staging's two words and the accumulators' eight.
|
|
38
|
+
*
|
|
39
|
+
* @type {ComputeShader}
|
|
40
|
+
*/
|
|
41
|
+
export const shader_mesh_brick_resolve = ComputeShader.from({
|
|
42
|
+
label: "Brick Clipmap Mesh Resolve",
|
|
43
|
+
resources,
|
|
44
|
+
body: CodeChunk.from(
|
|
45
|
+
//language=WGSL
|
|
46
|
+
`
|
|
47
|
+
/** per object cell: its staged minimum before the merge (as 255 less the byte), and its lanes done */
|
|
48
|
+
var<workgroup> object_staged: array<atomic<u32>, ${BRICK_OBJECT_CELLS_PER_AXIS ** 3}>;
|
|
49
|
+
var<workgroup> object_lanes: array<atomic<u32>, ${BRICK_OBJECT_CELLS_PER_AXIS ** 3}>;
|
|
50
|
+
|
|
51
|
+
@compute @workgroup_size(${BRICK_CELL_WORKGROUP_SIZE})
|
|
52
|
+
fn main(
|
|
53
|
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
|
54
|
+
@builtin(local_invocation_index) lane: u32,
|
|
55
|
+
) {
|
|
56
|
+
let index = folded_workgroup_index(workgroup_id);
|
|
57
|
+
|
|
58
|
+
// a folded dispatch's tail
|
|
59
|
+
if (index >= atomicLoad(&mesh_brick_counters[${MESH_BRICK_COUNTER_RESOLVE_GROUPS}u])) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let build = mesh_brick_resolves[index];
|
|
64
|
+
let accumulator = mesh_brick_accumulator(build);
|
|
65
|
+
let flags = mesh_brick_accumulators[accumulator + MESH_BRICK_ACCUMULATOR_FLAGS];
|
|
66
|
+
|
|
67
|
+
// contract 7: a walk of the cell that did not finish asks for the cell again
|
|
68
|
+
if (lane == 0u && (flags & MESH_BRICK_FLAG_UNFINISHED) != 0u) {
|
|
69
|
+
brick_staging[build * BRICK_STAGING_WORDS + BRICK_STAGING_RETRY_WORD] = 1u;
|
|
70
|
+
|
|
71
|
+
atomicAdd(&mesh_brick_counters[${MESH_BRICK_STATISTIC_CELLS_RETRIED}u], 1u);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// listed for its retry alone: no batch reached it, and its texel and object words are 0
|
|
75
|
+
if ((flags & MESH_BRICK_FLAG_TOUCHED) == 0u) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// eight texels a lane, x fastest, at y = lane mod 8 and z = lane / 8: the staging's two words
|
|
80
|
+
let y = lane % 8u;
|
|
81
|
+
let z = lane / 8u;
|
|
82
|
+
let first = build * BRICK_STAGING_WORDS + 2u * lane;
|
|
83
|
+
|
|
84
|
+
var staged_min = vec4<u32>(255u);
|
|
85
|
+
|
|
86
|
+
for (var w = 0u; w < 2u; w++) {
|
|
87
|
+
var word = brick_staging[first + w];
|
|
88
|
+
|
|
89
|
+
for (var b = 0u; b < 4u; b++) {
|
|
90
|
+
let x = 4u * w + b;
|
|
91
|
+
let texel = accumulator + x + 8u * (y + 8u * z);
|
|
92
|
+
let shift = 8u * b;
|
|
93
|
+
let staged = (word >> shift) & 0xffu;
|
|
94
|
+
let byte = 255u - mesh_brick_accumulators[texel];
|
|
95
|
+
|
|
96
|
+
mesh_brick_accumulators[texel] = 0u;
|
|
97
|
+
|
|
98
|
+
// contract 2: the encoding is monotone, so the minimum of the bytes is the byte of the minimum
|
|
99
|
+
word = (word & ~(0xffu << shift)) | (min(staged, byte) << shift);
|
|
100
|
+
|
|
101
|
+
let o = x / 2u;
|
|
102
|
+
|
|
103
|
+
staged_min[o] = min(staged_min[o], staged);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
brick_staging[first + w] = word;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// contract 3, per object cell: its four lanes each fold in their staged texels, and the last decides
|
|
110
|
+
for (var o = 0u; o < ${BRICK_OBJECT_CELLS_PER_AXIS}u; o++) {
|
|
111
|
+
let object = o + ${BRICK_OBJECT_CELLS_PER_AXIS}u * ((y / 2u) + ${BRICK_OBJECT_CELLS_PER_AXIS}u * (z / 2u));
|
|
112
|
+
|
|
113
|
+
atomicMax(&object_staged[object], 255u - staged_min[o]);
|
|
114
|
+
|
|
115
|
+
if (atomicAdd(&object_lanes[object], 1u) != 3u) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let key = mesh_brick_accumulators[accumulator + MESH_BRICK_ACCUMULATOR_OBJECTS + object];
|
|
120
|
+
|
|
121
|
+
mesh_brick_accumulators[accumulator + MESH_BRICK_ACCUMULATOR_OBJECTS + object] = 0u;
|
|
122
|
+
|
|
123
|
+
// a bid is never 0: only a byte below 255 bids. Ties keep the staged object
|
|
124
|
+
if (key != 0u && brick_object_key_byte(key) < 255u - atomicLoad(&object_staged[object])) {
|
|
125
|
+
brick_staging[build * BRICK_STAGING_WORDS + BRICK_STAGING_DISTANCE_WORDS + object] = brick_object_key_row(key);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
`, [
|
|
130
|
+
chunk_brick_clipmap,
|
|
131
|
+
chunk_folded_workgroup_index,
|
|
132
|
+
chunk_mesh_brick_walk,
|
|
133
|
+
chunk_brick_object,
|
|
134
|
+
]),
|
|
135
|
+
});
|
package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ export const BRICK_FREE_SETTINGS: WebGPUStruct;
|
|
|
10
10
|
* the cell is within √3/2 voxel of a texel, and |∇d| ≤ 1, so a surface crossing the cell always
|
|
11
11
|
* qualifies. One that does not holds no slot: a slot it held goes back on the free list, and its
|
|
12
12
|
* entry becomes EMPTY on the side most of its texels are on. One that does and holds no slot is
|
|
13
|
-
* marked for store to pop one. Either way its key leaves the pending set, so a mover may queue it again
|
|
13
|
+
* marked for store to pop one. Either way its key leaves the pending set, so a mover may queue it again;
|
|
14
|
+
* unless a provider set the cell's retry word (§7.6, contract 7), when the key stays pending and goes
|
|
15
|
+
* back on the ring, and the cell is built again from what this frame stores.
|
|
14
16
|
*
|
|
15
17
|
* The cell's last lane to finish decides, so that nothing waits on a barrier: a lane counts itself
|
|
16
18
|
* finished in the low byte of the workgroup's tally, with a texel within a voxel in the next, and its
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_brick_clipmap_free.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_brick_clipmap_free.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js"],"names":[],"mappings":"AAoBA;;GAEG;AACH,kCAFU,YAAY,CAOE;AAexB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wCAFU,aAAa,CAgFpB;6BAvI0B,sCAAsC;8BAHrC,kCAAkC"}
|
package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js
CHANGED
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
BRICK_STAGING_RESOURCE,
|
|
15
15
|
BRICK_STATE_RESOURCE,
|
|
16
16
|
BRICK_TAKE_RESOURCE,
|
|
17
|
-
chunk_brick_clipmap
|
|
17
|
+
chunk_brick_clipmap,
|
|
18
|
+
chunk_brick_clipmap_requeue_pending
|
|
18
19
|
} from "./chunk_brick_clipmap.js";
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -48,7 +49,9 @@ resources.createGroup()
|
|
|
48
49
|
* the cell is within √3/2 voxel of a texel, and |∇d| ≤ 1, so a surface crossing the cell always
|
|
49
50
|
* qualifies. One that does not holds no slot: a slot it held goes back on the free list, and its
|
|
50
51
|
* entry becomes EMPTY on the side most of its texels are on. One that does and holds no slot is
|
|
51
|
-
* marked for store to pop one. Either way its key leaves the pending set, so a mover may queue it again
|
|
52
|
+
* marked for store to pop one. Either way its key leaves the pending set, so a mover may queue it again;
|
|
53
|
+
* unless a provider set the cell's retry word (§7.6, contract 7), when the key stays pending and goes
|
|
54
|
+
* back on the ring, and the cell is built again from what this frame stores.
|
|
52
55
|
*
|
|
53
56
|
* The cell's last lane to finish decides, so that nothing waits on a barrier: a lane counts itself
|
|
54
57
|
* finished in the low byte of the workgroup's tally, with a texel within a voxel in the next, and its
|
|
@@ -123,10 +126,16 @@ fn main(
|
|
|
123
126
|
textureStore(brick_map, texel, vec4<u32>(side, 0u, 0u, 0u));
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
if (brick_staging[build * BRICK_STAGING_WORDS + BRICK_STAGING_RETRY_WORD] != 0u) {
|
|
130
|
+
// a provider could not finish the cell: built again, its key never out of the pending set
|
|
131
|
+
brick_clipmap_requeue_pending(key, settings.ring_capacity);
|
|
132
|
+
} else {
|
|
133
|
+
atomicAnd(&brick_pending[key >> 5u], ~(1u << (key & 31u)));
|
|
134
|
+
}
|
|
127
135
|
}
|
|
128
136
|
`, [
|
|
129
137
|
chunk_brick_clipmap,
|
|
138
|
+
chunk_brick_clipmap_requeue_pending,
|
|
130
139
|
chunk_folded_workgroup_index,
|
|
131
140
|
chunk_slot_stack,
|
|
132
141
|
]),
|