@woosh/meep-engine 3.12.0 → 3.13.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.
Files changed (285) hide show
  1. package/package.json +1 -1
  2. package/src/engine/graphics3/decal/GPUDecalRenderer.js +3 -3
  3. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  4. package/src/engine/graphics3/decal/shader_decal_composite.js +4 -2
  5. package/src/engine/graphics3/highlight/GPUHighlightRenderer.d.ts.map +1 -1
  6. package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +2 -3
  7. package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
  8. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  9. package/src/shade/RENDERER_CONTRACT.md +2 -1
  10. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +18 -0
  11. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  12. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +73 -0
  13. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +750 -0
  14. package/src/shade/device/ShadeGPUCommandContext.d.ts +10 -16
  15. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  16. package/src/shade/device/ShadeGPUCommandContext.js +801 -994
  17. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts +107 -0
  18. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts.map +1 -0
  19. package/src/shade/device/pass/ShadeGPUComputePassEncoder.js +222 -0
  20. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts +168 -0
  21. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts.map +1 -0
  22. package/src/shade/device/pass/ShadeGPURenderPassEncoder.js +317 -0
  23. package/src/shade/device/timing/GPUTimerArray.d.ts +4 -9
  24. package/src/shade/device/timing/GPUTimerArray.d.ts.map +1 -1
  25. package/src/shade/device/timing/GPUTimerArray.js +261 -289
  26. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +20 -2
  27. package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts +59 -0
  28. package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts.map +1 -0
  29. package/src/shade/device/timing/ShadeGPUContextProfiler.js +182 -0
  30. package/src/shade/device/timing/profile/GPUProfileSession.d.ts +4 -4
  31. package/src/shade/device/timing/profile/GPUProfileSession.js +4 -4
  32. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  33. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +3 -1
  34. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
  35. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +3 -1
  36. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  37. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +3 -1
  38. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +2 -2
  39. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +2 -2
  40. package/src/shade/renderer/Renderer.d.ts +0 -6
  41. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  42. package/src/shade/renderer/Renderer.js +0 -29
  43. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  44. package/src/shade/renderer/animation/GPUAnimationManager.js +1 -3
  45. package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
  46. package/src/shade/renderer/animation/shader_animation_tick.js +128 -125
  47. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  48. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +8 -18
  49. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
  50. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +100 -98
  51. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
  52. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +215 -212
  53. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts +1 -1
  54. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
  55. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +135 -120
  56. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
  57. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +77 -75
  58. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  59. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +375 -371
  60. package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +3 -3
  61. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +1 -1
  62. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  63. package/src/shade/renderer/buffer/table/GPUDatabase.js +14 -19
  64. package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.d.ts.map +1 -1
  65. package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.js +7 -2
  66. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  67. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +325 -319
  68. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
  69. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +3 -1
  70. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  71. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +4 -1
  72. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts +2 -2
  73. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts.map +1 -1
  74. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
  75. package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +3 -3
  76. package/src/shade/renderer/fow/shader_fog_of_war.d.ts.map +1 -1
  77. package/src/shade/renderer/fow/shader_fog_of_war.js +3 -1
  78. package/src/shade/renderer/geometry/bvh/record_blas_refit.js +102 -102
  79. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
  80. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +125 -121
  81. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  82. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +766 -774
  83. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +72 -69
  85. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  86. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +5 -10
  87. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +129 -129
  88. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
  89. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +5 -3
  90. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  91. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -1
  92. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.d.ts.map +1 -1
  93. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.js +3 -1
  94. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.js +114 -112
  96. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.js +4 -1
  98. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
  99. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +187 -184
  100. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
  101. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +4 -1
  102. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
  103. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +6 -8
  104. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -1
  106. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.d.ts.map +1 -1
  107. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.js +3 -1
  108. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +3 -3
  109. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +3 -3
  110. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
  111. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  112. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +145 -142
  113. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  114. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +87 -82
  115. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  116. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +143 -140
  117. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts +2 -2
  118. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts.map +1 -1
  119. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.js +43 -8
  120. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  121. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +4 -5
  122. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  123. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +88 -84
  124. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  125. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +194 -191
  126. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  127. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +33 -69
  128. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  129. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +6 -1
  130. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
  131. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +23 -7
  132. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  133. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +1 -2
  134. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.d.ts.map +1 -1
  135. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.js +6 -1
  136. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  137. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +234 -219
  138. package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +2 -2
  139. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +191 -191
  140. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.d.ts.map +1 -1
  141. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.js +85 -82
  142. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  143. package/src/shade/renderer/particles/graph_particles.js +5 -3
  144. package/src/shade/renderer/particles/prototypeParticleSystem.js +3 -4
  145. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  146. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +132 -117
  147. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  148. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +79 -77
  149. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +111 -99
  151. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/sort/shader_particle_sort.js +187 -158
  153. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  154. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +7 -10
  155. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  156. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +4 -1
  157. package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.d.ts.map +1 -1
  158. package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.js +3 -1
  159. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.d.ts.map +1 -1
  160. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +4 -2
  161. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +147 -147
  162. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
  163. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +121 -119
  164. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.d.ts.map +1 -1
  165. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +1 -2
  166. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.d.ts.map +1 -1
  167. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +4 -1
  168. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.d.ts.map +1 -1
  169. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +4 -1
  170. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.d.ts.map +1 -1
  171. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +4 -1
  172. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.d.ts.map +1 -1
  173. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +4 -1
  174. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.d.ts.map +1 -1
  175. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +2 -4
  176. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.d.ts.map +1 -1
  177. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +4 -1
  178. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.d.ts.map +1 -1
  179. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +4 -1
  180. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.d.ts.map +1 -1
  181. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.js +4 -1
  182. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
  183. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +269 -266
  184. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
  185. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +273 -270
  186. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.d.ts.map +1 -1
  187. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +4 -1
  188. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  189. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +8 -11
  190. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
  191. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +5 -1
  192. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  193. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +11 -8
  194. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  195. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +7 -8
  196. package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.d.ts.map +1 -1
  197. package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.js +3 -1
  198. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  199. package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
  200. package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +70 -68
  201. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +1 -1
  202. package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +70 -68
  203. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
  204. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +3 -1
  205. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
  206. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +4 -1
  207. package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.d.ts.map +1 -1
  208. package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.js +103 -101
  209. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  210. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
  211. package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.d.ts.map +1 -1
  212. package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.js +3 -1
  213. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  214. package/src/shade/renderer/postprocess/taa/shader_taa.js +4 -1
  215. package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +5 -5
  216. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  217. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +339 -341
  218. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  219. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +114 -109
  220. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  221. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +118 -115
  222. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  223. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +69 -65
  224. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +722 -722
  225. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  226. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +1 -9
  227. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  228. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +1 -6
  229. package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
  230. package/src/shade/renderer/restir/di/graph_restir_di.js +2 -3
  231. package/src/shade/renderer/restir/di/graph_restir_di_denoise.d.ts.map +1 -1
  232. package/src/shade/renderer/restir/di/graph_restir_di_denoise.js +1 -2
  233. package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
  234. package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +139 -136
  235. package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
  236. package/src/shade/renderer/restir/di/shader_restir_di_resample.js +131 -129
  237. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  238. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +101 -99
  239. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  240. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +379 -383
  241. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
  242. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +147 -144
  243. package/src/shade/renderer/shader/ComputeShader.d.ts +2 -2
  244. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  245. package/src/shade/renderer/shader/ComputeShader.js +14 -17
  246. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts +2 -2
  247. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  248. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +189 -189
  249. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  250. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +3 -1
  251. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  252. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +14 -18
  253. package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.d.ts.map +1 -1
  254. package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.js +5 -1
  255. package/src/shade/renderer/shadow/ray/shader_shadow_upscale.d.ts.map +1 -1
  256. package/src/shade/renderer/shadow/ray/shader_shadow_upscale.js +3 -1
  257. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +73 -73
  258. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
  259. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +151 -148
  260. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts.map +1 -1
  261. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +4 -2
  262. package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.d.ts.map +1 -1
  263. package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.js +18 -4
  264. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  265. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +7 -8
  266. package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.d.ts.map +1 -1
  267. package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.js +6 -2
  268. package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.d.ts.map +1 -1
  269. package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.js +129 -127
  270. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
  271. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +5 -3
  272. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  273. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +2 -5
  274. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
  275. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +233 -231
  276. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  277. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -4
  278. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  279. package/src/shade/wgsl/validate_wgsl_source.js +8 -3
  280. package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts +0 -21
  281. package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts.map +0 -1
  282. package/src/shade/device/timing/profile/make_profiling_pass_encoder.js +0 -114
  283. package/src/shade/device/timing/profile/parse_workgroup_size.d.ts +0 -20
  284. package/src/shade/device/timing/profile/parse_workgroup_size.d.ts.map +0 -1
  285. package/src/shade/device/timing/profile/parse_workgroup_size.js +0 -43
