@woosh/meep-engine 3.11.1 → 3.11.3

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 (225) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  4. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +294 -290
  5. package/src/engine/graphics3/ParticipatingMedia.d.ts +111 -0
  6. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -0
  7. package/src/engine/graphics3/ParticipatingMedia.js +203 -0
  8. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts +34 -0
  9. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts.map +1 -0
  10. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.js +73 -0
  11. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +87 -0
  12. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -0
  13. package/src/engine/graphics3/ParticipatingMediaSystem3.js +184 -0
  14. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  15. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts +16 -2
  16. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts.map +1 -1
  17. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +28 -4
  18. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +1 -1
  19. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  20. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +5 -2
  21. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +564 -451
  22. package/src/shade/device/ShadeGPUCommandContext.d.ts +18 -2
  23. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  24. package/src/shade/device/ShadeGPUCommandContext.js +994 -940
  25. package/src/shade/device/immediate_data_supported.d.ts +33 -0
  26. package/src/shade/device/immediate_data_supported.d.ts.map +1 -0
  27. package/src/shade/device/immediate_data_supported.js +53 -0
  28. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts +18 -0
  29. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts.map +1 -1
  30. package/src/shade/device/mock/SoftwareGPUCommandEncoder.js +24 -0
  31. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts +7 -0
  32. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts.map +1 -1
  33. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.js +49 -1
  34. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  35. package/src/shade/device/mock/SoftwareGPUDevice.js +20 -2
  36. package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts +65 -0
  37. package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts.map +1 -0
  38. package/src/shade/device/mock/SoftwareGPUImmediateData.js +160 -0
  39. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts +7 -0
  40. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts.map +1 -1
  41. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.js +50 -0
  42. package/src/shade/device/mock/pipeline_immediate_size.d.ts +11 -0
  43. package/src/shade/device/mock/pipeline_immediate_size.d.ts.map +1 -0
  44. package/src/shade/device/mock/pipeline_immediate_size.js +18 -0
  45. package/src/shade/device/pipeline/PipelineLayoutManager.d.ts.map +1 -1
  46. package/src/shade/device/pipeline/PipelineLayoutManager.js +1 -0
  47. package/src/shade/playground/volumetrics_froxel/README.md +104 -1
  48. package/src/shade/playground/volumetrics_froxel/index.html +20 -1
  49. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  50. package/src/shade/playground/volumetrics_froxel/main.js +298 -0
  51. package/src/shade/playground/volumetrics_froxel/measure.d.ts +119 -0
  52. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -0
  53. package/src/shade/playground/volumetrics_froxel/measure.js +559 -0
  54. package/src/shade/renderer/GraphicsContext.d.ts +9 -2
  55. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  56. package/src/shade/renderer/GraphicsContext.js +13 -1
  57. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  58. package/src/shade/renderer/Renderer.js +22 -18
  59. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  60. package/src/shade/renderer/atmosphere/GPUSky.js +145 -142
  61. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +34 -0
  62. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -0
  63. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +36 -0
  64. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts +20 -0
  65. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts.map +1 -0
  66. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.js +25 -0
  67. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +14 -1
  68. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
  69. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +163 -177
  70. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts +20 -0
  71. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts.map +1 -0
  72. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.js +46 -0
  73. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts +11 -1
  74. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts.map +1 -1
  75. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.js +57 -27
  76. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts +19 -1
  77. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts.map +1 -1
  78. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.js +69 -33
  79. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts +13 -0
  80. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts.map +1 -1
  81. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.js +35 -35
  82. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts +13 -0
  83. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts.map +1 -0
  84. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.js +38 -0
  85. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts +17 -0
  86. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts.map +1 -0
  87. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.js +29 -0
  88. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts +21 -0
  89. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts.map +1 -0
  90. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.js +42 -0
  91. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts +2 -2
  92. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
  93. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +165 -84
  94. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts.map +1 -1
  95. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +215 -204
  96. package/src/shade/renderer/atmosphere/shader_transmittance_lut.d.ts.map +1 -1
  97. package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +79 -67
  98. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  99. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +6 -2
  100. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  101. package/src/shade/renderer/postprocess/gtao/GTAO.js +4 -0
  102. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  103. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  104. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +341 -345
  105. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  106. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  107. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
  108. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  109. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +7 -3
  110. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  111. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +77 -81
  112. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  113. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +5 -1
  114. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  115. package/src/shade/renderer/shader/ComputeShader.js +6 -2
  116. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  117. package/src/shade/renderer/shader/ImageShader.js +4 -1
  118. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  119. package/src/shade/renderer/shader/ShaderDescriptor.js +26 -0
  120. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts +18 -0
  121. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts.map +1 -0
  122. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.js +32 -0
  123. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts +7 -0
  124. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts.map +1 -1
  125. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.js +17 -6
  126. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts +21 -0
  127. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts.map +1 -0
  128. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.js +69 -0
  129. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts +9 -0
  130. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts.map +1 -0
  131. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.js +22 -0
  132. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts +16 -0
  133. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts.map +1 -0
  134. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.js +41 -0
  135. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts +11 -0
  136. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts.map +1 -1
  137. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.js +15 -19
  138. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts +23 -0
  139. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts.map +1 -0
  140. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.js +44 -0
  141. package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.d.ts.map +1 -1
  142. package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.js +1 -4
  143. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +7 -1
  144. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  145. package/src/shade/renderer/shader/compiler/CodeChunk.js +37 -2
  146. package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.d.ts.map +1 -1
  147. package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.js +6 -0
  148. package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.js +1 -1
  149. package/src/shade/renderer/shader/graph/compute/graph_compute_pass.js +1 -1
  150. package/src/shade/renderer/shader/graph/graph_image_pass.js +1 -1
  151. package/src/shade/renderer/shader/graph/graph_prepare_bindings.d.ts.map +1 -1
  152. package/src/shade/renderer/shader/graph/graph_prepare_bindings.js +7 -0
  153. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts +3 -1
  154. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts.map +1 -1
  155. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.js +12 -1
  156. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  157. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +1 -0
  158. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts +21 -0
  159. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts.map +1 -0
  160. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.js +21 -0
  161. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts +59 -1
  162. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  163. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +195 -2
  164. package/src/shade/renderer/shader/type/type_has_arrays.d.ts +14 -0
  165. package/src/shade/renderer/shader/type/type_has_arrays.d.ts.map +1 -0
  166. package/src/shade/renderer/shader/type/type_has_arrays.js +33 -0
  167. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts +14 -13
  168. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
  169. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +133 -129
  170. package/src/shade/renderer/view/GPUViewSkyContext.d.ts.map +1 -1
  171. package/src/shade/renderer/view/GPUViewSkyContext.js +169 -173
  172. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  173. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +480 -315
  174. package/src/shade/renderer/volumetrics/NOTES.md +887 -8
  175. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +5 -0
  176. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  177. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +21 -2
  178. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +26 -0
  179. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  180. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +64 -21
  181. package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.d.ts.map +1 -1
  182. package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.js +84 -28
  183. package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.d.ts +98 -0
  184. package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.d.ts.map +1 -0
  185. package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.js +111 -0
  186. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts +84 -0
  187. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts.map +1 -0
  188. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.js +252 -0
  189. package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.js +75 -75
  190. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts +43 -0
  191. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts.map +1 -0
  192. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.js +145 -0
  193. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts +20 -0
  194. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts.map +1 -0
  195. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.js +48 -0
  196. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts +38 -0
  197. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts.map +1 -0
  198. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js +130 -0
  199. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +18 -3
  200. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  201. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +193 -70
  202. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +16 -0
  203. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  204. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +83 -15
  205. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  206. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +29 -18
  207. package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +260 -260
  208. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts +58 -0
  209. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -0
  210. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +290 -0
  211. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +25 -0
  212. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
  213. package/src/shade/wgsl/emulator/CPUBitmapData.js +33 -0
  214. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2228 -2215
  215. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  216. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +210 -2
  217. package/src/shade/wgsl/emulator/cpu_texture_gather.d.ts +69 -0
  218. package/src/shade/wgsl/emulator/cpu_texture_gather.d.ts.map +1 -0
  219. package/src/shade/wgsl/emulator/cpu_texture_gather.js +148 -0
  220. package/src/shade/wgsl/emulator/cpu_texture_sample.d.ts +16 -0
  221. package/src/shade/wgsl/emulator/cpu_texture_sample.d.ts.map +1 -1
  222. package/src/shade/wgsl/emulator/cpu_texture_sample.js +176 -172
  223. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts +0 -2
  224. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts.map +0 -1
  225. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.js +0 -1
