@woosh/meep-engine 3.59.0 → 3.60.1
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 +10 -9
- 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 +32 -39
- 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 +65 -19
- package/src/view/elements/progress/segmented/GhostTrail.d.ts +116 -0
- package/src/view/elements/progress/segmented/GhostTrail.d.ts.map +1 -0
- package/src/view/elements/progress/segmented/GhostTrail.js +280 -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 +163 -10
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +442 -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/probe/shader_probe_clipmap_project.js
CHANGED
|
@@ -9,15 +9,19 @@ import { f32, u32 } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
|
9
9
|
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
10
10
|
import {
|
|
11
11
|
chunk_probe_clipmap,
|
|
12
|
+
chunk_probe_clipmap_guide,
|
|
13
|
+
PROBE_GUIDE_READ_RESOURCE,
|
|
12
14
|
PROBE_MAPS_READ_RESOURCE,
|
|
13
15
|
PROBE_PROJECTION_READ_RESOURCE,
|
|
14
16
|
PROBE_PROJECTION_ROW_STRUCT,
|
|
15
17
|
PROBE_PROJECTION_WRITE_RESOURCE,
|
|
16
18
|
PROBE_RECORDS_STORE_RESOURCE,
|
|
19
|
+
PROBE_REQUEST_STRUCT,
|
|
20
|
+
PROBE_REQUESTS_WRITE_RESOURCE,
|
|
17
21
|
PROBE_STATES_STORE_RESOURCE,
|
|
18
22
|
PROBE_TRACE_READ_RESOURCE
|
|
19
23
|
} from "./chunk_probe_clipmap.js";
|
|
20
|
-
import { PROBE_DEAD_BACK_FACE_SHARE, PROBE_THREAD_WORKGROUP_SIZE } from "./PROBE_CLIPMAP.js";
|
|
24
|
+
import { PROBE_CHANGE_SIGNIFICANCE, PROBE_DEAD_BACK_FACE_SHARE, PROBE_RADIANCE_SAMPLES_LIMIT, PROBE_THREAD_WORKGROUP_SIZE } from "./PROBE_CLIPMAP.js";
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
27
|
* @type {WebGPUStruct}
|
|
@@ -25,12 +29,22 @@ import { PROBE_DEAD_BACK_FACE_SHARE, PROBE_THREAD_WORKGROUP_SIZE } from "./PROBE
|
|
|
25
29
|
export const PROBE_PROJECT_SETTINGS = WebGPUStruct.from({
|
|
26
30
|
/** probes a frame updates at most: the trace list's bound */
|
|
27
31
|
trace_capacity: u32,
|
|
32
|
+
/** rays a uniform update casts, R */
|
|
33
|
+
rays_per_probe: u32,
|
|
28
34
|
/** octahedral radiance texels a side, n_r */
|
|
29
35
|
radiance_resolution: u32,
|
|
30
36
|
/** octahedral depth texels a side, n_d */
|
|
31
37
|
depth_resolution: u32,
|
|
32
|
-
/** the frame
|
|
33
|
-
|
|
38
|
+
/** the frame, of the frames the clipmap has recorded */
|
|
39
|
+
frame: u32,
|
|
40
|
+
/** updates between a probe's uniform ones, `PROBE_UNIFORM_PERIOD` */
|
|
41
|
+
uniform_period: u32,
|
|
42
|
+
/** the fewest rays an update casts, `PROBE_RAYS_PER_TEXEL_MIN` of the texels */
|
|
43
|
+
rays_min: u32,
|
|
44
|
+
/** the most rays an update casts, `PROBE_RAYS_PER_TEXEL_MAX` of the texels */
|
|
45
|
+
rays_max: u32,
|
|
46
|
+
/** the radiance's short mean's response, τ, in frames: the change score's statistics follow it */
|
|
47
|
+
response_frames: f32,
|
|
34
48
|
}, "ProbeProjectSettings");
|
|
35
49
|
|
|
36
50
|
const row_resources = new ShaderResourceSetDescriptor();
|
|
@@ -46,8 +60,9 @@ row_resources.createGroup()
|
|
|
46
60
|
* Projection, rows (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.8): a thread a row of each listed probe's
|
|
47
61
|
* radiance map, dispatched through `PROBE_DISPATCH_ROWS`. It sums the row's texels, new and kept, as
|
|
48
62
|
* irradiance SH, `convert_to_irradiance_sh(L, ω)·dω/(2π)` over each texel's solid angle, so that the
|
|
49
|
-
* resolve gives E/π;
|
|
50
|
-
*
|
|
63
|
+
* resolve gives E/π; the row's rays this update, resolved and back faces; and how far the update's
|
|
64
|
+
* samples fell from their means, with that sum's variance. One row of the probe's projection each, which
|
|
65
|
+
* the probe's pass sums.
|
|
51
66
|
*
|
|
52
67
|
* @type {ComputeShader}
|
|
53
68
|
*/
|
|
@@ -84,11 +99,14 @@ fn main(
|
|
|
84
99
|
let weight = octahedral_solid_angle(uv, inverse) * ${(0.5 / Math.PI).toPrecision(17)};
|
|
85
100
|
let sh = convert_to_irradiance_sh(light, uv_octahedral_unit_decode(uv));
|
|
86
101
|
let rays = probe_maps[maps + 2u * texels + i];
|
|
102
|
+
let change = unpack2x16float(probe_maps[maps + 3u * texels + settings.depth_resolution * settings.depth_resolution + i]);
|
|
87
103
|
|
|
88
104
|
row_sum.sh.CoCg += sh.CoCg * weight;
|
|
89
105
|
row_sum.sh.Y += sh.Y * weight;
|
|
90
106
|
row_sum.resolved += rays & 0xFFFFu;
|
|
91
107
|
row_sum.back_faces += rays >> 16u;
|
|
108
|
+
row_sum.change += change.x;
|
|
109
|
+
row_sum.blended += change.y;
|
|
92
110
|
}
|
|
93
111
|
|
|
94
112
|
probe_projection[thread] = row_sum;
|
|
@@ -110,8 +128,10 @@ probe_resources.setImmediate("settings", PROBE_PROJECT_SETTINGS);
|
|
|
110
128
|
probe_resources.createGroup()
|
|
111
129
|
.add(PROBE_TRACE_READ_RESOURCE)
|
|
112
130
|
.add(PROBE_PROJECTION_READ_RESOURCE)
|
|
131
|
+
.add(PROBE_GUIDE_READ_RESOURCE)
|
|
113
132
|
.add(PROBE_STATES_STORE_RESOURCE)
|
|
114
|
-
.add(PROBE_RECORDS_STORE_RESOURCE)
|
|
133
|
+
.add(PROBE_RECORDS_STORE_RESOURCE)
|
|
134
|
+
.add(PROBE_REQUESTS_WRITE_RESOURCE);
|
|
115
135
|
|
|
116
136
|
/**
|
|
117
137
|
* Projection, probes (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.4, §8.8): a thread a listed probe,
|
|
@@ -119,6 +139,27 @@ probe_resources.createGroup()
|
|
|
119
139
|
* by the update's resolved rays: dead past a quarter of back faces, else alive, its update counted and
|
|
120
140
|
* its time the frame's. An update with no resolved ray keeps the probe's kind.
|
|
121
141
|
*
|
|
142
|
+
* Only uniform rays classify. Those are a uniform update's, and a guided update's whose guide weighs
|
|
143
|
+
* nothing (a dark history), which spreads its rays evenly. A guided update's rays shun back faces, whose
|
|
144
|
+
* radiance is nothing, so their share would read a probe inside a solid as alive. Such an update keeps
|
|
145
|
+
* the probe's kind and its back-face share.
|
|
146
|
+
*
|
|
147
|
+
* **The probe's ray request** (§8.6): the rays its next guided update asks for, in `probe_requests`.
|
|
148
|
+
* - After a probe's first update, the most: Enshrouded's new probe that asks for all it can have.
|
|
149
|
+
* - When its light has moved, the most again. The update's change score sums its blended texels' falls
|
|
150
|
+
* from their means, luminance, each in its own deviation and held to `PROBE_CHANGE_SIGNIFICANCE` by
|
|
151
|
+
* accumulation, over the root of their count. A test texel by texel sees no change under a one-ray
|
|
152
|
+
* texel's own noise (measured: the estimator's inconsistency barely moves on a doubling); a sum of the
|
|
153
|
+
* falls unbounded is one bright sample's.
|
|
154
|
+
* - The score is held to the probe's own: moved means past `PROBE_CHANGE_SIGNIFICANCE` of its running
|
|
155
|
+
* deviation, at least one, from its running mean, both over the estimator's variance window (2τ). A
|
|
156
|
+
* probe whose means sit off its samples (the estimator's own bias on texels lit by few rays) scores
|
|
157
|
+
* steadily off zero.
|
|
158
|
+
* - Measured, Sponza on the 4090, the camera and the light still, 3,600 frames settled: of the probes
|
|
159
|
+
* past 64 updates, 4.2% asked for the most against a sum of the raw falls held to zero, 3.2% with each
|
|
160
|
+
* texel's fall bounded, and 1.1–1.3% held to their own statistics.
|
|
161
|
+
* - Otherwise half what it asked for last, down to the fewest: a converged probe sips.
|
|
162
|
+
*
|
|
122
163
|
* @type {ComputeShader}
|
|
123
164
|
*/
|
|
124
165
|
export const shader_probe_clipmap_project = ComputeShader.from({
|
|
@@ -150,6 +191,8 @@ fn main(
|
|
|
150
191
|
sum.sh.Y += part.sh.Y;
|
|
151
192
|
sum.resolved += part.resolved;
|
|
152
193
|
sum.back_faces += part.back_faces;
|
|
194
|
+
sum.change += part.change;
|
|
195
|
+
sum.blended += part.blended;
|
|
153
196
|
}
|
|
154
197
|
|
|
155
198
|
let state = probe_states[slot].x;
|
|
@@ -157,21 +200,58 @@ fn main(
|
|
|
157
200
|
|
|
158
201
|
var kind = probe_state_kind(state);
|
|
159
202
|
|
|
160
|
-
|
|
203
|
+
// the guide's total, less the even shares, is the weight its luminance gave
|
|
204
|
+
let header = k * probe_clipmap_guide_words(n) + 2u * n * n + 2u * n;
|
|
205
|
+
let weighed = probe_guide[header] != probe_guide[header + 1u] * n * n;
|
|
206
|
+
let uniform = !probe_clipmap_guided(state, settings.uniform_period, settings.rays_per_probe, n * n) || !weighed;
|
|
207
|
+
|
|
208
|
+
if (sum.resolved > 0u && uniform) {
|
|
161
209
|
let share = f32(sum.back_faces) / f32(sum.resolved);
|
|
162
210
|
|
|
163
211
|
kind = select(PROBE_STATE_ALIVE, PROBE_STATE_DEAD, share > ${PROBE_DEAD_BACK_FACE_SHARE});
|
|
164
212
|
|
|
165
|
-
probe_records[slot].
|
|
213
|
+
probe_records[slot].flags = (probe_records[slot].flags & 0xFFFF0000u) | probe_record_flags(share, false, 0u);
|
|
166
214
|
}
|
|
167
215
|
|
|
216
|
+
let elapsed = f32(settings.frame - probe_records[slot].traced_frame);
|
|
217
|
+
|
|
168
218
|
probe_states[slot].x = probe_state(kind, updates + 1u);
|
|
169
|
-
probe_records[slot].sh = sum.sh;
|
|
170
|
-
probe_records[slot].
|
|
219
|
+
probe_records[slot].sh = probe_record_sh_encode(sum.sh);
|
|
220
|
+
probe_records[slot].traced_frame = settings.frame;
|
|
221
|
+
|
|
222
|
+
// the next guided update's rays: the most after the first update and whenever the light moved, else half
|
|
223
|
+
var request = probe_requests[slot];
|
|
224
|
+
|
|
225
|
+
if (updates == 0u) {
|
|
226
|
+
// its slot's last owner's statistics are not its own
|
|
227
|
+
request = ${PROBE_REQUEST_STRUCT.make({ rays: "settings.rays_max", change_mean: "0.0", change_variance: "0.0", changes: "0u" })};
|
|
228
|
+
} else if (sum.blended > 0.0) {
|
|
229
|
+
let score = sum.change / sqrt(sum.blended);
|
|
230
|
+
let reach = ${PROBE_CHANGE_SIGNIFICANCE} * max(sqrt(request.change_variance), 1.0);
|
|
231
|
+
let moved = abs(score - request.change_mean) > reach;
|
|
232
|
+
|
|
233
|
+
// the score's running statistics, a running mean while young, then over the estimator's variance
|
|
234
|
+
// window; a score past their reach counts at it, so a change in the light does not become the probe's
|
|
235
|
+
// own spread, while a lasting shift of its own still does within a few windows
|
|
236
|
+
let held = clamp(score, request.change_mean - reach, request.change_mean + reach);
|
|
237
|
+
let blend = max(1.0 / f32(request.changes + 1u), 1.0 - exp(-0.5 * elapsed / settings.response_frames));
|
|
238
|
+
let mean = mix(request.change_mean, held, blend);
|
|
239
|
+
|
|
240
|
+
request.change_variance = mix(request.change_variance, (held - request.change_mean) * (held - mean), blend);
|
|
241
|
+
request.change_mean = mean;
|
|
242
|
+
request.changes = min(request.changes + 1u, ${PROBE_RADIANCE_SAMPLES_LIMIT}u);
|
|
243
|
+
request.rays = select(max(settings.rays_min, request.rays >> 1u), settings.rays_max, moved);
|
|
244
|
+
} else {
|
|
245
|
+
request.rays = max(settings.rays_min, request.rays >> 1u);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
probe_requests[slot] = request;
|
|
171
249
|
}
|
|
172
250
|
`, [
|
|
173
251
|
chunk_probe_clipmap,
|
|
252
|
+
chunk_probe_clipmap_guide,
|
|
174
253
|
chunk_folded_workgroup_index,
|
|
175
254
|
PROBE_PROJECTION_ROW_STRUCT.declaration_chunk,
|
|
255
|
+
PROBE_REQUEST_STRUCT.declaration_chunk,
|
|
176
256
|
]),
|
|
177
257
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type {WebGPUStruct}
|
|
3
|
+
*/
|
|
4
|
+
export const PROBE_RAY_COUNTS_SETTINGS: WebGPUStruct;
|
|
5
|
+
/**
|
|
6
|
+
* The ray counts (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.6): a thread a listed probe, dispatched through
|
|
7
|
+
* `PROBE_DISPATCH_TRACED`, writes the rays its update casts, as two parts whose counts the trace command
|
|
8
|
+
* wrote:
|
|
9
|
+
* - `probe_ray_counts`, what the budget does not scale: a uniform update's R, a NEW probe's among them,
|
|
10
|
+
* and a DEAD probe's fewest, whose updates are all uniform. A uniform update's map of rays to texels
|
|
11
|
+
* takes a power of two, and U = ⌊budget / R⌋ makes room for a frame of them.
|
|
12
|
+
* - `probe_ray_requests`, what it does: a guided update's request, the rays the probe asked for after its
|
|
13
|
+
* last update (`probe_requests`), at least the fewest.
|
|
14
|
+
*
|
|
15
|
+
* Their scans, and the ray layout pass after them, lay the frame's rays out (`probe_ray_sums`).
|
|
16
|
+
*
|
|
17
|
+
* @type {ComputeShader}
|
|
18
|
+
*/
|
|
19
|
+
export const shader_probe_clipmap_ray_counts: ComputeShader;
|
|
20
|
+
/**
|
|
21
|
+
* @type {WebGPUStruct}
|
|
22
|
+
*/
|
|
23
|
+
export const PROBE_RAY_LAYOUT_SETTINGS: WebGPUStruct;
|
|
24
|
+
/**
|
|
25
|
+
* The ray layout (§8.6): a thread a listed probe, dispatched through `PROBE_DISPATCH_TRACED`, once the
|
|
26
|
+
* counts and the requests are scanned. The requests share what the budget leaves past the counts, all of
|
|
27
|
+
* them when they fit, in proportion when they do not (Enshrouded's requests scaled to the budget), and
|
|
28
|
+
* the k-th probe's rays end at its counts' sum and its requests' sum so scaled, rounded down. The rounded
|
|
29
|
+
* sums never fall as k rises and their last is under the budget, so the probes' rays partition the
|
|
30
|
+
* frame's without a second scan. The trace command wrote the sums' count.
|
|
31
|
+
*
|
|
32
|
+
* @type {ComputeShader}
|
|
33
|
+
*/
|
|
34
|
+
export const shader_probe_clipmap_ray_layout: ComputeShader;
|
|
35
|
+
/**
|
|
36
|
+
* The rays' command (§8.6): one thread, once the rays are laid out, writes a thread a ray of the frame's,
|
|
37
|
+
* its count the last sum, at `PROBE_DISPATCH_RAYS`: trace, shade, light, and the next frame's hits'
|
|
38
|
+
* wants. The last workgroup's threads past the last ray are trace's to mark (`PROBE_RAY_NONE`).
|
|
39
|
+
*
|
|
40
|
+
* @type {ComputeShader}
|
|
41
|
+
*/
|
|
42
|
+
export const shader_probe_clipmap_ray_command: ComputeShader;
|
|
43
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
44
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
45
|
+
//# sourceMappingURL=shader_probe_clipmap_ray_layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_probe_clipmap_ray_layout.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.js"],"names":[],"mappings":"AAuBA;;GAEG;AACH,wCAFU,YAAY,CAaO;AAa7B;;;;;;;;;;;;;GAaG;AACH,8CAFU,aAAa,CAyCpB;AAEH;;GAEG;AACH,wCAFU,YAAY,CAOO;AAW7B;;;;;;;;;GASG;AACH,8CAFU,aAAa,CA+BpB;AAQH;;;;;;GAMG;AACH,+CAFU,aAAa,CA4BpB;6BAtM0B,sCAAsC;8BAHrC,kCAAkC"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { chunk_folded_dispatch } from "../../../gpu_primitive/indirect/chunk_folded_dispatch.js";
|
|
2
|
+
import { chunk_folded_workgroup_index } from "../../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
3
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
4
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
5
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
6
|
+
import { u32 } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
7
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
8
|
+
import {
|
|
9
|
+
chunk_probe_clipmap,
|
|
10
|
+
chunk_probe_clipmap_guide,
|
|
11
|
+
PROBE_DISPATCH_RESOURCE,
|
|
12
|
+
PROBE_RAY_COUNT_SUMS_READ_RESOURCE,
|
|
13
|
+
PROBE_RAY_COUNTS_WRITE_RESOURCE,
|
|
14
|
+
PROBE_RAY_REQUEST_SUMS_READ_RESOURCE,
|
|
15
|
+
PROBE_RAY_REQUESTS_WRITE_RESOURCE,
|
|
16
|
+
PROBE_RAY_SUMS_READ_RESOURCE,
|
|
17
|
+
PROBE_RAY_SUMS_WRITE_RESOURCE,
|
|
18
|
+
PROBE_REQUESTS_READ_RESOURCE,
|
|
19
|
+
PROBE_STATES_READ_RESOURCE,
|
|
20
|
+
PROBE_TRACE_READ_RESOURCE
|
|
21
|
+
} from "./chunk_probe_clipmap.js";
|
|
22
|
+
import { PROBE_THREAD_WORKGROUP_SIZE } from "./PROBE_CLIPMAP.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @type {WebGPUStruct}
|
|
26
|
+
*/
|
|
27
|
+
export const PROBE_RAY_COUNTS_SETTINGS = WebGPUStruct.from({
|
|
28
|
+
/** probes a frame updates at most: the trace list's bound */
|
|
29
|
+
trace_capacity: u32,
|
|
30
|
+
/** rays a uniform update casts, R */
|
|
31
|
+
rays_per_probe: u32,
|
|
32
|
+
/** the fewest rays an update casts, a DEAD probe's, `PROBE_RAYS_PER_TEXEL_MIN` of the texels */
|
|
33
|
+
rays_min: u32,
|
|
34
|
+
/** octahedral radiance texels a side, n_r */
|
|
35
|
+
radiance_resolution: u32,
|
|
36
|
+
/** updates between a probe's uniform ones, `PROBE_UNIFORM_PERIOD` */
|
|
37
|
+
uniform_period: u32,
|
|
38
|
+
}, "ProbeRayCountsSettings");
|
|
39
|
+
|
|
40
|
+
const counts_resources = new ShaderResourceSetDescriptor();
|
|
41
|
+
|
|
42
|
+
counts_resources.setImmediate("settings", PROBE_RAY_COUNTS_SETTINGS);
|
|
43
|
+
|
|
44
|
+
counts_resources.createGroup()
|
|
45
|
+
.add(PROBE_TRACE_READ_RESOURCE)
|
|
46
|
+
.add(PROBE_STATES_READ_RESOURCE)
|
|
47
|
+
.add(PROBE_REQUESTS_READ_RESOURCE)
|
|
48
|
+
.add(PROBE_RAY_COUNTS_WRITE_RESOURCE)
|
|
49
|
+
.add(PROBE_RAY_REQUESTS_WRITE_RESOURCE);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The ray counts (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.6): a thread a listed probe, dispatched through
|
|
53
|
+
* `PROBE_DISPATCH_TRACED`, writes the rays its update casts, as two parts whose counts the trace command
|
|
54
|
+
* wrote:
|
|
55
|
+
* - `probe_ray_counts`, what the budget does not scale: a uniform update's R, a NEW probe's among them,
|
|
56
|
+
* and a DEAD probe's fewest, whose updates are all uniform. A uniform update's map of rays to texels
|
|
57
|
+
* takes a power of two, and U = ⌊budget / R⌋ makes room for a frame of them.
|
|
58
|
+
* - `probe_ray_requests`, what it does: a guided update's request, the rays the probe asked for after its
|
|
59
|
+
* last update (`probe_requests`), at least the fewest.
|
|
60
|
+
*
|
|
61
|
+
* Their scans, and the ray layout pass after them, lay the frame's rays out (`probe_ray_sums`).
|
|
62
|
+
*
|
|
63
|
+
* @type {ComputeShader}
|
|
64
|
+
*/
|
|
65
|
+
export const shader_probe_clipmap_ray_counts = ComputeShader.from({
|
|
66
|
+
label: "Probe Clipmap Ray Counts",
|
|
67
|
+
resources: counts_resources,
|
|
68
|
+
body: CodeChunk.from(
|
|
69
|
+
//language=WGSL
|
|
70
|
+
`
|
|
71
|
+
@compute @workgroup_size(${PROBE_THREAD_WORKGROUP_SIZE})
|
|
72
|
+
fn main(
|
|
73
|
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
|
74
|
+
@builtin(local_invocation_index) lane: u32,
|
|
75
|
+
) {
|
|
76
|
+
let k = folded_workgroup_index(workgroup_id) * PROBE_THREAD_WORKGROUP_SIZE + lane;
|
|
77
|
+
|
|
78
|
+
if (k >= min(probe_trace.count, settings.trace_capacity)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let slot = probe_trace.elements[k];
|
|
83
|
+
let state = probe_states[slot].x;
|
|
84
|
+
let n = settings.radiance_resolution;
|
|
85
|
+
|
|
86
|
+
var fixed = settings.rays_per_probe;
|
|
87
|
+
var request = 0u;
|
|
88
|
+
|
|
89
|
+
if (probe_state_kind(state) == PROBE_STATE_DEAD) {
|
|
90
|
+
fixed = settings.rays_min;
|
|
91
|
+
} else if (probe_clipmap_guided(state, settings.uniform_period, settings.rays_per_probe, n * n)) {
|
|
92
|
+
fixed = 0u;
|
|
93
|
+
request = max(probe_requests[slot].rays, settings.rays_min);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
probe_ray_counts.elements[k] = fixed;
|
|
97
|
+
probe_ray_requests.elements[k] = request;
|
|
98
|
+
}
|
|
99
|
+
`, [
|
|
100
|
+
chunk_probe_clipmap,
|
|
101
|
+
chunk_probe_clipmap_guide,
|
|
102
|
+
chunk_folded_workgroup_index,
|
|
103
|
+
]),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @type {WebGPUStruct}
|
|
108
|
+
*/
|
|
109
|
+
export const PROBE_RAY_LAYOUT_SETTINGS = WebGPUStruct.from({
|
|
110
|
+
/** probes a frame updates at most: the trace list's bound */
|
|
111
|
+
trace_capacity: u32,
|
|
112
|
+
/** rays a frame casts at most */
|
|
113
|
+
ray_budget: u32,
|
|
114
|
+
}, "ProbeRayLayoutSettings");
|
|
115
|
+
|
|
116
|
+
const layout_resources = new ShaderResourceSetDescriptor();
|
|
117
|
+
|
|
118
|
+
layout_resources.setImmediate("settings", PROBE_RAY_LAYOUT_SETTINGS);
|
|
119
|
+
|
|
120
|
+
layout_resources.createGroup()
|
|
121
|
+
.add(PROBE_RAY_COUNT_SUMS_READ_RESOURCE)
|
|
122
|
+
.add(PROBE_RAY_REQUEST_SUMS_READ_RESOURCE)
|
|
123
|
+
.add(PROBE_RAY_SUMS_WRITE_RESOURCE);
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The ray layout (§8.6): a thread a listed probe, dispatched through `PROBE_DISPATCH_TRACED`, once the
|
|
127
|
+
* counts and the requests are scanned. The requests share what the budget leaves past the counts, all of
|
|
128
|
+
* them when they fit, in proportion when they do not (Enshrouded's requests scaled to the budget), and
|
|
129
|
+
* the k-th probe's rays end at its counts' sum and its requests' sum so scaled, rounded down. The rounded
|
|
130
|
+
* sums never fall as k rises and their last is under the budget, so the probes' rays partition the
|
|
131
|
+
* frame's without a second scan. The trace command wrote the sums' count.
|
|
132
|
+
*
|
|
133
|
+
* @type {ComputeShader}
|
|
134
|
+
*/
|
|
135
|
+
export const shader_probe_clipmap_ray_layout = ComputeShader.from({
|
|
136
|
+
label: "Probe Clipmap Ray Layout",
|
|
137
|
+
resources: layout_resources,
|
|
138
|
+
body: CodeChunk.from(
|
|
139
|
+
//language=WGSL
|
|
140
|
+
`
|
|
141
|
+
@compute @workgroup_size(${PROBE_THREAD_WORKGROUP_SIZE})
|
|
142
|
+
fn main(
|
|
143
|
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
|
144
|
+
@builtin(local_invocation_index) lane: u32,
|
|
145
|
+
) {
|
|
146
|
+
let k = folded_workgroup_index(workgroup_id) * PROBE_THREAD_WORKGROUP_SIZE + lane;
|
|
147
|
+
let listed = probe_ray_count_sums.count;
|
|
148
|
+
|
|
149
|
+
if (k >= listed) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let counted = probe_ray_count_sums.elements[listed - 1u];
|
|
154
|
+
let requested = probe_ray_request_sums.elements[listed - 1u];
|
|
155
|
+
let room = select(0u, settings.ray_budget - counted, settings.ray_budget > counted);
|
|
156
|
+
let scale = select(1.0, f32(room) / f32(requested), requested > room);
|
|
157
|
+
|
|
158
|
+
probe_ray_sums.elements[k] = probe_ray_count_sums.elements[k] + u32(floor(scale * f32(probe_ray_request_sums.elements[k])));
|
|
159
|
+
}
|
|
160
|
+
`, [
|
|
161
|
+
chunk_probe_clipmap,
|
|
162
|
+
chunk_folded_workgroup_index,
|
|
163
|
+
]),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const command_resources = new ShaderResourceSetDescriptor();
|
|
167
|
+
|
|
168
|
+
command_resources.createGroup()
|
|
169
|
+
.add(PROBE_RAY_SUMS_READ_RESOURCE)
|
|
170
|
+
.add(PROBE_DISPATCH_RESOURCE);
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The rays' command (§8.6): one thread, once the rays are laid out, writes a thread a ray of the frame's,
|
|
174
|
+
* its count the last sum, at `PROBE_DISPATCH_RAYS`: trace, shade, light, and the next frame's hits'
|
|
175
|
+
* wants. The last workgroup's threads past the last ray are trace's to mark (`PROBE_RAY_NONE`).
|
|
176
|
+
*
|
|
177
|
+
* @type {ComputeShader}
|
|
178
|
+
*/
|
|
179
|
+
export const shader_probe_clipmap_ray_command = ComputeShader.from({
|
|
180
|
+
label: "Probe Clipmap Ray Command",
|
|
181
|
+
resources: command_resources,
|
|
182
|
+
body: CodeChunk.from(
|
|
183
|
+
//language=WGSL
|
|
184
|
+
`
|
|
185
|
+
@compute @workgroup_size(1)
|
|
186
|
+
fn main() {
|
|
187
|
+
let listed = probe_ray_sums.count;
|
|
188
|
+
|
|
189
|
+
var total = 0u;
|
|
190
|
+
|
|
191
|
+
if (listed > 0u) {
|
|
192
|
+
total = probe_ray_sums.elements[listed - 1u];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let rays = folded_dispatch((total + PROBE_THREAD_WORKGROUP_SIZE - 1u) / PROBE_THREAD_WORKGROUP_SIZE);
|
|
196
|
+
|
|
197
|
+
probe_dispatch[PROBE_DISPATCH_RAYS] = rays.x;
|
|
198
|
+
probe_dispatch[PROBE_DISPATCH_RAYS + 1u] = rays.y;
|
|
199
|
+
probe_dispatch[PROBE_DISPATCH_RAYS + 2u] = rays.z;
|
|
200
|
+
}
|
|
201
|
+
`, [
|
|
202
|
+
chunk_probe_clipmap,
|
|
203
|
+
chunk_folded_dispatch,
|
|
204
|
+
]),
|
|
205
|
+
});
|
package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js
CHANGED
|
@@ -87,7 +87,7 @@ fn main(
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
let slot = probe_trace.elements[index];
|
|
90
|
-
let spacing = probe_levels[probe_records[slot].
|
|
90
|
+
let spacing = probe_levels[probe_record_cascade(probe_records[slot].flags)].cell_size;
|
|
91
91
|
let lattice = vec3<f32>(probe_records[slot].cell) * spacing;
|
|
92
92
|
let clearance = ${PROBE_RELOCATION_CLEARANCE} * spacing;
|
|
93
93
|
|
package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts
CHANGED
|
@@ -6,9 +6,22 @@ export const PROBE_RETIRE_SETTINGS: WebGPUStruct;
|
|
|
6
6
|
* Retire (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): a thread a live probe, the first of the frame's
|
|
7
7
|
* lifetime passes, dispatched through `PROBE_DISPATCH_ACTIVE` over the list the frame before wrote.
|
|
8
8
|
*
|
|
9
|
-
* A probe is freed when its lattice point has left its cascade's window, or when
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* A probe is freed when its lattice point has left its cascade's window, or when the last frame's
|
|
10
|
+
* schedule asked for its slot: its slot goes back on the free list, its state to FREE, and its
|
|
11
|
+
* indirection entry, if it still names the slot, to none. The rest go on the frame's list.
|
|
12
|
+
*
|
|
13
|
+
* Eviction follows the pressure on the slots, not a time (Enshrouded's cache): schedule asks for as many
|
|
14
|
+
* slots as the free ones are short of the frame's wanted points and `PROBE_FREE_SLACK` of the capacity,
|
|
15
|
+
* least recently wanted first, so with room to spare a probe keeps its history however long nothing
|
|
16
|
+
* wants it. It asks by the probes' age buckets (`probe_clipmap_age_bucket` of the frames since the probe
|
|
17
|
+
* was last wanted), `PROBE_EVICTION_STRUCT`: the oldest buckets whole, and a number of the bucket below
|
|
18
|
+
* them, which the frame's threads take while `PROBE_COUNTER_EVICTED` is under it. A probe in use is
|
|
19
|
+
* never evicted: one a want waits on, NEW or wanted since its last update, and one wanted the last
|
|
20
|
+
* frame. Where those fill the slots, an admission starves and the capacity grows (§7.10).
|
|
21
|
+
*
|
|
22
|
+
* Every probe it keeps that it could have evicted is counted into its age's bucket, from
|
|
23
|
+
* `PROBE_COUNTER_AGES`, for the frame's schedule to choose the next eviction by; and every one it keeps
|
|
24
|
+
* that waits for an update into `PROBE_COUNTER_WAITING`, for the period.
|
|
12
25
|
*
|
|
13
26
|
* Running before want means a window's move needs no pass of its own: the storage cells it vacated
|
|
14
27
|
* are emptied before any point it exposed can claim them.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_probe_clipmap_retire.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_probe_clipmap_retire.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js"],"names":[],"mappings":"AAyBA;;GAEG;AACH,oCAFU,YAAY,CASI;AAiB1B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,0CAFU,aAAa,CAsFpB;6BAxJ0B,sCAAsC;8BAHrC,kCAAkC"}
|
package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js
CHANGED
|
@@ -3,16 +3,18 @@ import { chunk_slot_stack } from "../../../gpu_primitive/slot_stack/chunk_slot_s
|
|
|
3
3
|
import { chunk_clipmap_contains } from "../../../shader/chunk/clipmap/chunk_clipmap_contains.js";
|
|
4
4
|
import { chunk_clipmap_storage_coord } from "../../../shader/chunk/clipmap/chunk_clipmap_storage_coord.js";
|
|
5
5
|
import { chunk_folded_workgroup_index } from "../../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
6
|
+
import { chunk_subgroup_atomic_add } from "../../../shader/chunk/subgroup/chunk_subgroup_atomic_add.js";
|
|
6
7
|
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
7
8
|
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
8
9
|
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
9
|
-
import {
|
|
10
|
+
import { u32 } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
10
11
|
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
11
12
|
import {
|
|
12
13
|
chunk_probe_clipmap,
|
|
13
14
|
PROBE_ACTIVE_READ_RESOURCE,
|
|
14
15
|
PROBE_ACTIVE_WRITE_RESOURCE,
|
|
15
16
|
PROBE_COUNTERS_RESOURCE,
|
|
17
|
+
PROBE_EVICTION_READ_RESOURCE,
|
|
16
18
|
PROBE_FREE_RESOURCE,
|
|
17
19
|
PROBE_INDIRECTION_STORE_RESOURCE,
|
|
18
20
|
PROBE_LEVELS_RESOURCE,
|
|
@@ -29,10 +31,8 @@ export const PROBE_RETIRE_SETTINGS = WebGPUStruct.from({
|
|
|
29
31
|
capacity: u32,
|
|
30
32
|
/** lattice points a cascade's window has a side */
|
|
31
33
|
resolution: u32,
|
|
32
|
-
/** the frame
|
|
33
|
-
|
|
34
|
-
/** seconds an unwanted probe keeps its slot, `retention_time` */
|
|
35
|
-
retention_time: f32,
|
|
34
|
+
/** the frame, of the frames the clipmap has recorded: a probe wanted the frame before it or since is not evicted */
|
|
35
|
+
frame: u32,
|
|
36
36
|
}, "ProbeRetireSettings");
|
|
37
37
|
|
|
38
38
|
const resources = new ShaderResourceSetDescriptor();
|
|
@@ -45,6 +45,7 @@ resources.createGroup()
|
|
|
45
45
|
.add(PROBE_STATES_STORE_RESOURCE)
|
|
46
46
|
.add(PROBE_RECORDS_STORE_RESOURCE)
|
|
47
47
|
.add(PROBE_COUNTERS_RESOURCE)
|
|
48
|
+
.add(PROBE_EVICTION_READ_RESOURCE)
|
|
48
49
|
.add(PROBE_FREE_RESOURCE)
|
|
49
50
|
.add(PROBE_ACTIVE_READ_RESOURCE)
|
|
50
51
|
.add(PROBE_ACTIVE_WRITE_RESOURCE);
|
|
@@ -53,9 +54,22 @@ resources.createGroup()
|
|
|
53
54
|
* Retire (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): a thread a live probe, the first of the frame's
|
|
54
55
|
* lifetime passes, dispatched through `PROBE_DISPATCH_ACTIVE` over the list the frame before wrote.
|
|
55
56
|
*
|
|
56
|
-
* A probe is freed when its lattice point has left its cascade's window, or when
|
|
57
|
-
*
|
|
58
|
-
*
|
|
57
|
+
* A probe is freed when its lattice point has left its cascade's window, or when the last frame's
|
|
58
|
+
* schedule asked for its slot: its slot goes back on the free list, its state to FREE, and its
|
|
59
|
+
* indirection entry, if it still names the slot, to none. The rest go on the frame's list.
|
|
60
|
+
*
|
|
61
|
+
* Eviction follows the pressure on the slots, not a time (Enshrouded's cache): schedule asks for as many
|
|
62
|
+
* slots as the free ones are short of the frame's wanted points and `PROBE_FREE_SLACK` of the capacity,
|
|
63
|
+
* least recently wanted first, so with room to spare a probe keeps its history however long nothing
|
|
64
|
+
* wants it. It asks by the probes' age buckets (`probe_clipmap_age_bucket` of the frames since the probe
|
|
65
|
+
* was last wanted), `PROBE_EVICTION_STRUCT`: the oldest buckets whole, and a number of the bucket below
|
|
66
|
+
* them, which the frame's threads take while `PROBE_COUNTER_EVICTED` is under it. A probe in use is
|
|
67
|
+
* never evicted: one a want waits on, NEW or wanted since its last update, and one wanted the last
|
|
68
|
+
* frame. Where those fill the slots, an admission starves and the capacity grows (§7.10).
|
|
69
|
+
*
|
|
70
|
+
* Every probe it keeps that it could have evicted is counted into its age's bucket, from
|
|
71
|
+
* `PROBE_COUNTER_AGES`, for the frame's schedule to choose the next eviction by; and every one it keeps
|
|
72
|
+
* that waits for an update into `PROBE_COUNTER_WAITING`, for the period.
|
|
59
73
|
*
|
|
60
74
|
* Running before want means a window's move needs no pass of its own: the storage cells it vacated
|
|
61
75
|
* are emptied before any point it exposed can claim them.
|
|
@@ -77,18 +91,43 @@ fn main(
|
|
|
77
91
|
|
|
78
92
|
var slot = 0u;
|
|
79
93
|
var keep = false;
|
|
94
|
+
var waiting = false;
|
|
95
|
+
var evictable = false;
|
|
96
|
+
var bucket = 0u;
|
|
80
97
|
|
|
81
98
|
if (index < min(probe_active_read.count, settings.capacity)) {
|
|
82
99
|
slot = probe_active_read.elements[index];
|
|
83
100
|
|
|
84
101
|
let cell = probe_records[slot].cell;
|
|
85
|
-
let cascade = probe_records[slot].
|
|
102
|
+
let cascade = probe_record_cascade(probe_records[slot].flags);
|
|
86
103
|
let level = probe_levels[cascade];
|
|
104
|
+
let wanted_frame = probe_records[slot].wanted_frame;
|
|
87
105
|
|
|
88
106
|
// the lattice's window is one point wider than the cages' on each axis
|
|
89
107
|
let held = clipmap_contains(cell, level.corner, level.size + vec3<i32>(1));
|
|
90
108
|
|
|
91
|
-
|
|
109
|
+
waiting = probe_state_kind(probe_states[slot].x) == PROBE_STATE_NEW || wanted_frame > probe_records[slot].traced_frame;
|
|
110
|
+
// not wanted the frame before: wanted_frame < frame − 1, which does not wrap at the first frame
|
|
111
|
+
evictable = !waiting && wanted_frame + 1u < settings.frame;
|
|
112
|
+
|
|
113
|
+
let age = settings.frame - wanted_frame;
|
|
114
|
+
|
|
115
|
+
bucket = probe_clipmap_age_bucket(age);
|
|
116
|
+
|
|
117
|
+
// the bucket the last frame's schedule counted it in, a frame younger: a probe that aged into an asked
|
|
118
|
+
// bucket since, uncounted, is not taken for it
|
|
119
|
+
let counted = probe_clipmap_age_bucket(age - 1u);
|
|
120
|
+
|
|
121
|
+
// the oldest buckets whole, and as many of the one below them as are asked for; one that left its
|
|
122
|
+
// window goes anyway and takes none of those
|
|
123
|
+
let whole = PROBE_AGE_BUCKETS - min(probe_eviction.buckets, PROBE_AGE_BUCKETS);
|
|
124
|
+
var evicted = evictable && counted >= whole;
|
|
125
|
+
|
|
126
|
+
if (held && evictable && counted + 1u == whole && probe_eviction.remaining > 0u) {
|
|
127
|
+
evicted = atomicAdd(&probe_counters[PROBE_COUNTER_EVICTED], 1u) < probe_eviction.remaining;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
keep = held && !evicted;
|
|
92
131
|
|
|
93
132
|
if (!keep) {
|
|
94
133
|
let resolution = settings.resolution;
|
|
@@ -103,8 +142,13 @@ fn main(
|
|
|
103
142
|
|
|
104
143
|
slot_stack_push(&probe_counters[PROBE_COUNTER_FREE], &probe_free, slot);
|
|
105
144
|
}
|
|
145
|
+
|
|
146
|
+
if (keep && evictable) {
|
|
147
|
+
atomicAdd(&probe_counters[PROBE_COUNTER_AGES + bucket], 1u);
|
|
148
|
+
}
|
|
106
149
|
}
|
|
107
150
|
|
|
151
|
+
subgroup_atomic_add_u32(&probe_counters[PROBE_COUNTER_WAITING], select(0u, 1u, keep && waiting));
|
|
108
152
|
collection_u32_append(&probe_active_write, keep, slot, settings.capacity);
|
|
109
153
|
}
|
|
110
154
|
`, [
|
|
@@ -114,5 +158,6 @@ fn main(
|
|
|
114
158
|
chunk_clipmap_storage_coord,
|
|
115
159
|
chunk_slot_stack,
|
|
116
160
|
chunk_collection_u32_append,
|
|
161
|
+
chunk_subgroup_atomic_add,
|
|
117
162
|
]),
|
|
118
163
|
});
|
|
@@ -3,14 +3,29 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const PROBE_SCHEDULE_SETTINGS: WebGPUStruct;
|
|
5
5
|
/**
|
|
6
|
-
* Schedule (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.5): one thread, after admit, when the frame's
|
|
7
|
-
* list is whole.
|
|
8
|
-
* - The period: with P_w the
|
|
9
|
-
*
|
|
6
|
+
* Schedule (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3, §8.5): one thread, after admit, when the frame's
|
|
7
|
+
* active list is whole.
|
|
8
|
+
* - The period: with P_w the probes waiting for an update, the NEW and those wanted since their last
|
|
9
|
+
* update, `T = max(1, ⌈P_w / U⌉)` frames, so that every probe a want waits on is updated within a period
|
|
10
|
+
* and the period follows the live count. Retire and admit counted them in
|
|
11
|
+
* `probe_counters[PROBE_COUNTER_WAITING]`, which it empties for the next frame's; the period goes to
|
|
10
12
|
* `probe_counters[PROBE_COUNTER_PERIOD]` for the due passes.
|
|
13
|
+
* - The next frame's eviction, `probe_eviction`: as many slots as the free ones fall short of the frame's
|
|
14
|
+
* wanted points and the slack, the probes wanted longest ago first. Walking retire's age buckets from the
|
|
15
|
+
* oldest, it asks for each bucket whole while the shortfall takes it, then for what is left of the
|
|
16
|
+
* shortfall from the next; past the youngest bucket it counted anything in, it asks for nothing, so a
|
|
17
|
+
* shortfall the evictable probes cannot cover frees them all and no more. It empties the buckets and
|
|
18
|
+
* the count of a bucket's probes retire evicted.
|
|
11
19
|
* - A thread an entry of the frame's active list, at `PROBE_DISPATCH_ACTIVE`: the due passes' launch, and
|
|
12
20
|
* the next frame's retire's, which reads this list.
|
|
13
21
|
*
|
|
22
|
+
* A hit wants a probe the frame after its probe's update, so a probe hits keep may be wanted on few of
|
|
23
|
+
* its turns. The waiting count is what due lists over a period, where this frame's wanted points would
|
|
24
|
+
* count the probes a pixel wants every frame and miss most of those hits want between their turns.
|
|
25
|
+
*
|
|
26
|
+
* The frame's wanted points are the most a frame can admit, so the next frame's admissions find slots
|
|
27
|
+
* for as many points as this one wanted, and the slack more, before an admission starves.
|
|
28
|
+
*
|
|
14
29
|
* @type {ComputeShader}
|
|
15
30
|
*/
|
|
16
31
|
export const shader_probe_clipmap_schedule: ComputeShader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_probe_clipmap_schedule.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_probe_clipmap_schedule.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js"],"names":[],"mappings":"AAeA;;GAEG;AACH,sCAFU,YAAY,CAWM;AAa5B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,4CAFU,aAAa,CA6DpB;6BAxH0B,sCAAsC;8BAHrC,kCAAkC"}
|