@@ -1,191 +1,194 @@
1
- import { WebGPUExtensionType } from "../../../descriptor/WebGPUExtensionType.js";
2
- import { u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
3
- import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
4
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
5
- import { ComputeShader } from "../../shader/ComputeShader.js";
6
- import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
7
- import { chunk_sort_digit } from "./chunk_sort_digit.js";
8
- import { chunk_sort_rank } from "./chunk_sort_rank.js";
9
- import { chunk_sort_workgroup_scan } from "./chunk_sort_workgroup_scan.js";
10
- import { RADIX, RADIX_LOG, SORT_KEYS_PER_THREAD, SORT_TILE_SIZE, SORT_WORKGROUP_SIZE } from "./defs.js";
11
- import { SORT_PASS_SETTINGS_STRUCT } from "./SORT_PASS_SETTINGS_STRUCT.js";
12
-
13
- const resources = new ShaderResourceSetDescriptor();
14
- resources.createGroup()
15
- .addUniform("settings", SORT_PASS_SETTINGS_STRUCT)
16
- .addStorageBuffer("in_keys", WebGPUArray.from(u32), false)
17
- .addStorageBuffer("in_values", WebGPUArray.from(u32), false)
18
- .addStorageBuffer("out_keys", WebGPUArray.from(u32), true)
19
- .addStorageBuffer("out_values", WebGPUArray.from(u32), true)
20
- // scanned spine, read flat past its `{count, elements}` header
21
- .addStorageBuffer("spine", WebGPUArray.from(u32), false);
22
-
23
- const body = CodeChunk.from(
24
- //language=WGSL
25
- `
26
- const WORKGROUP_SIZE = ${SORT_WORKGROUP_SIZE}u;
27
- const KEYS_PER_THREAD = ${SORT_KEYS_PER_THREAD}u;
28
- const TILE_SIZE = ${SORT_TILE_SIZE}u;
29
- const RADIX = ${RADIX}u;
30
- const RADIX_LOG = ${RADIX_LOG}u;
31
-
32
- /**
33
- * The key a slot past the end of the input is filled with. It is the largest u32, so its digit is
34
- * the largest in every pass and the stable in-tile sort parks every one of them behind every real
35
- * key — which is what makes "sorted position < the tile's real key count" a sufficient test for
36
- * whether a slot holds a real key.
37
- */
38
- const PADDING_KEY = 0xffffffffu;
39
-
40
- var<workgroup> wg_keys: array<u32, TILE_SIZE>;
41
- var<workgroup> wg_values: array<u32, TILE_SIZE>;
42
- // one bin per thread; RADIX == WORKGROUP_SIZE
43
- var<workgroup> wg_histogram: array<atomic<u32>, RADIX>;
44
- var<workgroup> wg_base: array<u32, RADIX>;
45
-
46
- @compute @workgroup_size(WORKGROUP_SIZE, 1, 1)
47
- fn main(
48
- @builtin(local_invocation_index) thread_id: u32,
49
- @builtin(workgroup_id) workgroup_id: vec3<u32>,
50
- @builtin(subgroup_invocation_id) lane_id: u32,
51
- @builtin(subgroup_size) lane_count: u32,
52
- ) {
53
- let tile = workgroup_id.x;
54
- let tile_base = tile * TILE_SIZE;
55
- let shift = settings.shift;
56
-
57
- atomicStore(&wg_histogram[thread_id], 0u);
58
-
59
- // Striped load, so neighbouring threads read neighbouring addresses.
60
- for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
61
- let slot = k * WORKGROUP_SIZE + thread_id;
62
- let source = tile_base + slot;
63
-
64
- var key = PADDING_KEY;
65
- var value = 0u;
66
-
67
- if (source < settings.element_count) {
68
- key = in_keys[source];
69
- value = in_values[source];
70
- }
71
-
72
- wg_keys[slot] = key;
73
- wg_values[slot] = value;
74
- }
75
-
76
- workgroupBarrier();
77
-
78
- // Local histogram over the real keys only — it has to agree with what the histogram pass
79
- // counted, because the spine value this tile reads back was built from that count.
80
- for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
81
- let slot = k * WORKGROUP_SIZE + thread_id;
82
-
83
- if (tile_base + slot < settings.element_count) {
84
- atomicAdd(&wg_histogram[sort_extract_digit(wg_keys[slot], shift)], 1u);
85
- }
86
- }
87
-
88
- workgroupBarrier();
89
-
90
- // this thread's bin, captured before the in-tile sort touches anything
91
- let local_count = atomicLoad(&wg_histogram[thread_id]);
92
-
93
- // Order the tile by this pass's digit, one bit at a time, least significant first. Eight stable
94
- // binary splits are a sort by the whole 8-bit digit; ranking a key against its same-digit peers
95
- // then costs nothing, because the rank IS the sorted position, and the device writes that
96
- // follow come out contiguous per bin.
97
- for (var bit_index = 0u; bit_index < RADIX_LOG; bit_index += 1u) {
98
- let bit = shift + bit_index;
99
-
100
- // Blocked ownership for the permutation: thread t owns the tile's slots
101
- // [t*KEYS_PER_THREAD, (t+1)*KEYS_PER_THREAD), so the offsets a thread hands its own keys
102
- // are consecutive and the scan below only has to run over one value per thread.
103
- var keys: array<u32, KEYS_PER_THREAD>;
104
- var values: array<u32, KEYS_PER_THREAD>;
105
- var ones = 0u;
106
-
107
- for (var j = 0u; j < KEYS_PER_THREAD; j += 1u) {
108
- let slot = thread_id * KEYS_PER_THREAD + j;
109
-
110
- keys[j] = wg_keys[slot];
111
- values[j] = wg_values[slot];
112
- ones += (keys[j] >> bit) & 1u;
113
- }
114
-
115
- // The scan's first barrier is what fences every thread's reads above against the writes
116
- // below — by the time it returns, no read of wg_keys/wg_values is outstanding.
117
- let scan = sort_workgroup_exclusive_scan(ones, thread_id, lane_id, lane_count);
118
-
119
- let total_zeros = TILE_SIZE - scan.y;
120
-
121
- var ones_before = scan.x;
122
- var zeros_before = thread_id * KEYS_PER_THREAD - scan.x;
123
-
124
- for (var j = 0u; j < KEYS_PER_THREAD; j += 1u) {
125
- let is_one = ((keys[j] >> bit) & 1u) != 0u;
126
- let destination = sort_split_destination(is_one, zeros_before, ones_before, total_zeros);
127
-
128
- if (is_one) {
129
- ones_before += 1u;
130
- } else {
131
- zeros_before += 1u;
132
- }
133
-
134
- wg_keys[destination] = keys[j];
135
- wg_values[destination] = values[j];
136
- }
137
-
138
- workgroupBarrier();
139
- }
140
-
141
- // Exclusive prefix of the local histogram — for a tile now sorted by digit this is exactly the
142
- // slot each bin's run begins at, and the total is the tile's real key count, because the
143
- // padding was never counted.
144
- let histogram_scan = sort_workgroup_exclusive_scan(local_count, thread_id, lane_id, lane_count);
145
-
146
- let bin_start = histogram_scan.x;
147
- let valid_count = histogram_scan.y;
148
-
149
- let spine_inclusive = spine[sort_spine_index(thread_id, tile, settings.tile_count)];
150
-
151
- wg_base[thread_id] = sort_scatter_base(spine_inclusive, local_count, bin_start);
152
-
153
- workgroupBarrier();
154
-
155
- for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
156
- let slot = k * WORKGROUP_SIZE + thread_id;
157
-
158
- if (slot < valid_count) {
159
- let key = wg_keys[slot];
160
- let destination = wg_base[sort_extract_digit(key, shift)] + slot;
161
-
162
- out_keys[destination] = key;
163
- out_values[destination] = wg_values[slot];
164
- }
165
- }
166
- }
167
- `, [
168
- chunk_sort_digit,
169
- chunk_sort_rank,
170
- chunk_sort_workgroup_scan,
171
- ]);
172
-
173
- body.addExtension(WebGPUExtensionType.Subgroups);
174
-
175
- /**
176
- * Rank-and-scatter — stage (c) of one digit pass of {@link graph_radix_sort}.
177
- *
178
- * One workgroup per tile. The tile is sorted by the current digit in workgroup memory (stability is
179
- * what an LSD radix sort's correctness rests on, and it is also what lets the tail tile's padding
180
- * be identified by position), the tile's own histogram is re-derived rather than carried over from
181
- * the histogram pass the scan is inclusive-only, and re-counting is cheaper than preserving
182
- * pre-scan counts and each key is written to
183
- * `spine_inclusive[bin] - local_count[bin] - bin_start[bin] + sorted_position`.
184
- *
185
- * @type {ComputeShader}
186
- */
187
- export const shader_radix_sort_scatter = ComputeShader.from({
188
- label: "RadixSort/Scatter",
189
- resources,
190
- body,
191
- });
1
+ import { WebGPUExtensionType } from "../../../descriptor/WebGPUExtensionType.js";
2
+ import { u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
3
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
4
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
5
+ import { ComputeShader } from "../../shader/ComputeShader.js";
6
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
7
+ import { chunk_sort_digit } from "./chunk_sort_digit.js";
8
+ import { chunk_sort_rank } from "./chunk_sort_rank.js";
9
+ import { chunk_sort_workgroup_scan } from "./chunk_sort_workgroup_scan.js";
10
+ import { RADIX, RADIX_LOG, SORT_KEYS_PER_THREAD, SORT_TILE_SIZE, SORT_WORKGROUP_SIZE } from "./defs.js";
11
+ import { SORT_PASS_SETTINGS_STRUCT } from "./SORT_PASS_SETTINGS_STRUCT.js";
12
+
13
+ const resources = new ShaderResourceSetDescriptor();
14
+
15
+ // see shader_radix_sort_histogram — the same per-pass settings, carried as immediate data
16
+ resources.setImmediate("settings", SORT_PASS_SETTINGS_STRUCT);
17
+
18
+ resources.createGroup()
19
+ .addStorageBuffer("in_keys", WebGPUArray.from(u32), false)
20
+ .addStorageBuffer("in_values", WebGPUArray.from(u32), false)
21
+ .addStorageBuffer("out_keys", WebGPUArray.from(u32), true)
22
+ .addStorageBuffer("out_values", WebGPUArray.from(u32), true)
23
+ // scanned spine, read flat past its `{count, elements}` header
24
+ .addStorageBuffer("spine", WebGPUArray.from(u32), false);
25
+
26
+ const body = CodeChunk.from(
27
+ //language=WGSL
28
+ `
29
+ const WORKGROUP_SIZE = ${SORT_WORKGROUP_SIZE}u;
30
+ const KEYS_PER_THREAD = ${SORT_KEYS_PER_THREAD}u;
31
+ const TILE_SIZE = ${SORT_TILE_SIZE}u;
32
+ const RADIX = ${RADIX}u;
33
+ const RADIX_LOG = ${RADIX_LOG}u;
34
+
35
+ /**
36
+ * The key a slot past the end of the input is filled with. It is the largest u32, so its digit is
37
+ * the largest in every pass and the stable in-tile sort parks every one of them behind every real
38
+ * key — which is what makes "sorted position < the tile's real key count" a sufficient test for
39
+ * whether a slot holds a real key.
40
+ */
41
+ const PADDING_KEY = 0xffffffffu;
42
+
43
+ var<workgroup> wg_keys: array<u32, TILE_SIZE>;
44
+ var<workgroup> wg_values: array<u32, TILE_SIZE>;
45
+ // one bin per thread; RADIX == WORKGROUP_SIZE
46
+ var<workgroup> wg_histogram: array<atomic<u32>, RADIX>;
47
+ var<workgroup> wg_base: array<u32, RADIX>;
48
+
49
+ @compute @workgroup_size(WORKGROUP_SIZE, 1, 1)
50
+ fn main(
51
+ @builtin(local_invocation_index) thread_id: u32,
52
+ @builtin(workgroup_id) workgroup_id: vec3<u32>,
53
+ @builtin(subgroup_invocation_id) lane_id: u32,
54
+ @builtin(subgroup_size) lane_count: u32,
55
+ ) {
56
+ let tile = workgroup_id.x;
57
+ let tile_base = tile * TILE_SIZE;
58
+ let shift = settings.shift;
59
+
60
+ atomicStore(&wg_histogram[thread_id], 0u);
61
+
62
+ // Striped load, so neighbouring threads read neighbouring addresses.
63
+ for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
64
+ let slot = k * WORKGROUP_SIZE + thread_id;
65
+ let source = tile_base + slot;
66
+
67
+ var key = PADDING_KEY;
68
+ var value = 0u;
69
+
70
+ if (source < settings.element_count) {
71
+ key = in_keys[source];
72
+ value = in_values[source];
73
+ }
74
+
75
+ wg_keys[slot] = key;
76
+ wg_values[slot] = value;
77
+ }
78
+
79
+ workgroupBarrier();
80
+
81
+ // Local histogram over the real keys only — it has to agree with what the histogram pass
82
+ // counted, because the spine value this tile reads back was built from that count.
83
+ for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
84
+ let slot = k * WORKGROUP_SIZE + thread_id;
85
+
86
+ if (tile_base + slot < settings.element_count) {
87
+ atomicAdd(&wg_histogram[sort_extract_digit(wg_keys[slot], shift)], 1u);
88
+ }
89
+ }
90
+
91
+ workgroupBarrier();
92
+
93
+ // this thread's bin, captured before the in-tile sort touches anything
94
+ let local_count = atomicLoad(&wg_histogram[thread_id]);
95
+
96
+ // Order the tile by this pass's digit, one bit at a time, least significant first. Eight stable
97
+ // binary splits are a sort by the whole 8-bit digit; ranking a key against its same-digit peers
98
+ // then costs nothing, because the rank IS the sorted position, and the device writes that
99
+ // follow come out contiguous per bin.
100
+ for (var bit_index = 0u; bit_index < RADIX_LOG; bit_index += 1u) {
101
+ let bit = shift + bit_index;
102
+
103
+ // Blocked ownership for the permutation: thread t owns the tile's slots
104
+ // [t*KEYS_PER_THREAD, (t+1)*KEYS_PER_THREAD), so the offsets a thread hands its own keys
105
+ // are consecutive and the scan below only has to run over one value per thread.
106
+ var keys: array<u32, KEYS_PER_THREAD>;
107
+ var values: array<u32, KEYS_PER_THREAD>;
108
+ var ones = 0u;
109
+
110
+ for (var j = 0u; j < KEYS_PER_THREAD; j += 1u) {
111
+ let slot = thread_id * KEYS_PER_THREAD + j;
112
+
113
+ keys[j] = wg_keys[slot];
114
+ values[j] = wg_values[slot];
115
+ ones += (keys[j] >> bit) & 1u;
116
+ }
117
+
118
+ // The scan's first barrier is what fences every thread's reads above against the writes
119
+ // below by the time it returns, no read of wg_keys/wg_values is outstanding.
120
+ let scan = sort_workgroup_exclusive_scan(ones, thread_id, lane_id, lane_count);
121
+
122
+ let total_zeros = TILE_SIZE - scan.y;
123
+
124
+ var ones_before = scan.x;
125
+ var zeros_before = thread_id * KEYS_PER_THREAD - scan.x;
126
+
127
+ for (var j = 0u; j < KEYS_PER_THREAD; j += 1u) {
128
+ let is_one = ((keys[j] >> bit) & 1u) != 0u;
129
+ let destination = sort_split_destination(is_one, zeros_before, ones_before, total_zeros);
130
+
131
+ if (is_one) {
132
+ ones_before += 1u;
133
+ } else {
134
+ zeros_before += 1u;
135
+ }
136
+
137
+ wg_keys[destination] = keys[j];
138
+ wg_values[destination] = values[j];
139
+ }
140
+
141
+ workgroupBarrier();
142
+ }
143
+
144
+ // Exclusive prefix of the local histogram — for a tile now sorted by digit this is exactly the
145
+ // slot each bin's run begins at, and the total is the tile's real key count, because the
146
+ // padding was never counted.
147
+ let histogram_scan = sort_workgroup_exclusive_scan(local_count, thread_id, lane_id, lane_count);
148
+
149
+ let bin_start = histogram_scan.x;
150
+ let valid_count = histogram_scan.y;
151
+
152
+ let spine_inclusive = spine[sort_spine_index(thread_id, tile, settings.tile_count)];
153
+
154
+ wg_base[thread_id] = sort_scatter_base(spine_inclusive, local_count, bin_start);
155
+
156
+ workgroupBarrier();
157
+
158
+ for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
159
+ let slot = k * WORKGROUP_SIZE + thread_id;
160
+
161
+ if (slot < valid_count) {
162
+ let key = wg_keys[slot];
163
+ let destination = wg_base[sort_extract_digit(key, shift)] + slot;
164
+
165
+ out_keys[destination] = key;
166
+ out_values[destination] = wg_values[slot];
167
+ }
168
+ }
169
+ }
170
+ `, [
171
+ chunk_sort_digit,
172
+ chunk_sort_rank,
173
+ chunk_sort_workgroup_scan,
174
+ ]);
175
+
176
+ body.addExtension(WebGPUExtensionType.Subgroups);
177
+
178
+ /**
179
+ * Rank-and-scatter stage (c) of one digit pass of {@link graph_radix_sort}.
180
+ *
181
+ * One workgroup per tile. The tile is sorted by the current digit in workgroup memory (stability is
182
+ * what an LSD radix sort's correctness rests on, and it is also what lets the tail tile's padding
183
+ * be identified by position), the tile's own histogram is re-derived rather than carried over from
184
+ * the histogram pass — the scan is inclusive-only, and re-counting is cheaper than preserving
185
+ * pre-scan counts — and each key is written to
186
+ * `spine_inclusive[bin] - local_count[bin] - bin_start[bin] + sorted_position`.
187
+ *
188
+ * @type {ComputeShader}
189
+ */
190
+ export const shader_radix_sort_scatter = ComputeShader.from({
191
+ label: "RadixSort/Scatter",
192
+ resources,
193
+ body,
194
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"HierarchicalZBuffer.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/HierarchicalZBuffer.js"],"names":[],"mappings":"AAcA;IAqCI;;;OAGG;IACH,uCAYC;IAzCD;;;OAGG;IACH,iCAEC;IAqCD;;;;;OAKG;IACH,kFAFW,MAAM,EAAE,QAqGlB;IAmDD;;;;OAIG;IACH,mBAHW,MAAM,KACN,MAAM,QAahB;IAgED,gBAGC;;CACJ"}
1
+ {"version":3,"file":"HierarchicalZBuffer.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/HierarchicalZBuffer.js"],"names":[],"mappings":"AASA;IAgCI;;;OAGG;IACH,uCAYC;IApCD;;;OAGG;IACH,iCAEC;IAgCD;;;;;OAKG;IACH,kFAFW,MAAM,EAAE,QAiGlB;IAmED;;;;OAIG;IACH,mBAHW,MAAM,KACN,MAAM,QAahB;IA2BD,gBAEC;;CACJ"}
@@ -1,17 +1,12 @@
1
1
  import { assert } from "../../../core/assert.js";
2
2
  import { max2 } from "../../../core/math/max2.js";
3
- import { round_up } from "../../../core/math/round_up.js";
4
3
  import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
5
4
  import { TextureViewDescriptor } from "../../descriptor/texture/TextureViewDescriptor.js";
6
- import { vec4u } from "../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
7
5
  import { compute_max_mip_count } from "../../util/compute_max_mip_count.js";
8
6
  import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
9
7
  import { shader_hzb_reduce_any, shader_hzb_reduce_mip0 } from "./shader_hzb_reduce_any.js";
10
8
  import { shader_hzb_reduce_mip0_clip } from "./shader_hzb_reduce_mip0_clip.js";
11
9
 
12
- const VEC2_UINT_SIZE = 2 * Uint32Array.BYTES_PER_ELEMENT;
13
-
14
-
15
10
  export class HierarchicalZBuffer {
16
11
 
17
12
  /**
@@ -38,11 +33,6 @@ export class HierarchicalZBuffer {
38
33
  */
39
34
  #graphics;
40
35
 
41
- /**
42
- * @type {GPUBuffer}
43
- */
44
- #buffer_resolution;
45
-
46
36
  /**
47
37
  *
48
38
  * @type {number[]}
@@ -128,20 +118,16 @@ export class HierarchicalZBuffer {
128
118
  if (is_clipped_variant) {
129
119
  // special case for clip region
130
120
 
131
- const clip_region = encoder.allocateTransientValueBuffer(vec4u, [
132
- source_offset[0], source_offset[1],
133
- viewport_size[0], viewport_size[1],
134
- ]);
135
-
136
121
  shader_hzb_reduce_mip0_clip.draw({
137
122
  encoder,
138
123
  bindings: {
139
124
  tInput: source_view,
140
- clip_region,
141
- output_resolution: {
142
- buffer: this.#buffer_resolution,
143
- offset: 0,
144
- size: VEC2_UINT_SIZE
125
+ settings: {
126
+ clip_region: [
127
+ source_offset[0], source_offset[1],
128
+ viewport_size[0], viewport_size[1],
129
+ ],
130
+ output_resolution: this.#mip_resolution(0),
145
131
  },
146
132
  },
147
133
  colorAttachments: [{
@@ -192,17 +178,11 @@ export class HierarchicalZBuffer {
192
178
  viewport
193
179
  ) {
194
180
 
195
- const align_vec2u = this.#get_aligned_vec2u_size();
196
-
197
181
  shader.draw({
198
182
  encoder,
199
183
  bindings: {
200
184
  tInput: source_view,
201
- output_resolution: {
202
- buffer: this.#buffer_resolution,
203
- offset: index * align_vec2u,
204
- size: VEC2_UINT_SIZE
205
- },
185
+ output_resolution: this.#mip_resolution(index),
206
186
  },
207
187
  colorAttachments: [
208
188
  {
@@ -216,11 +196,33 @@ export class HierarchicalZBuffer {
216
196
 
217
197
  }
218
198
 
219
- #get_aligned_vec2u_size() {
220
- const device = this.#graphics.device;
221
- const limits = device.limits;
199
+ /**
200
+ * Scratch for {@link #mip_resolution}. The value is serialised into the pass's immediate bytes
201
+ * before the next call, so one array can serve every mip.
202
+ *
203
+ * @type {number[]}
204
+ */
205
+ #mip_resolution_scratch = [1, 1];
222
206
 
223
- return round_up(VEC2_UINT_SIZE, limits.minUniformBufferOffsetAlignment);
207
+ /**
208
+ * Size of mip `index` of the HZB, which is what the reduction pass writing into it needs to know.
209
+ *
210
+ * Each mip halves the one above it, floored at one texel — the same walk that used to be
211
+ * precomputed into a uniform buffer of every mip's resolution and bound at a per-mip dynamic
212
+ * offset. As immediate data there is nothing to precompute into.
213
+ *
214
+ * @param {number} index
215
+ * @returns {number[]}
216
+ */
217
+ #mip_resolution(index) {
218
+ const size = this.#texture.size;
219
+
220
+ const out = this.#mip_resolution_scratch;
221
+
222
+ out[0] = max2(1, size[0] >>> index);
223
+ out[1] = max2(1, size[1] >>> index);
224
+
225
+ return out;
224
226
  }
225
227
 
226
228
  /**
@@ -264,47 +266,9 @@ export class HierarchicalZBuffer {
264
266
  texture.descriptor.mipLevelCount = mip_count;
265
267
 
266
268
  texture.resize(x, y);
267
-
268
- const aligned_vec2u_size = this.#get_aligned_vec2u_size();
269
-
270
- const required_resolution_buffer_size = (mip_count + 1) * aligned_vec2u_size;
271
-
272
- if (this.#buffer_resolution !== undefined) {
273
- this.#buffer_resolution.destroy();
274
- }
275
-
276
- // build destination resolution buffer for reduction shader
277
- this.#buffer_resolution = this.#graphics.device.createBuffer({
278
- label: "HZB Destination Resolution",
279
- size: required_resolution_buffer_size,
280
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
281
- mappedAtCreation: true
282
- });
283
-
284
- const res_buffer = this.#buffer_resolution.getMappedRange();
285
-
286
- // write all mip resolutions into the buffer
287
- // TODO can get away with just the mip index, can deduce the resolution through bitshift
288
- const res_32 = new Uint32Array(res_buffer);
289
-
290
- let res_x = x;
291
- let res_y = y;
292
-
293
- const vec2_align4 = aligned_vec2u_size >> 2;
294
-
295
- for (let i = 0; i < mip_count; i++) {
296
- res_32[i * vec2_align4] = res_x;
297
- res_32[i * vec2_align4 + 1] = res_y;
298
-
299
- res_x = max2(1, res_x >>> 1);
300
- res_y = max2(1, res_y >>> 1);
301
- }
302
-
303
- this.#buffer_resolution.unmap();
304
269
  }
305
270
 
306
271
  destroy() {
307
272
  this.#texture.destroy();
308
- this.#buffer_resolution.destroy();
309
273
  }
310
274
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shader_hzb_reduce_any.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/shader_hzb_reduce_any.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH,qCAFU,WAAW,CAoBlB;AAGH;;;GAGG;AACH,oCAFU,WAAW,CAmBnB;4BA5D0B,0BAA0B"}
1
+ {"version":3,"file":"shader_hzb_reduce_any.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/shader_hzb_reduce_any.js"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,qCAFU,WAAW,CAoBlB;AAGH;;;GAGG;AACH,oCAFU,WAAW,CAmBnB;4BAjE0B,0BAA0B"}
@@ -7,8 +7,13 @@ import { generate_downsampler_code } from "./generate_downsampler_code.js";
7
7
  import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
8
8
 
9
9
  const resources = new ShaderResourceSetDescriptor();
10
+
11
+ // per-pass, eight bytes, read-only: immediate data rather than a uniform buffer. The reduction
12
+ // walks the mip chain a pass at a time and every pass wants a different resolution, which used to
13
+ // mean a persistent table of them bound at a per-mip dynamic offset.
14
+ resources.setImmediate("output_resolution", vec2u);
15
+
10
16
  resources.createGroup()
11
- .addUniform("output_resolution", vec2u)
12
17
  .addTexture("tInput", "unfilterable-float")
13
18
  ;
14
19
 
@@ -1 +1 @@
1
- {"version":3,"file":"shader_hzb_reduce_mip0_clip.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js"],"names":[],"mappings":"AAiFA;;;;GAIG;AACH,0CAFU,WAAW,CAWlB;4BA7FyB,0BAA0B"}
1
+ {"version":3,"file":"shader_hzb_reduce_mip0_clip.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js"],"names":[],"mappings":"AAiGA;;;;GAIG;AACH,0CAFU,WAAW,CAWlB;4BA5GyB,0BAA0B"}
@@ -1,14 +1,30 @@
1
1
  import { vec2u, vec4u } from "../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUStruct } from "../shader/type/WebGPUStruct.js";
2
3
  import { CodeChunk } from "../shader/compiler/CodeChunk.js";
3
4
  import { ImageShader } from "../shader/ImageShader.js";
4
5
  import { ShaderResourceSetDescriptor } from "../shader/resource/ShaderResourceSetDescriptor.js";
5
6
  import { ShaderDescriptor } from "../shader/ShaderDescriptor.js";
6
7
  import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
7
8
 
9
+ /**
10
+ * Per-pass, 24 bytes, read-only.
11
+ *
12
+ * `clip_region` and `output_resolution` were two uniforms, so two buffers per pass. WGSL allows one
13
+ * immediate per entry point, so carrying them as immediate data means carrying them together.
14
+ *
15
+ * @type {WebGPUStruct}
16
+ */
17
+ const HZB_CLIP_SETTINGS = WebGPUStruct.from({
18
+ // x, y, width, height
19
+ clip_region: vec4u,
20
+ output_resolution: vec2u,
21
+ }, 'HzbClipSettings');
22
+
8
23
  const resources = new ShaderResourceSetDescriptor();
24
+
25
+ resources.setImmediate("settings", HZB_CLIP_SETTINGS);
26
+
9
27
  resources.createGroup()
10
- .addUniform("clip_region", vec4u) //x,y, width, height
11
- .addUniform("output_resolution", vec2u)
12
28
  .addTexture("tInput", "unfilterable-float")
13
29
  ;
14
30
 
@@ -23,7 +39,7 @@ fn main(
23
39
 
24
40
  // 1. Calculate the UV bounds of the current *output* pixel.
25
41
  // We use the output resolution to determine how wide one pixel is in UV space.
26
- let output_pixel_size2 = 0.5 / vec2<f32>(output_resolution);
42
+ let output_pixel_size2 = 0.5 / vec2<f32>(settings.output_resolution);
27
43
  let uv_min = uv - output_pixel_size2;
28
44
  let uv_max = uv + output_pixel_size2;
29
45
 
@@ -36,7 +52,7 @@ fn main(
36
52
 
37
53
  // 2. Convert UV bounds to Source Texel coordinates (float).
38
54
  // We map the 0..1 UVs to the size of the source clip region.
39
- let source_size = vec2<f32>(clip_region.zw);
55
+ let source_size = vec2<f32>(settings.clip_region.zw);
40
56
  let texel_min_f = safe_uv_min * source_size;
41
57
  let texel_max_f = safe_uv_max * source_size;
42
58
 
@@ -52,10 +68,10 @@ fn main(
52
68
  let bound_max = vec2<i32>(ceil(texel_max_f));
53
69
 
54
70
  // 4. Clamp bounds to the clip region size to be safe.
55
- let limit = vec2<i32>(clip_region.zw);
71
+ let limit = vec2<i32>(settings.clip_region.zw);
56
72
 
57
- let start = max(bound_min, vec2<i32>(0)) + vec2<i32>(clip_region.xy);
58
- let end = min(bound_max, limit) + vec2<i32>(clip_region.xy);
73
+ let start = max(bound_min, vec2<i32>(0)) + vec2<i32>(settings.clip_region.xy);
74
+ let end = min(bound_max, limit) + vec2<i32>(settings.clip_region.xy);
59
75
 
60
76
  var output = vec2<f32>(1.0, 0.0); // Initialize min/max
61
77