@@ -1,346 +1,342 @@
1
- import { assert } from "../../../../core/assert.js";
2
- import { ceilPowerOfTwo } from "../../../../core/binary/operations/ceilPowerOfTwo.js";
3
- import { round_up } from "../../../../core/math/round_up.js";
4
- import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
5
- import { u32, vec2u } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
6
- import { STRUCT_UNINDEXED_DRAW_COMMAND } from "../../gpu_primitive/indirect/STRUCT_UNINDEXED_DRAW_COMMAND.js";
7
- import { cpu_build_hash_table } from "../../gpu_primitive/hash_table/cpu_build_hash_table.js";
8
- import { graph_prefix_scan_csdldf } from "../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
9
- import { shader_hzb_meshlet_filter_1way_full } from "../cull/hzb/shader_hzb_meshlet_filter_1way_full.js";
10
- import { COMPUTE_SHADER_DEFAULT_GROUP_SIZE } from "../../shader/COMPUTE_SHADER_DEFAULT_GROUP_SIZE.js";
11
- import { graph_import_raw_buffer } from "../../shader/graph/graph_import_raw_buffer.js";
12
- import { graph_record_stat } from "../../util/graph_record_stat.js";
13
- import {
14
- build_indirect_compute_dispatch_command,
15
- graph_build_indirect_dispatch_command,
16
- INDIRECT_COMPUTE_COMMAND_DESCRIPTOR
17
- } from "../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
18
- import { graph_mesh_filter_one_way } from "../expand/graph_mesh_filter_one_way.js";
19
- import { graph_expand_meshes_to_meshlets } from "../expand/mesh/graph_expand_meshes_to_meshlets.js";
20
- import { RasterizationCollectionType } from "../expand/RasterizationCollectionType.js";
21
- import { shader_count_meshlets_by_material } from "./shader_count_meshlets_by_material.js";
22
- import {
23
- shader_make_meshlet_indirect_draw_commands_by_material
24
- } from "./shader_make_meshlet_indirect_draw_commands_by_material.js";
25
- import { PUSH_CONSTANTS, shader_read_out_bucket } from "./shader_read_out_bucket.js";
26
- import { shader_sort_meshlets_by_material } from "./shader_sort_meshlets_by_material.js";
27
-
28
- /**
29
- *
30
- * @param {FrameGraph} graph
31
- * @param {ShadeMaterial[]} materials
32
- * @param {number} bucket_index
33
- * @param {GPUCollectionLimits} limits
34
- * @param {number} buckets resource ID
35
- * @param {number} [camera] camera resource ID, optional
36
- * @param {number} [hzb] hierarchical z-buffer resource ID, optional
37
- * @param {number[]} resolution
38
- * @param {string} [label] used for debug
39
- * @param {GPUSceneContext} scene
40
- */
41
- export function graph_prepare_meshlet_draw_commands_by_material({
42
- graph,
43
- materials,
44
- bucket_id,
45
- limits,
46
- buckets,
47
- hzb = -1,
48
- camera = -1,
49
- scene,
50
- resolution,
51
- label,
52
- }) {
53
-
54
- assert.defined(limits, 'limits');
55
- assert.defined(materials, 'materials');
56
- assert.isNonNegativeInteger(bucket_id, 'bucket_index');
57
-
58
- const copy_bucket_data = {};
59
-
60
- /**
61
- *
62
- * @param data
63
- * @param {FramePassResources} resources
64
- * @param {GraphicsExecutionContext} context
65
- */
66
- function copy_bucket(data, resources, context) {
67
- const encoder = context.encoder;
68
-
69
- const buckets_buffer = resources.get(data.buckets);
70
- const command = resources.get(data.command);
71
- const output = resources.get(data.output);
72
-
73
- build_indirect_compute_dispatch_command(
74
- COMPUTE_SHADER_DEFAULT_GROUP_SIZE,
75
- encoder,
76
- buckets_buffer,
77
- // the bucketed buffer header consists of pairs of u32 values (count,offset)
78
- bucket_id * (u32.size * 2),
79
- command,
80
- 0
81
- );
82
-
83
- const settings = encoder.allocateTransientValueBuffer(PUSH_CONSTANTS, {
84
- bucket_id,
85
- });
86
-
87
- shader_read_out_bucket.dispatchIndirect({
88
- encoder,
89
- command,
90
- bindings: {
91
- settings,
92
- input: buckets_buffer,
93
- output,
94
- }
95
- });
96
- }
97
-
98
- const copy_bucket_pass = graph.add('copy bucket', copy_bucket_data, copy_bucket);
99
-
100
- copy_bucket_data.buckets = copy_bucket_pass.read(buckets);
101
- copy_bucket_data.command = copy_bucket_pass.create("command", INDIRECT_COMPUTE_COMMAND_DESCRIPTOR);
102
- const mesh_buffer_size = limits.compute_buffer_size(RasterizationCollectionType.Meshes);
103
- copy_bucket_data.output = copy_bucket_pass.create("output", BufferResourceDescriptor.from(
104
- mesh_buffer_size,
105
- GPUBufferUsage.STORAGE,
106
- 0, 16 // clear count; an empty bucket dispatches zero workgroups and writes nothing
107
- ));
108
- let meshes = copy_bucket_data.output;
109
-
110
- if (hzb !== -1 && camera !== -1) {
111
- // filter source meshes
112
- meshes = graph_mesh_filter_one_way({
113
- graph,
114
- scene,
115
- camera,
116
- hzb,
117
- input: meshes,
118
- output_size: mesh_buffer_size
119
- });
120
- }
121
-
122
- // 1. expand meshes
123
- const meshlet_buffer_size = limits.compute_buffer_size(RasterizationCollectionType.Meshlets);
124
- let meshlets = graph_expand_meshes_to_meshlets({
125
- graph,
126
- input_meshes: meshes,
127
- scene,
128
- stats: limits.stats,
129
- limits,
130
- expected_output_size: meshlet_buffer_size,
131
- });
132
-
133
- graph_record_stat(graph, limits.stats, RasterizationCollectionType.Meshlets, meshlets);
134
-
135
- if (hzb !== -1 && camera !== -1) {
136
- // filter meshlets
137
- const command = graph_build_indirect_dispatch_command(graph, meshlets, COMPUTE_SHADER_DEFAULT_GROUP_SIZE)
138
-
139
-
140
- /**
141
- *
142
- * @param data
143
- * @param {FramePassResources} resources
144
- * @param {GraphicsExecutionContext} context
145
- */
146
- function filter_meshlets(data, resources, context) {
147
- const encoder = context.encoder;
148
-
149
- const camera_state = resources.get(data.camera);
150
- const input = resources.get(data.input_meshlets);
151
- const output = resources.get(data.output_meshlets);
152
- const hzb = resources.get(data.texture_hzb);
153
- const command = resources.get(data.command);
154
-
155
- const uResolution = encoder.allocateTransientValueBuffer(vec2u, resolution);
156
-
157
- shader_hzb_meshlet_filter_1way_full.dispatchIndirect({
158
- encoder,
159
- command,
160
- bindings: {
161
- camera: camera_state,
162
- resolution: uResolution,
163
- scene_database: scene.scene_database_buffer,
164
- meshlet_metadata: scene.geometries.meshlets.buffer_metadata,
165
- texture_hzb: hzb.obtainView(),
166
- input,
167
- output
168
- }
169
- })
170
- }
171
-
172
- const data = {};
173
-
174
- const pass = graph.add('filter meshlets', data, filter_meshlets);
175
-
176
- data.scene = scene;
177
- data.command = pass.read(command);
178
- data.texture_hzb = pass.read(hzb);
179
- data.input_meshlets = pass.read(meshlets);
180
- data.output_meshlets = pass.create("filtered", BufferResourceDescriptor.from(
181
- meshlet_buffer_size,
182
- GPUBufferUsage.STORAGE,
183
- 0, 16
184
- ));
185
- data.camera = pass.read(camera);
186
-
187
-
188
- meshlets = data.output_meshlets;
189
-
190
- }
191
-
192
- // 2. build material lookup table
193
- const material_ids = materials.map(m => m.id);
194
- const material_count = material_ids.length;
195
- const HASH_TABLE_SLACK = 1.3;
196
- const material_table_size = ceilPowerOfTwo(Math.max(1, material_count * HASH_TABLE_SLACK));
197
- const material_lookup_data = new ArrayBuffer((material_table_size * 2 + 2) * 4)
198
- const material_lookup = new Uint32Array(material_lookup_data);
199
- cpu_build_hash_table(
200
- material_lookup, 0,
201
- material_table_size,
202
- material_ids,
203
- material_count,
204
- );
205
-
206
- // TODO build the table on the GPU
207
- const gr_material_lookup = graph_import_raw_buffer({
208
- graph,
209
- value: material_lookup_data,
210
- usage: GPUBufferUsage.STORAGE,
211
- });
212
-
213
- // 3. Build meshlet iterator command to be used in later passes
214
- const meshlet_iterator_command = graph_build_indirect_dispatch_command(graph, meshlets, COMPUTE_SHADER_DEFAULT_GROUP_SIZE);
215
-
216
- // 4. build meshlet counts by material
217
- const count_by_material_data = {};
218
-
219
- /**
220
- *
221
- * @param data
222
- * @param {FramePassResources} resources
223
- * @param {GraphicsExecutionContext} context
224
- */
225
- function count_by_material(data, resources, context) {
226
- const input_meshlets = resources.get(data.meshlets);
227
- const output_counts = resources.get(data.counts);
228
- const command = resources.get(data.command);
229
- const material_lookup = resources.get(data.material_lookup);
230
-
231
- //
232
- shader_count_meshlets_by_material.dispatchIndirect({
233
- encoder: context.encoder,
234
- command,
235
- bindings: {
236
- input: input_meshlets,
237
- output: output_counts,
238
- scene_database: scene.scene_database_buffer,
239
- material_lookup,
240
- }
241
- })
242
- }
243
-
244
- const count_by_material_pass = graph.add('meshlet counts by material', count_by_material_data, count_by_material);
245
- count_by_material_data.meshlets = count_by_material_pass.read(meshlets);
246
- count_by_material_data.counts = count_by_material_pass.create("counts", BufferResourceDescriptor.empty(
247
- round_up((material_count + 4) * u32.size, 1024),
248
- GPUBufferUsage.STORAGE
249
- ));
250
- count_by_material_data.material_lookup = count_by_material_pass.read(gr_material_lookup);
251
- count_by_material_data.command = count_by_material_pass.read(meshlet_iterator_command);
252
-
253
- // 5. prefix scan meshlets by material
254
- const prefix_sum = graph_prefix_scan_csdldf({
255
- graph,
256
- data: count_by_material_data.counts,
257
- element_max_count: Math.max(1, material_count),
258
- });
259
- // 6. Sort meshlets by material, using the prefix sum
260
- const sort_meshlets_by_material_data = {};
261
-
262
- /**
263
- *
264
- * @param data
265
- * @param {FramePassResources} resources
266
- * @param {GraphicsExecutionContext} context
267
- */
268
- function sort_meshlets_by_material(data, resources, context) {
269
- const prefix_sums = resources.get(data.prefix_sums);
270
- const input_meshlets = resources.get(data.input);
271
- const output_meshlets = resources.get(data.output);
272
- const command = resources.get(data.command);
273
- const material_lookup = resources.get(data.material_lookup);
274
- const counters = resources.get(data.counters);
275
-
276
- const encoder = context.encoder;
277
-
278
- shader_sort_meshlets_by_material.dispatchIndirect({
279
- encoder,
280
- command,
281
- bindings: {
282
- prefix_sums,
283
- input: input_meshlets,
284
- output: output_meshlets,
285
- scene_database: scene.scene_database_buffer,
286
- material_lookup,
287
- counters,
288
- }
289
- });
290
- }
291
-
292
- const sort_meshlets_by_material_pass = graph.add('sort meshlets by material', sort_meshlets_by_material_data, sort_meshlets_by_material);
293
- sort_meshlets_by_material_data.prefix_sums = sort_meshlets_by_material_pass.read(prefix_sum);
294
- sort_meshlets_by_material_data.input = sort_meshlets_by_material_pass.read(meshlets);
295
- sort_meshlets_by_material_data.material_lookup = sort_meshlets_by_material_pass.read(gr_material_lookup);
296
- sort_meshlets_by_material_data.counters = sort_meshlets_by_material_pass.create("counters", BufferResourceDescriptor.empty(
297
- round_up(Math.max(1, material_count) * u32.size, 1024),
298
- GPUBufferUsage.STORAGE
299
- ));
300
- sort_meshlets_by_material_data.command = sort_meshlets_by_material_pass.read(meshlet_iterator_command);
301
- sort_meshlets_by_material_data.output = sort_meshlets_by_material_pass.create("sorted meshlets", BufferResourceDescriptor.from(
302
- limits.compute_buffer_size(RasterizationCollectionType.Meshlets),
303
- GPUBufferUsage.STORAGE,
304
- ));
305
-
306
- // 7. Build draw commands
307
- const draw_commands_data = {};
308
-
309
- /**
310
- *
311
- * @param data
312
- * @param {FramePassResources} resources
313
- * @param {GraphicsExecutionContext} context
314
- */
315
- function build_draw_commands(data, resources, context) {
316
- if (material_count === 0) {
317
- return;
318
- }
319
-
320
- const prefix_sums = resources.get(data.prefix_sums);
321
- const commands = resources.get(data.commands);
322
-
323
- shader_make_meshlet_indirect_draw_commands_by_material.dispatchLinear({
324
- encoder: context.encoder,
325
- element_count: material_count,
326
- bindings: {
327
- commands,
328
- prefix_sums,
329
- }
330
- })
331
- }
332
-
333
- const build_draw_commands_pass = graph.add('build draw commands', draw_commands_data, build_draw_commands);
334
- draw_commands_data.prefix_sums = build_draw_commands_pass.read(prefix_sum);
335
-
336
- // NOTE: clearing is critical. We might end up with no writes which would produce garbage without clearing
337
- draw_commands_data.commands = build_draw_commands_pass.create("commands", BufferResourceDescriptor.empty(
338
- STRUCT_UNINDEXED_DRAW_COMMAND.size * material_count,
339
- GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT,
340
- ));
341
-
342
- return {
343
- meshlets: sort_meshlets_by_material_data.output,
344
- draw_commands: draw_commands_data.commands
345
- }
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { ceilPowerOfTwo } from "../../../../core/binary/operations/ceilPowerOfTwo.js";
3
+ import { round_up } from "../../../../core/math/round_up.js";
4
+ import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
5
+ import { u32, vec2u } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
6
+ import { STRUCT_UNINDEXED_DRAW_COMMAND } from "../../gpu_primitive/indirect/STRUCT_UNINDEXED_DRAW_COMMAND.js";
7
+ import { cpu_build_hash_table } from "../../gpu_primitive/hash_table/cpu_build_hash_table.js";
8
+ import { graph_prefix_scan_csdldf } from "../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
9
+ import { shader_hzb_meshlet_filter_1way_full } from "../cull/hzb/shader_hzb_meshlet_filter_1way_full.js";
10
+ import { COMPUTE_SHADER_DEFAULT_GROUP_SIZE } from "../../shader/COMPUTE_SHADER_DEFAULT_GROUP_SIZE.js";
11
+ import { graph_import_raw_buffer } from "../../shader/graph/graph_import_raw_buffer.js";
12
+ import { graph_record_stat } from "../../util/graph_record_stat.js";
13
+ import {
14
+ build_indirect_compute_dispatch_command,
15
+ graph_build_indirect_dispatch_command,
16
+ INDIRECT_COMPUTE_COMMAND_DESCRIPTOR
17
+ } from "../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
18
+ import { graph_mesh_filter_one_way } from "../expand/graph_mesh_filter_one_way.js";
19
+ import { graph_expand_meshes_to_meshlets } from "../expand/mesh/graph_expand_meshes_to_meshlets.js";
20
+ import { RasterizationCollectionType } from "../expand/RasterizationCollectionType.js";
21
+ import { shader_count_meshlets_by_material } from "./shader_count_meshlets_by_material.js";
22
+ import {
23
+ shader_make_meshlet_indirect_draw_commands_by_material
24
+ } from "./shader_make_meshlet_indirect_draw_commands_by_material.js";
25
+ import { shader_read_out_bucket } from "./shader_read_out_bucket.js";
26
+ import { shader_sort_meshlets_by_material } from "./shader_sort_meshlets_by_material.js";
27
+
28
+ /**
29
+ *
30
+ * @param {FrameGraph} graph
31
+ * @param {ShadeMaterial[]} materials
32
+ * @param {number} bucket_index
33
+ * @param {GPUCollectionLimits} limits
34
+ * @param {number} buckets resource ID
35
+ * @param {number} [camera] camera resource ID, optional
36
+ * @param {number} [hzb] hierarchical z-buffer resource ID, optional
37
+ * @param {number[]} resolution
38
+ * @param {string} [label] used for debug
39
+ * @param {GPUSceneContext} scene
40
+ */
41
+ export function graph_prepare_meshlet_draw_commands_by_material({
42
+ graph,
43
+ materials,
44
+ bucket_id,
45
+ limits,
46
+ buckets,
47
+ hzb = -1,
48
+ camera = -1,
49
+ scene,
50
+ resolution,
51
+ label,
52
+ }) {
53
+
54
+ assert.defined(limits, 'limits');
55
+ assert.defined(materials, 'materials');
56
+ assert.isNonNegativeInteger(bucket_id, 'bucket_index');
57
+
58
+ const copy_bucket_data = {};
59
+
60
+ /**
61
+ *
62
+ * @param data
63
+ * @param {FramePassResources} resources
64
+ * @param {GraphicsExecutionContext} context
65
+ */
66
+ function copy_bucket(data, resources, context) {
67
+ const encoder = context.encoder;
68
+
69
+ const buckets_buffer = resources.get(data.buckets);
70
+ const command = resources.get(data.command);
71
+ const output = resources.get(data.output);
72
+
73
+ build_indirect_compute_dispatch_command(
74
+ COMPUTE_SHADER_DEFAULT_GROUP_SIZE,
75
+ encoder,
76
+ buckets_buffer,
77
+ // the bucketed buffer header consists of pairs of u32 values (count,offset)
78
+ bucket_id * (u32.size * 2),
79
+ command,
80
+ 0
81
+ );
82
+
83
+ shader_read_out_bucket.dispatchIndirect({
84
+ encoder,
85
+ command,
86
+ bindings: {
87
+ settings: { bucket_id },
88
+ input: buckets_buffer,
89
+ output,
90
+ }
91
+ });
92
+ }
93
+
94
+ const copy_bucket_pass = graph.add('copy bucket', copy_bucket_data, copy_bucket);
95
+
96
+ copy_bucket_data.buckets = copy_bucket_pass.read(buckets);
97
+ copy_bucket_data.command = copy_bucket_pass.create("command", INDIRECT_COMPUTE_COMMAND_DESCRIPTOR);
98
+ const mesh_buffer_size = limits.compute_buffer_size(RasterizationCollectionType.Meshes);
99
+ copy_bucket_data.output = copy_bucket_pass.create("output", BufferResourceDescriptor.from(
100
+ mesh_buffer_size,
101
+ GPUBufferUsage.STORAGE,
102
+ 0, 16 // clear count; an empty bucket dispatches zero workgroups and writes nothing
103
+ ));
104
+ let meshes = copy_bucket_data.output;
105
+
106
+ if (hzb !== -1 && camera !== -1) {
107
+ // filter source meshes
108
+ meshes = graph_mesh_filter_one_way({
109
+ graph,
110
+ scene,
111
+ camera,
112
+ hzb,
113
+ input: meshes,
114
+ output_size: mesh_buffer_size
115
+ });
116
+ }
117
+
118
+ // 1. expand meshes
119
+ const meshlet_buffer_size = limits.compute_buffer_size(RasterizationCollectionType.Meshlets);
120
+ let meshlets = graph_expand_meshes_to_meshlets({
121
+ graph,
122
+ input_meshes: meshes,
123
+ scene,
124
+ stats: limits.stats,
125
+ limits,
126
+ expected_output_size: meshlet_buffer_size,
127
+ });
128
+
129
+ graph_record_stat(graph, limits.stats, RasterizationCollectionType.Meshlets, meshlets);
130
+
131
+ if (hzb !== -1 && camera !== -1) {
132
+ // filter meshlets
133
+ const command = graph_build_indirect_dispatch_command(graph, meshlets, COMPUTE_SHADER_DEFAULT_GROUP_SIZE)
134
+
135
+
136
+ /**
137
+ *
138
+ * @param data
139
+ * @param {FramePassResources} resources
140
+ * @param {GraphicsExecutionContext} context
141
+ */
142
+ function filter_meshlets(data, resources, context) {
143
+ const encoder = context.encoder;
144
+
145
+ const camera_state = resources.get(data.camera);
146
+ const input = resources.get(data.input_meshlets);
147
+ const output = resources.get(data.output_meshlets);
148
+ const hzb = resources.get(data.texture_hzb);
149
+ const command = resources.get(data.command);
150
+
151
+ const uResolution = encoder.allocateTransientValueBuffer(vec2u, resolution);
152
+
153
+ shader_hzb_meshlet_filter_1way_full.dispatchIndirect({
154
+ encoder,
155
+ command,
156
+ bindings: {
157
+ camera: camera_state,
158
+ resolution: uResolution,
159
+ scene_database: scene.scene_database_buffer,
160
+ meshlet_metadata: scene.geometries.meshlets.buffer_metadata,
161
+ texture_hzb: hzb.obtainView(),
162
+ input,
163
+ output
164
+ }
165
+ })
166
+ }
167
+
168
+ const data = {};
169
+
170
+ const pass = graph.add('filter meshlets', data, filter_meshlets);
171
+
172
+ data.scene = scene;
173
+ data.command = pass.read(command);
174
+ data.texture_hzb = pass.read(hzb);
175
+ data.input_meshlets = pass.read(meshlets);
176
+ data.output_meshlets = pass.create("filtered", BufferResourceDescriptor.from(
177
+ meshlet_buffer_size,
178
+ GPUBufferUsage.STORAGE,
179
+ 0, 16
180
+ ));
181
+ data.camera = pass.read(camera);
182
+
183
+
184
+ meshlets = data.output_meshlets;
185
+
186
+ }
187
+
188
+ // 2. build material lookup table
189
+ const material_ids = materials.map(m => m.id);
190
+ const material_count = material_ids.length;
191
+ const HASH_TABLE_SLACK = 1.3;
192
+ const material_table_size = ceilPowerOfTwo(Math.max(1, material_count * HASH_TABLE_SLACK));
193
+ const material_lookup_data = new ArrayBuffer((material_table_size * 2 + 2) * 4)
194
+ const material_lookup = new Uint32Array(material_lookup_data);
195
+ cpu_build_hash_table(
196
+ material_lookup, 0,
197
+ material_table_size,
198
+ material_ids,
199
+ material_count,
200
+ );
201
+
202
+ // TODO build the table on the GPU
203
+ const gr_material_lookup = graph_import_raw_buffer({
204
+ graph,
205
+ value: material_lookup_data,
206
+ usage: GPUBufferUsage.STORAGE,
207
+ });
208
+
209
+ // 3. Build meshlet iterator command to be used in later passes
210
+ const meshlet_iterator_command = graph_build_indirect_dispatch_command(graph, meshlets, COMPUTE_SHADER_DEFAULT_GROUP_SIZE);
211
+
212
+ // 4. build meshlet counts by material
213
+ const count_by_material_data = {};
214
+
215
+ /**
216
+ *
217
+ * @param data
218
+ * @param {FramePassResources} resources
219
+ * @param {GraphicsExecutionContext} context
220
+ */
221
+ function count_by_material(data, resources, context) {
222
+ const input_meshlets = resources.get(data.meshlets);
223
+ const output_counts = resources.get(data.counts);
224
+ const command = resources.get(data.command);
225
+ const material_lookup = resources.get(data.material_lookup);
226
+
227
+ //
228
+ shader_count_meshlets_by_material.dispatchIndirect({
229
+ encoder: context.encoder,
230
+ command,
231
+ bindings: {
232
+ input: input_meshlets,
233
+ output: output_counts,
234
+ scene_database: scene.scene_database_buffer,
235
+ material_lookup,
236
+ }
237
+ })
238
+ }
239
+
240
+ const count_by_material_pass = graph.add('meshlet counts by material', count_by_material_data, count_by_material);
241
+ count_by_material_data.meshlets = count_by_material_pass.read(meshlets);
242
+ count_by_material_data.counts = count_by_material_pass.create("counts", BufferResourceDescriptor.empty(
243
+ round_up((material_count + 4) * u32.size, 1024),
244
+ GPUBufferUsage.STORAGE
245
+ ));
246
+ count_by_material_data.material_lookup = count_by_material_pass.read(gr_material_lookup);
247
+ count_by_material_data.command = count_by_material_pass.read(meshlet_iterator_command);
248
+
249
+ // 5. prefix scan meshlets by material
250
+ const prefix_sum = graph_prefix_scan_csdldf({
251
+ graph,
252
+ data: count_by_material_data.counts,
253
+ element_max_count: Math.max(1, material_count),
254
+ });
255
+ // 6. Sort meshlets by material, using the prefix sum
256
+ const sort_meshlets_by_material_data = {};
257
+
258
+ /**
259
+ *
260
+ * @param data
261
+ * @param {FramePassResources} resources
262
+ * @param {GraphicsExecutionContext} context
263
+ */
264
+ function sort_meshlets_by_material(data, resources, context) {
265
+ const prefix_sums = resources.get(data.prefix_sums);
266
+ const input_meshlets = resources.get(data.input);
267
+ const output_meshlets = resources.get(data.output);
268
+ const command = resources.get(data.command);
269
+ const material_lookup = resources.get(data.material_lookup);
270
+ const counters = resources.get(data.counters);
271
+
272
+ const encoder = context.encoder;
273
+
274
+ shader_sort_meshlets_by_material.dispatchIndirect({
275
+ encoder,
276
+ command,
277
+ bindings: {
278
+ prefix_sums,
279
+ input: input_meshlets,
280
+ output: output_meshlets,
281
+ scene_database: scene.scene_database_buffer,
282
+ material_lookup,
283
+ counters,
284
+ }
285
+ });
286
+ }
287
+
288
+ const sort_meshlets_by_material_pass = graph.add('sort meshlets by material', sort_meshlets_by_material_data, sort_meshlets_by_material);
289
+ sort_meshlets_by_material_data.prefix_sums = sort_meshlets_by_material_pass.read(prefix_sum);
290
+ sort_meshlets_by_material_data.input = sort_meshlets_by_material_pass.read(meshlets);
291
+ sort_meshlets_by_material_data.material_lookup = sort_meshlets_by_material_pass.read(gr_material_lookup);
292
+ sort_meshlets_by_material_data.counters = sort_meshlets_by_material_pass.create("counters", BufferResourceDescriptor.empty(
293
+ round_up(Math.max(1, material_count) * u32.size, 1024),
294
+ GPUBufferUsage.STORAGE
295
+ ));
296
+ sort_meshlets_by_material_data.command = sort_meshlets_by_material_pass.read(meshlet_iterator_command);
297
+ sort_meshlets_by_material_data.output = sort_meshlets_by_material_pass.create("sorted meshlets", BufferResourceDescriptor.from(
298
+ limits.compute_buffer_size(RasterizationCollectionType.Meshlets),
299
+ GPUBufferUsage.STORAGE,
300
+ ));
301
+
302
+ // 7. Build draw commands
303
+ const draw_commands_data = {};
304
+
305
+ /**
306
+ *
307
+ * @param data
308
+ * @param {FramePassResources} resources
309
+ * @param {GraphicsExecutionContext} context
310
+ */
311
+ function build_draw_commands(data, resources, context) {
312
+ if (material_count === 0) {
313
+ return;
314
+ }
315
+
316
+ const prefix_sums = resources.get(data.prefix_sums);
317
+ const commands = resources.get(data.commands);
318
+
319
+ shader_make_meshlet_indirect_draw_commands_by_material.dispatchLinear({
320
+ encoder: context.encoder,
321
+ element_count: material_count,
322
+ bindings: {
323
+ commands,
324
+ prefix_sums,
325
+ }
326
+ })
327
+ }
328
+
329
+ const build_draw_commands_pass = graph.add('build draw commands', draw_commands_data, build_draw_commands);
330
+ draw_commands_data.prefix_sums = build_draw_commands_pass.read(prefix_sum);
331
+
332
+ // NOTE: clearing is critical. We might end up with no writes which would produce garbage without clearing
333
+ draw_commands_data.commands = build_draw_commands_pass.create("commands", BufferResourceDescriptor.empty(
334
+ STRUCT_UNINDEXED_DRAW_COMMAND.size * material_count,
335
+ GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT,
336
+ ));
337
+
338
+ return {
339
+ meshlets: sort_meshlets_by_material_data.output,
340
+ draw_commands: draw_commands_data.commands
341
+ }
346
342
  }