@woosh/meep-engine 3.49.0 → 3.50.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 (1364) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +11 -0
  3. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  4. package/editor/particles/effect/ParticleReferenceSimulation.js +28 -0
  5. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  6. package/editor/view/particles/effect/ParticleGraphEditorView.js +2 -0
  7. package/package.json +1 -1
  8. package/src/core/color/xyz/m3_rgb_to_xyz_from_primaries.d.ts +11 -0
  9. package/src/core/color/xyz/m3_rgb_to_xyz_from_primaries.d.ts.map +1 -0
  10. package/src/core/color/xyz/m3_rgb_to_xyz_from_primaries.js +40 -0
  11. package/src/core/geom/3d/mat4/m4_decompose_rigid_array.d.ts +24 -0
  12. package/src/core/geom/3d/mat4/m4_decompose_rigid_array.d.ts.map +1 -0
  13. package/src/core/geom/3d/mat4/m4_decompose_rigid_array.js +80 -0
  14. package/src/core/geom/3d/shape/PosedShape3D.d.ts +10 -0
  15. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  16. package/src/core/geom/3d/shape/PosedShape3D.js +50 -11
  17. package/src/core/geom/3d/shape/TransformedShape3D.d.ts +37 -0
  18. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/TransformedShape3D.js +73 -49
  20. package/src/core/geom/3d/shape/UnionShape3D.d.ts +13 -0
  21. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  22. package/src/core/geom/3d/shape/UnionShape3D.js +17 -4
  23. package/src/core/geom/3d/shape/record/ShapeRecord.d.ts +65 -0
  24. package/src/core/geom/3d/shape/record/ShapeRecord.d.ts.map +1 -0
  25. package/src/core/geom/3d/shape/record/ShapeRecord.js +72 -0
  26. package/src/core/geom/3d/shape/record/ShapeRecordKind.d.ts +13 -0
  27. package/src/core/geom/3d/shape/record/ShapeRecordKind.d.ts.map +1 -0
  28. package/src/core/geom/3d/shape/record/ShapeRecordKind.js +39 -0
  29. package/src/core/geom/3d/shape/record/shape_record_local_bounds.d.ts +19 -0
  30. package/src/core/geom/3d/shape/record/shape_record_local_bounds.d.ts.map +1 -0
  31. package/src/core/geom/3d/shape/record/shape_record_local_bounds.js +61 -0
  32. package/src/core/geom/3d/shape/record/shape_record_pack.d.ts +88 -0
  33. package/src/core/geom/3d/shape/record/shape_record_pack.d.ts.map +1 -0
  34. package/src/core/geom/3d/shape/record/shape_record_pack.js +418 -0
  35. package/src/core/geom/3d/shape/record/shape_record_pack_bounding_box.d.ts +23 -0
  36. package/src/core/geom/3d/shape/record/shape_record_pack_bounding_box.d.ts.map +1 -0
  37. package/src/core/geom/3d/shape/record/shape_record_pack_bounding_box.js +69 -0
  38. package/src/core/geom/3d/shape/record/shape_record_signed_distance.d.ts +52 -0
  39. package/src/core/geom/3d/shape/record/shape_record_signed_distance.d.ts.map +1 -0
  40. package/src/core/geom/3d/shape/record/shape_record_signed_distance.js +135 -0
  41. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +7 -0
  42. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -1
  43. package/src/core/geom/3d/shape/sdf/sdf3_plane.js +7 -0
  44. package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.d.ts +3 -0
  45. package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.d.ts.map +1 -1
  46. package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +19 -13
  47. package/src/core/geom/clipmap/ClipmapWindowSet.d.ts +141 -0
  48. package/src/core/geom/clipmap/ClipmapWindowSet.d.ts.map +1 -0
  49. package/src/core/geom/clipmap/ClipmapWindowSet.js +301 -0
  50. package/src/core/geom/clipmap/clipmap_select_finest.d.ts +20 -0
  51. package/src/core/geom/clipmap/clipmap_select_finest.d.ts.map +1 -0
  52. package/src/core/geom/clipmap/clipmap_select_finest.js +53 -0
  53. package/src/core/geom/clipmap/quantize_hysteretic.d.ts +22 -0
  54. package/src/core/geom/clipmap/quantize_hysteretic.d.ts.map +1 -0
  55. package/src/core/geom/clipmap/quantize_hysteretic.js +33 -0
  56. package/src/core/geom/clipmap/window_scroll_regions.d.ts +25 -0
  57. package/src/core/geom/clipmap/window_scroll_regions.d.ts.map +1 -0
  58. package/src/core/geom/clipmap/window_scroll_regions.js +83 -0
  59. package/src/core/geom/vec3/v3_clamp_to_cone.d.ts +59 -0
  60. package/src/core/geom/vec3/v3_clamp_to_cone.d.ts.map +1 -0
  61. package/src/core/geom/vec3/v3_clamp_to_cone.js +197 -0
  62. package/src/core/math/falloff_quadratic.d.ts +13 -0
  63. package/src/core/math/falloff_quadratic.d.ts.map +1 -0
  64. package/src/core/math/falloff_quadratic.js +20 -0
  65. package/src/core/math/physics/fluid/vortex_swirl.d.ts +40 -0
  66. package/src/core/math/physics/fluid/vortex_swirl.d.ts.map +1 -0
  67. package/src/core/math/physics/fluid/vortex_swirl.js +91 -0
  68. package/src/core/math/physics/kinematics/rigid_velocity_at_point.d.ts +27 -0
  69. package/src/core/math/physics/kinematics/rigid_velocity_at_point.d.ts.map +1 -0
  70. package/src/core/math/physics/kinematics/rigid_velocity_at_point.js +40 -0
  71. package/src/engine/EngineHarness.d.ts.map +1 -1
  72. package/src/engine/EngineHarness.js +6 -0
  73. package/src/engine/ecs/EntityComponentDataset.d.ts +48 -4
  74. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  75. package/src/engine/ecs/EntityComponentDataset.js +120 -11
  76. package/src/engine/ecs/fow/FogOfWarVisibilityPredicate.d.ts.map +1 -1
  77. package/src/engine/ecs/fow/FogOfWarVisibilityPredicate.js +1 -3
  78. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  79. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +2 -0
  80. package/src/engine/ecs/terrain/util/obtainTerrain.d.ts.map +1 -1
  81. package/src/engine/ecs/terrain/util/obtainTerrain.js +5 -0
  82. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +8 -21
  83. package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -1
  84. package/src/engine/graphics/ecs/water/WaterWaves.js +8 -31
  85. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts +4 -0
  86. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -1
  87. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +5 -5
  88. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_1_2.d.ts +9 -0
  89. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_1_2.d.ts.map +1 -0
  90. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_1_2.js +19 -0
  91. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +21 -0
  92. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -1
  93. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +78 -0
  94. package/src/engine/graphics3/GPUFluidSystem.d.ts +266 -0
  95. package/src/engine/graphics3/GPUFluidSystem.d.ts.map +1 -0
  96. package/src/engine/graphics3/GPUFluidSystem.js +1613 -0
  97. package/src/engine/graphics3/ParticipatingMedia.d.ts +6 -0
  98. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -1
  99. package/src/engine/graphics3/ParticipatingMedia.js +6 -0
  100. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +32 -22
  101. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -1
  102. package/src/engine/graphics3/ParticipatingMediaSystem.js +218 -70
  103. package/src/engine/graphics3/WaterSystem.d.ts +9 -2
  104. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  105. package/src/engine/graphics3/WaterSystem.js +53 -15
  106. package/src/engine/physics/cloth/MEASUREMENTS.md +39 -0
  107. package/src/engine/physics/cloth/PLAN.md +21 -2
  108. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -1
  109. package/src/engine/physics/cloth/collider/ClothColliderKind.js +14 -7
  110. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +19 -5
  111. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -1
  112. package/src/engine/physics/cloth/collider/ClothColliderRecord.js +28 -5
  113. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +3 -2
  114. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
  115. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +26 -108
  116. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +6 -5
  117. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  118. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +18 -28
  119. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +6 -9
  120. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  121. package/src/engine/physics/cloth/ecs/ClothInstance.js +6 -9
  122. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +3 -2
  123. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  124. package/src/engine/physics/cloth/ecs/ClothSystem.js +3 -2
  125. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +38 -28
  126. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  127. package/src/engine/physics/cloth/ecs/ClothWorld.js +136 -28
  128. package/src/engine/physics/cloth/playground/README.md +8 -4
  129. package/src/engine/physics/cloth/playground/wind.html +4 -4
  130. package/src/engine/physics/cloth/playground/wind_build.d.ts +3 -2
  131. package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -1
  132. package/src/engine/physics/cloth/playground/wind_build.js +4 -3
  133. package/src/engine/physics/cloth/playground/wind_main.js +58 -19
  134. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +36 -35
  135. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/wind/AbstractClothWind.js +36 -35
  137. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +46 -25
  138. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  139. package/src/engine/physics/cloth/wind/ClothFluidWind.js +70 -30
  140. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts +96 -0
  141. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts.map +1 -0
  142. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.js +441 -0
  143. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +9 -7
  144. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/wind/cloth_sample_air.js +9 -7
  146. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +1 -1
  147. package/src/engine/physics/ecs/PhysicsSystem.d.ts +1 -1
  148. package/src/engine/physics/fluid/FluidAtmosphere.d.ts +80 -0
  149. package/src/engine/physics/fluid/FluidAtmosphere.d.ts.map +1 -0
  150. package/src/engine/physics/fluid/FluidAtmosphere.js +78 -0
  151. package/src/engine/physics/fluid/FluidField.d.ts +14 -2
  152. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  153. package/src/engine/physics/fluid/FluidField.js +26 -6
  154. package/src/engine/physics/fluid/FluidSimulator.d.ts +5 -1
  155. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  156. package/src/engine/physics/fluid/FluidSimulator.js +13 -2
  157. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +1382 -0
  158. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts +10 -4
  159. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts.map +1 -1
  160. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +13 -4
  161. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts +47 -0
  162. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts.map +1 -0
  163. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.js +72 -0
  164. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts +67 -0
  165. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts.map +1 -0
  166. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.js +307 -0
  167. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +6 -6
  168. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
  169. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +24 -13
  170. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -1
  171. package/src/engine/physics/fluid/ecs/FluidSystem.js +79 -15
  172. package/src/engine/physics/fluid/ecs/FluidWorkerCore.d.ts.map +1 -1
  173. package/src/engine/physics/fluid/ecs/FluidWorkerCore.js +17 -5
  174. package/src/engine/physics/fluid/ecs/GPUFluidComponent.d.ts +82 -0
  175. package/src/engine/physics/fluid/ecs/GPUFluidComponent.d.ts.map +1 -0
  176. package/src/engine/physics/fluid/ecs/GPUFluidComponent.js +124 -0
  177. package/src/engine/physics/fluid/ecs/GPUFluidComponentSerializationAdapter.d.ts +30 -0
  178. package/src/engine/physics/fluid/ecs/GPUFluidComponentSerializationAdapter.d.ts.map +1 -0
  179. package/src/engine/physics/fluid/ecs/GPUFluidComponentSerializationAdapter.js +51 -0
  180. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts +19 -10
  181. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts.map +1 -1
  182. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +64 -14
  183. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.d.ts +4 -1
  184. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.d.ts.map +1 -1
  185. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.js +9 -1
  186. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.d.ts +1 -0
  187. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.d.ts.map +1 -1
  188. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +9 -7
  189. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.d.ts +5 -3
  190. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.d.ts.map +1 -1
  191. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.js +5 -3
  192. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.d.ts +20 -2
  193. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.d.ts.map +1 -1
  194. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.js +34 -6
  195. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +46 -3
  196. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts.map +1 -1
  197. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +53 -3
  198. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +73 -13
  199. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  200. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +207 -88
  201. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts +35 -0
  202. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts.map +1 -0
  203. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.js +72 -0
  204. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts +34 -10
  205. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -1
  206. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +139 -150
  207. package/src/engine/physics/fluid/effector/ImpulseFluidEffectorSerializationAdapter.d.ts +26 -0
  208. package/src/engine/physics/fluid/effector/ImpulseFluidEffectorSerializationAdapter.d.ts.map +1 -0
  209. package/src/engine/physics/fluid/effector/ImpulseFluidEffectorSerializationAdapter.js +51 -0
  210. package/src/engine/physics/fluid/effector/VortexFluidEffector.d.ts +55 -0
  211. package/src/engine/physics/fluid/effector/VortexFluidEffector.d.ts.map +1 -0
  212. package/src/engine/physics/fluid/effector/VortexFluidEffector.js +255 -0
  213. package/src/engine/physics/fluid/effector/VortexFluidEffectorSerializationAdapter.d.ts +25 -0
  214. package/src/engine/physics/fluid/effector/VortexFluidEffectorSerializationAdapter.d.ts.map +1 -0
  215. package/src/engine/physics/fluid/effector/VortexFluidEffectorSerializationAdapter.js +52 -0
  216. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +22 -20
  217. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  218. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +181 -185
  219. package/src/engine/physics/fluid/effector/WakeFluidEffectorSerializationAdapter.d.ts +31 -0
  220. package/src/engine/physics/fluid/effector/WakeFluidEffectorSerializationAdapter.d.ts.map +1 -0
  221. package/src/engine/physics/fluid/effector/WakeFluidEffectorSerializationAdapter.js +56 -0
  222. package/src/engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.d.ts +52 -0
  223. package/src/engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.d.ts.map +1 -0
  224. package/src/engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.js +68 -0
  225. package/src/engine/physics/fluid/effector/record/FluidEffectorRecordKind.d.ts +10 -0
  226. package/src/engine/physics/fluid/effector/record/FluidEffectorRecordKind.d.ts.map +1 -0
  227. package/src/engine/physics/fluid/effector/record/FluidEffectorRecordKind.js +31 -0
  228. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_deposit.d.ts +25 -0
  229. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_deposit.d.ts.map +1 -0
  230. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_deposit.js +105 -0
  231. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.d.ts +17 -0
  232. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.d.ts.map +1 -0
  233. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.js +47 -0
  234. package/src/engine/physics/fluid/effector/record/fluid_effector_record_create.d.ts +54 -0
  235. package/src/engine/physics/fluid/effector/record/fluid_effector_record_create.d.ts.map +1 -0
  236. package/src/engine/physics/fluid/effector/record/fluid_effector_record_create.js +34 -0
  237. package/src/engine/physics/fluid/effector/record/fluid_effector_record_deposit.d.ts +98 -0
  238. package/src/engine/physics/fluid/effector/record/fluid_effector_record_deposit.d.ts.map +1 -0
  239. package/src/engine/physics/fluid/effector/record/fluid_effector_record_deposit.js +409 -0
  240. package/src/engine/physics/fluid/effector/record/fluid_effector_record_resolve.d.ts +25 -0
  241. package/src/engine/physics/fluid/effector/record/fluid_effector_record_resolve.d.ts.map +1 -0
  242. package/src/engine/physics/fluid/effector/record/fluid_effector_record_resolve.js +78 -0
  243. package/src/engine/physics/fluid/effector/record/fluid_record_apply.d.ts +27 -0
  244. package/src/engine/physics/fluid/effector/record/fluid_record_apply.d.ts.map +1 -0
  245. package/src/engine/physics/fluid/effector/record/fluid_record_apply.js +151 -0
  246. package/src/engine/physics/fluid/fluid_apply_atmosphere.d.ts +42 -0
  247. package/src/engine/physics/fluid/fluid_apply_atmosphere.d.ts.map +1 -0
  248. package/src/engine/physics/fluid/fluid_apply_atmosphere.js +148 -0
  249. package/src/engine/physics/fluid/fluid_atmosphere_to_grid.d.ts +16 -0
  250. package/src/engine/physics/fluid/fluid_atmosphere_to_grid.d.ts.map +1 -0
  251. package/src/engine/physics/fluid/fluid_atmosphere_to_grid.js +47 -0
  252. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts +32 -0
  253. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts.map +1 -0
  254. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js +50 -0
  255. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +24 -0
  256. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -0
  257. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +61 -0
  258. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts +58 -0
  259. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts.map +1 -0
  260. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.js +35 -0
  261. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_evaluate.d.ts +34 -0
  262. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_evaluate.d.ts.map +1 -0
  263. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_evaluate.js +90 -0
  264. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_extent.d.ts +17 -0
  265. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_extent.d.ts.map +1 -0
  266. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_extent.js +44 -0
  267. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts +98 -0
  268. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts.map +1 -0
  269. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.js +281 -0
  270. package/src/engine/physics/fluid/prototype.js +2 -0
  271. package/src/engine/physics/narrowphase/rigid_subject_pose.d.ts.map +1 -1
  272. package/src/engine/physics/narrowphase/rigid_subject_pose.js +3 -43
  273. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +4 -4
  274. package/src/shade/assets/textures/split_sum.bin +0 -0
  275. package/src/shade/device/ShadeGPUCommandContext.d.ts +20 -0
  276. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  277. package/src/shade/device/ShadeGPUCommandContext.js +25 -8
  278. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts +6 -2
  279. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts.map +1 -1
  280. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.js +7 -3
  281. package/src/shade/playground/avboit/main.d.ts.map +1 -1
  282. package/src/shade/playground/avboit/main.js +9 -6
  283. package/src/shade/playground/particle_ecs/README.md +20 -0
  284. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +10 -0
  285. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -1
  286. package/src/shade/playground/particle_ecs/bonfire_effects.js +10 -0
  287. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts +48 -0
  288. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts.map +1 -0
  289. package/src/shade/playground/particle_ecs/bonfire_wind.js +83 -0
  290. package/src/shade/playground/particle_ecs/effects/embers.json +1695 -1633
  291. package/src/shade/playground/particle_ecs/effects/flame.json +63 -1
  292. package/src/shade/playground/particle_ecs/effects/smoke.json +14 -14
  293. package/src/shade/playground/particle_ecs/effects/soot.json +63 -1
  294. package/src/shade/playground/particle_ecs/index.html +21 -0
  295. package/src/shade/playground/particle_ecs/main.js +35 -1
  296. package/src/shade/playground/path_traced_media/main.js +12 -10
  297. package/src/shade/playground/render_submitted_frames.d.ts +20 -0
  298. package/src/shade/playground/render_submitted_frames.d.ts.map +1 -0
  299. package/src/shade/playground/render_submitted_frames.js +29 -0
  300. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  301. package/src/shade/playground/skinned_blas_refit/main.js +4 -6
  302. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
  303. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +267 -270
  304. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  305. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +3 -6
  306. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  307. package/src/shade/playground/skinned_mesh_soup/main.js +4 -5
  308. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +438 -438
  309. package/src/shade/playground/ssr_motion/README.md +24 -22
  310. package/src/shade/playground/ssr_motion/main.js +150 -149
  311. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +1 -1
  312. package/src/shade/playground/ssr_reprojection/main.js +5 -3
  313. package/src/shade/playground/ssr_variance/capture.js +1 -1
  314. package/src/shade/playground/ssr_variance/main.js +247 -246
  315. package/src/shade/playground/submit_frame.d.ts +25 -0
  316. package/src/shade/playground/submit_frame.d.ts.map +1 -0
  317. package/src/shade/playground/submit_frame.js +36 -0
  318. package/src/shade/playground/tonemap_sdr/README.md +1 -1
  319. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts.map +1 -1
  320. package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +13 -4
  321. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  322. package/src/shade/playground/volumetrics_froxel/main.js +7 -1
  323. package/src/shade/playground/water_refraction/README.md +4 -2
  324. package/src/shade/playground/water_refraction/main.js +19 -3
  325. package/src/shade/playground/water_refraction/world.d.ts.map +1 -1
  326. package/src/shade/playground/water_refraction/world.js +2 -1
  327. package/src/shade/playground/water_surface/README.md +15 -7
  328. package/src/shade/playground/water_surface/index.html +2 -1
  329. package/src/shade/playground/water_surface/main.js +39 -7
  330. package/src/shade/playground/water_surface/world.d.ts +2 -5
  331. package/src/shade/playground/water_surface/world.d.ts.map +1 -1
  332. package/src/shade/playground/water_surface/world.js +9 -8
  333. package/src/shade/renderer/INDIRECT_LIGHTING.d.ts +13 -0
  334. package/src/shade/renderer/INDIRECT_LIGHTING.d.ts.map +1 -0
  335. package/src/shade/renderer/INDIRECT_LIGHTING.js +14 -0
  336. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  337. package/src/shade/renderer/Renderer.js +68 -61
  338. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSET_RESOURCES.d.ts +17 -0
  339. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSET_RESOURCES.d.ts.map +1 -0
  340. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSET_RESOURCES.js +19 -0
  341. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  342. package/src/shade/renderer/buffer/table/GPUDatabase.js +7 -4
  343. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts +32 -2
  344. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts.map +1 -1
  345. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.js +231 -62
  346. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +12 -0
  347. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  348. package/src/shade/renderer/buffer/table/GPUTypedTable.js +51 -14
  349. package/src/shade/renderer/camera/CAMERA_RESOURCE.d.ts +7 -0
  350. package/src/shade/renderer/camera/CAMERA_RESOURCE.d.ts.map +1 -0
  351. package/src/shade/renderer/camera/CAMERA_RESOURCE.js +8 -0
  352. package/src/shade/renderer/deferred/GBUFFER_RESOURCES.d.ts +22 -0
  353. package/src/shade/renderer/deferred/GBUFFER_RESOURCES.d.ts.map +1 -0
  354. package/src/shade/renderer/deferred/GBUFFER_RESOURCES.js +25 -0
  355. package/src/shade/renderer/deferred/LOCAL_LIGHT_SHADING.d.ts +12 -0
  356. package/src/shade/renderer/deferred/LOCAL_LIGHT_SHADING.d.ts.map +1 -0
  357. package/src/shade/renderer/deferred/LOCAL_LIGHT_SHADING.js +13 -0
  358. package/src/shade/renderer/deferred/LocalLightShading.d.ts +10 -0
  359. package/src/shade/renderer/deferred/LocalLightShading.d.ts.map +1 -0
  360. package/src/shade/renderer/deferred/LocalLightShading.js +12 -0
  361. package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.d.ts.map +1 -1
  362. package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.js +15 -11
  363. package/src/shade/renderer/deferred/TonemapDisplaySettings.d.ts +50 -0
  364. package/src/shade/renderer/deferred/TonemapDisplaySettings.d.ts.map +1 -0
  365. package/src/shade/renderer/deferred/TonemapDisplaySettings.js +142 -0
  366. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.d.ts.map +1 -1
  367. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.js +6 -1
  368. package/src/shade/renderer/deferred/chunk_sample_volumetrics.d.ts.map +1 -1
  369. package/src/shade/renderer/deferred/chunk_sample_volumetrics.js +11 -1
  370. package/src/shade/renderer/deferred/chunk_shade_directional_lights.d.ts +1 -2
  371. package/src/shade/renderer/deferred/chunk_shade_directional_lights.d.ts.map +1 -1
  372. package/src/shade/renderer/deferred/chunk_shade_directional_lights.js +4 -2
  373. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.d.ts +10 -3
  374. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.d.ts.map +1 -1
  375. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.js +23 -5
  376. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_deferred.d.ts +16 -0
  377. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_deferred.d.ts.map +1 -0
  378. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_deferred.js +23 -0
  379. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_heavy.d.ts +3 -2
  380. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_heavy.d.ts.map +1 -1
  381. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_heavy.js +17 -16
  382. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.d.ts +3 -2
  383. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.d.ts.map +1 -1
  384. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.js +9 -2
  385. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.d.ts.map +1 -1
  386. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.js +4 -1
  387. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.d.ts.map +1 -1
  388. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.js +4 -1
  389. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.d.ts.map +1 -1
  390. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.js +7 -0
  391. package/src/shade/renderer/deferred/shader_deferred_main.d.ts +11 -6
  392. package/src/shade/renderer/deferred/shader_deferred_main.d.ts.map +1 -1
  393. package/src/shade/renderer/deferred/shader_deferred_main.js +65 -86
  394. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts +1 -1
  395. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  396. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +14 -20
  397. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts +2 -2
  398. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts.map +1 -1
  399. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.js +13 -10
  400. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts +2 -2
  401. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts.map +1 -1
  402. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.js +13 -20
  403. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts +2 -2
  404. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts.map +1 -1
  405. package/src/shade/renderer/deferred/shader_tonemap_LDR.js +13 -11
  406. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts +2 -2
  407. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts.map +1 -1
  408. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.js +12 -9
  409. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts +2 -2
  410. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts.map +1 -1
  411. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.js +12 -9
  412. package/src/shade/renderer/fluid/FluidCascadePlacement.d.ts +142 -0
  413. package/src/shade/renderer/fluid/FluidCascadePlacement.d.ts.map +1 -0
  414. package/src/shade/renderer/fluid/FluidCascadePlacement.js +349 -0
  415. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +383 -0
  416. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -0
  417. package/src/shade/renderer/fluid/GPUFluidCascade.js +1217 -0
  418. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +191 -0
  419. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -0
  420. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +463 -0
  421. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_FILL_STRUCT.d.ts +27 -0
  422. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_FILL_STRUCT.d.ts.map +1 -0
  423. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_FILL_STRUCT.js +43 -0
  424. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_GHOSTS.d.ts +31 -0
  425. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_GHOSTS.d.ts.map +1 -0
  426. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_GHOSTS.js +38 -0
  427. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts +46 -0
  428. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts.map +1 -0
  429. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.js +61 -0
  430. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts +25 -0
  431. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts.map +1 -0
  432. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.js +41 -0
  433. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts +52 -0
  434. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts.map +1 -0
  435. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.js +146 -0
  436. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts +41 -0
  437. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -0
  438. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +238 -0
  439. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.d.ts +32 -0
  440. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.d.ts.map +1 -0
  441. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.js +141 -0
  442. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts +34 -0
  443. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -0
  444. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +101 -0
  445. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts +31 -0
  446. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts.map +1 -0
  447. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.js +126 -0
  448. package/src/shade/renderer/fluid/fluid_cascade_ruler.d.ts +15 -0
  449. package/src/shade/renderer/fluid/fluid_cascade_ruler.d.ts.map +1 -0
  450. package/src/shade/renderer/fluid/fluid_cascade_ruler.js +38 -0
  451. package/src/shade/renderer/fluid/fluid_cascade_window.d.ts +41 -0
  452. package/src/shade/renderer/fluid/fluid_cascade_window.d.ts.map +1 -0
  453. package/src/shade/renderer/fluid/fluid_cascade_window.js +49 -0
  454. package/src/shade/renderer/fluid/forcing/FLUID_DATABASE_SPEC.d.ts +68 -0
  455. package/src/shade/renderer/fluid/forcing/FLUID_DATABASE_SPEC.d.ts.map +1 -0
  456. package/src/shade/renderer/fluid/forcing/FLUID_DATABASE_SPEC.js +103 -0
  457. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts +71 -0
  458. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts.map +1 -0
  459. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.js +100 -0
  460. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts +21 -0
  461. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts.map +1 -0
  462. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.js +35 -0
  463. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_EXTRACT_STRUCT.d.ts +18 -0
  464. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_EXTRACT_STRUCT.d.ts.map +1 -0
  465. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_EXTRACT_STRUCT.js +27 -0
  466. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_QUERY_STRUCT.d.ts +17 -0
  467. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_QUERY_STRUCT.d.ts.map +1 -0
  468. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_QUERY_STRUCT.js +28 -0
  469. package/src/shade/renderer/fluid/forcing/FLUID_OBSTACLE_PLANE_STRUCT.d.ts +12 -0
  470. package/src/shade/renderer/fluid/forcing/FLUID_OBSTACLE_PLANE_STRUCT.d.ts.map +1 -0
  471. package/src/shade/renderer/fluid/forcing/FLUID_OBSTACLE_PLANE_STRUCT.js +16 -0
  472. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +289 -0
  473. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -0
  474. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +1487 -0
  475. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts +32 -0
  476. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts.map +1 -0
  477. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.js +87 -0
  478. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_leaf.d.ts +28 -0
  479. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_leaf.d.ts.map +1 -0
  480. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_leaf.js +99 -0
  481. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts +29 -0
  482. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts.map +1 -0
  483. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.js +67 -0
  484. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +38 -0
  485. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -0
  486. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +287 -0
  487. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_command.d.ts +18 -0
  488. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_command.d.ts.map +1 -0
  489. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_command.js +64 -0
  490. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_extract.d.ts +22 -0
  491. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_extract.d.ts.map +1 -0
  492. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_extract.js +168 -0
  493. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_query.d.ts +31 -0
  494. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_query.d.ts.map +1 -0
  495. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_query.js +208 -0
  496. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts +35 -0
  497. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts.map +1 -0
  498. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.js +50 -0
  499. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +162 -0
  500. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -0
  501. package/src/shade/renderer/fluid/mac/FluidMacPasses.js +384 -0
  502. package/src/shade/renderer/fluid/mac/FluidMacVelocitySet.d.ts +40 -0
  503. package/src/shade/renderer/fluid/mac/FluidMacVelocitySet.d.ts.map +1 -0
  504. package/src/shade/renderer/fluid/mac/FluidMacVelocitySet.js +77 -0
  505. package/src/shade/renderer/fluid/mac/V3_MAC_LATTICE_TAP_STRUCT.d.ts +14 -0
  506. package/src/shade/renderer/fluid/mac/V3_MAC_LATTICE_TAP_STRUCT.d.ts.map +1 -0
  507. package/src/shade/renderer/fluid/mac/V3_MAC_LATTICE_TAP_STRUCT.js +19 -0
  508. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts +35 -0
  509. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts.map +1 -0
  510. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.js +178 -0
  511. package/src/shade/renderer/fluid/mac/chunk_v3_mac_advect_maccormack.d.ts +17 -0
  512. package/src/shade/renderer/fluid/mac/chunk_v3_mac_advect_maccormack.d.ts.map +1 -0
  513. package/src/shade/renderer/fluid/mac/chunk_v3_mac_advect_maccormack.js +156 -0
  514. package/src/shade/renderer/fluid/mac/chunk_v3_mac_clip_trace.d.ts +31 -0
  515. package/src/shade/renderer/fluid/mac/chunk_v3_mac_clip_trace.d.ts.map +1 -0
  516. package/src/shade/renderer/fluid/mac/chunk_v3_mac_clip_trace.js +63 -0
  517. package/src/shade/renderer/fluid/mac/chunk_v3_mac_compute_divergence.d.ts +27 -0
  518. package/src/shade/renderer/fluid/mac/chunk_v3_mac_compute_divergence.d.ts.map +1 -0
  519. package/src/shade/renderer/fluid/mac/chunk_v3_mac_compute_divergence.js +42 -0
  520. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_carrier.d.ts +25 -0
  521. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_carrier.d.ts.map +1 -0
  522. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_carrier.js +67 -0
  523. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_pinned.d.ts +23 -0
  524. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_pinned.d.ts.map +1 -0
  525. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_pinned.js +38 -0
  526. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts +33 -0
  527. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts.map +1 -0
  528. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.js +231 -0
  529. package/src/shade/renderer/fluid/mac/chunk_v3_mac_subtract_pressure_gradient.d.ts +30 -0
  530. package/src/shade/renderer/fluid/mac/chunk_v3_mac_subtract_pressure_gradient.d.ts.map +1 -0
  531. package/src/shade/renderer/fluid/mac/chunk_v3_mac_subtract_pressure_gradient.js +66 -0
  532. package/src/shade/renderer/fluid/mac/chunk_v3_mac_vorticity_confinement.d.ts +27 -0
  533. package/src/shade/renderer/fluid/mac/chunk_v3_mac_vorticity_confinement.d.ts.map +1 -0
  534. package/src/shade/renderer/fluid/mac/chunk_v3_mac_vorticity_confinement.js +65 -0
  535. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +43 -0
  536. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -0
  537. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +245 -0
  538. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts +31 -0
  539. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts.map +1 -0
  540. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.js +109 -0
  541. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts +38 -0
  542. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts.map +1 -0
  543. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.js +222 -0
  544. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts +26 -0
  545. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts.map +1 -0
  546. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.js +92 -0
  547. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts +32 -0
  548. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts.map +1 -0
  549. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.js +181 -0
  550. package/src/shade/renderer/fluid/pressure/FLUID_MG.d.ts +112 -0
  551. package/src/shade/renderer/fluid/pressure/FLUID_MG.d.ts.map +1 -0
  552. package/src/shade/renderer/fluid/pressure/FLUID_MG.js +140 -0
  553. package/src/shade/renderer/fluid/pressure/FLUID_MG_PASS_STRUCT.d.ts +29 -0
  554. package/src/shade/renderer/fluid/pressure/FLUID_MG_PASS_STRUCT.d.ts.map +1 -0
  555. package/src/shade/renderer/fluid/pressure/FLUID_MG_PASS_STRUCT.js +45 -0
  556. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +156 -0
  557. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts.map +1 -0
  558. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.js +605 -0
  559. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_coarse_word.d.ts +18 -0
  560. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_coarse_word.d.ts.map +1 -0
  561. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_coarse_word.js +48 -0
  562. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_level0_word.d.ts +17 -0
  563. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_level0_word.d.ts.map +1 -0
  564. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_level0_word.js +47 -0
  565. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_prolong.d.ts +21 -0
  566. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_prolong.d.ts.map +1 -0
  567. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_prolong.js +47 -0
  568. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_relax.d.ts +27 -0
  569. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_relax.d.ts.map +1 -0
  570. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_relax.js +79 -0
  571. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_restrict.d.ts +18 -0
  572. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_restrict.d.ts.map +1 -0
  573. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_restrict.js +35 -0
  574. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_word.d.ts +17 -0
  575. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_word.d.ts.map +1 -0
  576. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_word.js +34 -0
  577. package/src/shade/renderer/fluid/pressure/chunk_fluid_pressure_ghost.d.ts +21 -0
  578. package/src/shade/renderer/fluid/pressure/chunk_fluid_pressure_ghost.d.ts.map +1 -0
  579. package/src/shade/renderer/fluid/pressure/chunk_fluid_pressure_ghost.js +34 -0
  580. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarse_weights.d.ts +10 -0
  581. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarse_weights.d.ts.map +1 -0
  582. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarse_weights.js +45 -0
  583. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.d.ts +17 -0
  584. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.d.ts.map +1 -0
  585. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.js +126 -0
  586. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_level0_weights.d.ts +10 -0
  587. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_level0_weights.d.ts.map +1 -0
  588. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_level0_weights.js +44 -0
  589. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts +18 -0
  590. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts.map +1 -0
  591. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js +149 -0
  592. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts +30 -0
  593. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts.map +1 -0
  594. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js +183 -0
  595. package/src/shade/renderer/fluid/publish/FLUID_WIND_PUBLISH_STRUCT.d.ts +9 -0
  596. package/src/shade/renderer/fluid/publish/FLUID_WIND_PUBLISH_STRUCT.d.ts.map +1 -0
  597. package/src/shade/renderer/fluid/publish/FLUID_WIND_PUBLISH_STRUCT.js +12 -0
  598. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts +49 -0
  599. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts.map +1 -0
  600. package/src/shade/renderer/fluid/publish/FluidWindPublish.js +136 -0
  601. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.d.ts +24 -0
  602. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.d.ts.map +1 -0
  603. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.js +37 -0
  604. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts +41 -0
  605. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -0
  606. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +122 -0
  607. package/src/shade/renderer/fluid/query/FLUID_QUERY_DATABASE_SPEC.d.ts +66 -0
  608. package/src/shade/renderer/fluid/query/FLUID_QUERY_DATABASE_SPEC.d.ts.map +1 -0
  609. package/src/shade/renderer/fluid/query/FLUID_QUERY_DATABASE_SPEC.js +88 -0
  610. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +157 -0
  611. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts.map +1 -0
  612. package/src/shade/renderer/fluid/query/GPUFluidQueries.js +709 -0
  613. package/src/shade/renderer/fluid/query/shader_fluid_query_gather.d.ts +47 -0
  614. package/src/shade/renderer/fluid/query/shader_fluid_query_gather.d.ts.map +1 -0
  615. package/src/shade/renderer/fluid/query/shader_fluid_query_gather.js +140 -0
  616. package/src/shade/renderer/geometry/GEOMETRY_ATTRIBUTE_DATA_RESOURCE.d.ts +7 -0
  617. package/src/shade/renderer/geometry/GEOMETRY_ATTRIBUTE_DATA_RESOURCE.d.ts.map +1 -0
  618. package/src/shade/renderer/geometry/GEOMETRY_ATTRIBUTE_DATA_RESOURCE.js +8 -0
  619. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +619 -606
  620. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts +3 -2
  621. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts.map +1 -1
  622. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.js +50 -44
  623. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts +12 -9
  624. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts.map +1 -1
  625. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.js +447 -363
  626. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts +7 -4
  627. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts.map +1 -1
  628. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.js +13 -6
  629. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts +21 -0
  630. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts.map +1 -0
  631. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.js +75 -0
  632. package/src/shade/renderer/geometry/meshlet/MESHLET_METADATA_RESOURCE.d.ts +7 -0
  633. package/src/shade/renderer/geometry/meshlet/MESHLET_METADATA_RESOURCE.d.ts.map +1 -0
  634. package/src/shade/renderer/geometry/meshlet/MESHLET_METADATA_RESOURCE.js +9 -0
  635. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +3 -3
  636. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  637. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +11 -9
  638. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts.map +1 -1
  639. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +7 -3
  640. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +1 -1
  641. package/src/shade/renderer/global_illumination/brick4/gpu/BRICK4_RESOURCE.d.ts +7 -0
  642. package/src/shade/renderer/global_illumination/brick4/gpu/BRICK4_RESOURCE.d.ts.map +1 -0
  643. package/src/shade/renderer/global_illumination/brick4/gpu/BRICK4_RESOURCE.js +8 -0
  644. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  645. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +2 -0
  646. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  647. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -2
  648. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_load_probe.d.ts.map +1 -1
  649. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_load_probe.js +4 -1
  650. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_by_position.d.ts.map +1 -1
  651. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_by_position.js +4 -1
  652. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_sample_probes.d.ts.map +1 -1
  653. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_sample_probes.js +3 -0
  654. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.d.ts.map +1 -1
  655. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.js +4 -1
  656. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.d.ts.map +1 -1
  657. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.js +3 -0
  658. package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.d.ts +15 -0
  659. package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.d.ts.map +1 -1
  660. package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.js +57 -57
  661. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  662. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +2 -0
  663. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.d.ts.map +1 -1
  664. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.js +3 -0
  665. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
  666. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +4 -2
  667. package/src/shade/renderer/global_illumination/probe/octahedral/LPV_SHADER_RESOURCE_GROUP.d.ts +39 -0
  668. package/src/shade/renderer/global_illumination/probe/octahedral/LPV_SHADER_RESOURCE_GROUP.d.ts.map +1 -1
  669. package/src/shade/renderer/global_illumination/probe/octahedral/LPV_SHADER_RESOURCE_GROUP.js +57 -4
  670. package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.js +3 -3
  671. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_radiance_sample_reflection.d.ts.map +1 -1
  672. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_radiance_sample_reflection.js +3 -0
  673. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_DEFINITION.d.ts +10 -0
  674. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_DEFINITION.d.ts.map +1 -0
  675. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_DEFINITION.js +25 -0
  676. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_LAYOUT.d.ts +55 -0
  677. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_LAYOUT.d.ts.map +1 -0
  678. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_LAYOUT.js +63 -0
  679. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +120 -4
  680. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.d.ts +23 -11
  681. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.d.ts.map +1 -1
  682. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.js +171 -102
  683. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_repair.d.ts +23 -0
  684. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_repair.d.ts.map +1 -0
  685. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_repair.js +80 -0
  686. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +5 -3
  687. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts.map +1 -1
  688. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +55 -5
  689. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_refit_lbvh.d.ts +55 -0
  690. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_refit_lbvh.d.ts.map +1 -0
  691. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_refit_lbvh.js +197 -0
  692. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts +3 -1
  693. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts.map +1 -1
  694. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js +45 -2
  695. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts +3 -2
  696. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  697. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +13 -3
  698. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts +6 -6
  699. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  700. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +11 -8
  701. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_prepare.d.ts +24 -0
  702. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_prepare.d.ts.map +1 -0
  703. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_prepare.js +99 -0
  704. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_repair.d.ts +17 -0
  705. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_repair.d.ts.map +1 -0
  706. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_repair.js +63 -0
  707. package/src/shade/renderer/gpu_primitive/chunk_collection_u32_append.d.ts +19 -0
  708. package/src/shade/renderer/gpu_primitive/chunk_collection_u32_append.d.ts.map +1 -0
  709. package/src/shade/renderer/gpu_primitive/chunk_collection_u32_append.js +44 -0
  710. package/src/shade/renderer/light/LIGHT_DATA_RESOURCE.d.ts +7 -0
  711. package/src/shade/renderer/light/LIGHT_DATA_RESOURCE.d.ts.map +1 -0
  712. package/src/shade/renderer/light/LIGHT_DATA_RESOURCE.js +8 -0
  713. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_LIST.d.ts +7 -0
  714. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_LIST.d.ts.map +1 -0
  715. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_LIST.js +16 -0
  716. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.d.ts +12 -0
  717. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.d.ts.map +1 -0
  718. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.js +33 -0
  719. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_ASSIGNMENT_SETTINGS.d.ts +7 -0
  720. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_ASSIGNMENT_SETTINGS.d.ts.map +1 -0
  721. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_ASSIGNMENT_SETTINGS.js +24 -0
  722. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.d.ts +8 -0
  723. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.d.ts.map +1 -0
  724. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.js +7 -0
  725. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_METADATA.d.ts.map +1 -1
  726. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_METADATA.js +2 -3
  727. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_RESOURCES.d.ts +17 -0
  728. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_RESOURCES.d.ts.map +1 -0
  729. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_RESOURCES.js +22 -0
  730. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +524 -0
  731. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +1101 -0
  732. package/src/shade/renderer/light/cluster/chunk_cluster_cell.d.ts +19 -0
  733. package/src/shade/renderer/light/cluster/chunk_cluster_cell.d.ts.map +1 -0
  734. package/src/shade/renderer/light/cluster/chunk_cluster_cell.js +133 -0
  735. package/src/shade/renderer/light/cluster/chunk_cluster_from_fragment_coord.d.ts.map +1 -1
  736. package/src/shade/renderer/light/cluster/chunk_cluster_from_fragment_coord.js +6 -1
  737. package/src/shade/renderer/light/cluster/chunk_cluster_light_proxy.d.ts +19 -0
  738. package/src/shade/renderer/light/cluster/chunk_cluster_light_proxy.d.ts.map +1 -0
  739. package/src/shade/renderer/light/cluster/chunk_cluster_light_proxy.js +95 -0
  740. package/src/shade/renderer/light/cluster/chunk_light_cluster_counts.d.ts +6 -4
  741. package/src/shade/renderer/light/cluster/chunk_light_cluster_counts.d.ts.map +1 -1
  742. package/src/shade/renderer/light/cluster/chunk_light_cluster_counts.js +10 -8
  743. package/src/shade/renderer/light/cluster/chunk_light_cluster_metadata_by_position.d.ts.map +1 -1
  744. package/src/shade/renderer/light/cluster/chunk_light_cluster_metadata_by_position.js +4 -1
  745. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts +8 -0
  746. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  747. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +1 -1
  748. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts +27 -2
  749. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  750. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +174 -76
  751. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts +3 -1
  752. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts.map +1 -1
  753. package/src/shade/renderer/light/cluster/graph_build_light_clusters.js +3 -0
  754. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts +14 -2
  755. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts.map +1 -1
  756. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.js +230 -139
  757. package/src/shade/renderer/light/cluster/shader_cluster_coarse_mark.d.ts +19 -0
  758. package/src/shade/renderer/light/cluster/shader_cluster_coarse_mark.d.ts.map +1 -0
  759. package/src/shade/renderer/light/cluster/shader_cluster_coarse_mark.js +134 -0
  760. package/src/shade/renderer/light/cluster/shader_cluster_light_compact.d.ts +11 -0
  761. package/src/shade/renderer/light/cluster/shader_cluster_light_compact.d.ts.map +1 -0
  762. package/src/shade/renderer/light/cluster/shader_cluster_light_compact.js +114 -0
  763. package/src/shade/renderer/light/cluster/shader_cluster_light_mark.d.ts +9 -0
  764. package/src/shade/renderer/light/cluster/shader_cluster_light_mark.d.ts.map +1 -0
  765. package/src/shade/renderer/light/cluster/shader_cluster_light_mark.js +59 -0
  766. package/src/shade/renderer/light/cluster/shader_cluster_light_prepare.d.ts +14 -0
  767. package/src/shade/renderer/light/cluster/shader_cluster_light_prepare.d.ts.map +1 -0
  768. package/src/shade/renderer/light/cluster/shader_cluster_light_prepare.js +142 -0
  769. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts +7 -0
  770. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts.map +1 -0
  771. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.js +7 -0
  772. package/src/shade/renderer/light/environment/ENVIRONMENT_SH_RESOURCE.d.ts +7 -0
  773. package/src/shade/renderer/light/environment/ENVIRONMENT_SH_RESOURCE.d.ts.map +1 -0
  774. package/src/shade/renderer/light/environment/ENVIRONMENT_SH_RESOURCE.js +8 -0
  775. package/src/shade/renderer/light/environment/sh_exponential/README.md +2 -1
  776. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  777. package/src/shade/renderer/lightmap/GPULightMap.js +2 -0
  778. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
  779. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +4 -2
  780. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
  781. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +4 -2
  782. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_density.d.ts.map +1 -1
  783. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_density.js +4 -0
  784. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_uv_checker.d.ts.map +1 -1
  785. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_uv_checker.js +4 -0
  786. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_flat.d.ts.map +1 -1
  787. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_flat.js +4 -0
  788. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_sh.d.ts.map +1 -1
  789. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_sh.js +4 -0
  790. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  791. package/src/shade/renderer/material/standard/SHADING_MATERIAL_RESOURCE_GROUP.d.ts +22 -0
  792. package/src/shade/renderer/material/standard/SHADING_MATERIAL_RESOURCE_GROUP.d.ts.map +1 -1
  793. package/src/shade/renderer/material/standard/SHADING_MATERIAL_RESOURCE_GROUP.js +33 -9
  794. package/src/shade/renderer/particles/DESIGN.md +16 -2
  795. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  796. package/src/shade/renderer/particles/GPUParticleSystem.js +3 -0
  797. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  798. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +21 -9
  799. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  800. package/src/shade/renderer/particles/graph/particle_node_parameters.js +1 -0
  801. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  802. package/src/shade/renderer/particles/graph/particle_node_presentation.js +8 -0
  803. package/src/shade/renderer/particles/graph_particles.d.ts +4 -1
  804. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  805. package/src/shade/renderer/particles/graph_particles.js +13 -0
  806. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +13 -0
  807. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  808. package/src/shade/renderer/particles/isa/InstructionStream.js +13 -0
  809. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +1 -0
  810. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  811. package/src/shade/renderer/particles/isa/ParticleVMISA.js +8 -0
  812. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +2 -1
  813. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  814. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +28 -6
  815. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +1 -1
  816. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  817. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +7 -0
  818. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +1 -1
  819. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  820. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +5 -2
  821. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -1
  822. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +5 -2
  823. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  824. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +5 -2
  825. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -1
  826. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +5 -2
  827. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +16 -1
  828. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  829. package/src/shade/renderer/particles/vm/ParticleVMReference.js +35 -2
  830. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  831. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +8 -0
  832. package/src/shade/renderer/particles/vm/chunk_particle_vm_wind_field.d.ts +20 -0
  833. package/src/shade/renderer/particles/vm/chunk_particle_vm_wind_field.d.ts.map +1 -0
  834. package/src/shade/renderer/particles/vm/chunk_particle_vm_wind_field.js +25 -0
  835. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts +4 -1
  836. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  837. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +8 -0
  838. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -1
  839. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +109 -106
  840. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -1
  841. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +71 -68
  842. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  843. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +3 -8
  844. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  845. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +4 -2
  846. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  847. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +6 -2
  848. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +4 -4
  849. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -3
  850. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  851. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +11 -8
  852. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  853. package/src/shade/renderer/postprocess/ssr/SSR.js +49 -52
  854. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts +28 -0
  855. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts.map +1 -0
  856. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.js +79 -0
  857. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts +30 -0
  858. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts.map +1 -0
  859. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.js +66 -0
  860. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts +11 -0
  861. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -0
  862. package/src/shade/renderer/postprocess/ssr/resolve/{build_ssr_resolve_shader.js → ssr_resolve_shader.js} +93 -85
  863. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.d.ts.map +1 -1
  864. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.js +4 -0
  865. package/src/shade/renderer/rasterize/expand/RasterizationCollectionType.d.ts +1 -0
  866. package/src/shade/renderer/rasterize/expand/RasterizationCollectionType.js +5 -0
  867. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts +25 -0
  868. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts.map +1 -0
  869. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.js +33 -0
  870. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_brick4.d.ts +10 -0
  871. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_brick4.d.ts.map +1 -0
  872. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_brick4.js +38 -0
  873. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_environment.d.ts +9 -0
  874. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_environment.d.ts.map +1 -0
  875. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_environment.js +30 -0
  876. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment.d.ts +10 -0
  877. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment.d.ts.map +1 -0
  878. package/src/shade/renderer/rasterize/forward/{chunk_forward_shade_standard_fragment_brick4.js → chunk_forward_shade_standard_fragment.js} +60 -33
  879. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +2 -3
  880. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  881. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +2 -3
  882. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +9 -4
  883. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -1
  884. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +11 -5
  885. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +4 -7
  886. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  887. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +19 -45
  888. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts +18 -0
  889. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts.map +1 -0
  890. package/src/shade/renderer/rasterize/native/avboit/{shader_avboit_draw_brick4.js → shader_avboit_draw.js} +23 -19
  891. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +3 -3
  892. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts +3 -3
  893. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  894. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +18 -47
  895. package/src/shade/renderer/rasterize/native/oit/oit_resolve_fragment_body.d.ts +12 -8
  896. package/src/shade/renderer/rasterize/native/oit/oit_resolve_fragment_body.d.ts.map +1 -1
  897. package/src/shade/renderer/rasterize/native/oit/oit_resolve_fragment_body.js +128 -123
  898. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +3 -3
  899. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts +11 -2
  900. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts.map +1 -1
  901. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +17 -10
  902. package/src/shade/renderer/restir/di/RESTIR_RADIANCE_RESOURCE.d.ts +7 -0
  903. package/src/shade/renderer/restir/di/RESTIR_RADIANCE_RESOURCE.d.ts.map +1 -0
  904. package/src/shade/renderer/restir/di/RESTIR_RADIANCE_RESOURCE.js +7 -0
  905. package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
  906. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  907. package/src/shade/renderer/scene/GPUSceneContext.js +21 -1
  908. package/src/shade/renderer/scene/MESH_INSTANCE_METADATA_STRUCT.d.ts.map +1 -1
  909. package/src/shade/renderer/scene/MESH_INSTANCE_METADATA_STRUCT.js +5 -0
  910. package/src/shade/renderer/scene/SCENE_DATABASE_RESOURCE.d.ts +7 -0
  911. package/src/shade/renderer/scene/SCENE_DATABASE_RESOURCE.d.ts.map +1 -0
  912. package/src/shade/renderer/scene/SCENE_DATABASE_RESOURCE.js +8 -0
  913. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +14 -0
  914. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  915. package/src/shade/renderer/scene/rows/GPUSceneRows.js +114 -10
  916. package/src/shade/renderer/shader/ComputeShader.d.ts +21 -0
  917. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  918. package/src/shade/renderer/shader/ComputeShader.js +54 -0
  919. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +10 -4
  920. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  921. package/src/shade/renderer/shader/ShaderDescriptor.js +78 -0
  922. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +394 -0
  923. package/src/shade/renderer/shader/chunk/brdf/chunk_BRDF_GGX.d.ts +4 -1
  924. package/src/shade/renderer/shader/chunk/brdf/chunk_BRDF_GGX.d.ts.map +1 -1
  925. package/src/shade/renderer/shader/chunk/brdf/chunk_BRDF_GGX.js +7 -4
  926. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.d.ts +4 -1
  927. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.d.ts.map +1 -1
  928. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.js +9 -9
  929. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts +10 -1
  930. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts.map +1 -1
  931. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js +16 -5
  932. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts +82 -0
  933. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -0
  934. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +286 -0
  935. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_frontier.d.ts +47 -0
  936. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_frontier.d.ts.map +1 -0
  937. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_frontier.js +121 -0
  938. package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.d.ts +22 -0
  939. package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.d.ts.map +1 -0
  940. package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js +38 -0
  941. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_contains.d.ts +11 -0
  942. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_contains.d.ts.map +1 -0
  943. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_contains.js +20 -0
  944. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.d.ts +19 -0
  945. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.d.ts.map +1 -0
  946. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.js +71 -0
  947. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_storage_coord.d.ts +15 -0
  948. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_storage_coord.d.ts.map +1 -0
  949. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_storage_coord.js +25 -0
  950. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_P3.d.ts +17 -0
  951. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_P3.d.ts.map +1 -0
  952. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_P3.js +26 -0
  953. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts +8 -4
  954. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts.map +1 -1
  955. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.js +13 -19
  956. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_intersects_aabb3.d.ts +14 -0
  957. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_intersects_aabb3.d.ts.map +1 -0
  958. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_intersects_aabb3.js +24 -0
  959. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_signed_distance_to_point.d.ts +3 -0
  960. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_signed_distance_to_point.d.ts.map +1 -1
  961. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_signed_distance_to_point.js +9 -10
  962. package/src/shade/renderer/shader/chunk/geometry/chunk_point_closest_on_line.d.ts +11 -0
  963. package/src/shade/renderer/shader/chunk/geometry/chunk_point_closest_on_line.d.ts.map +1 -0
  964. package/src/shade/renderer/shader/chunk/geometry/chunk_point_closest_on_line.js +28 -0
  965. package/src/shade/renderer/shader/chunk/geometry/chunk_point_distance_to_line.d.ts +3 -2
  966. package/src/shade/renderer/shader/chunk/geometry/chunk_point_distance_to_line.d.ts.map +1 -1
  967. package/src/shade/renderer/shader/chunk/geometry/chunk_point_distance_to_line.js +8 -17
  968. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_u32.d.ts.map +1 -1
  969. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_u32.js +3 -0
  970. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec2f.d.ts.map +1 -1
  971. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec2f.js +4 -1
  972. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec3f.d.ts.map +1 -1
  973. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec3f.js +4 -1
  974. package/src/shade/renderer/shader/chunk/geometry/plane/chunk_point_distance_above_plane.d.ts +8 -0
  975. package/src/shade/renderer/shader/chunk/geometry/plane/chunk_point_distance_above_plane.d.ts.map +1 -1
  976. package/src/shade/renderer/shader/chunk/geometry/plane/chunk_point_distance_above_plane.js +8 -0
  977. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_angle_stable.d.ts +14 -0
  978. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_angle_stable.d.ts.map +1 -0
  979. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_angle_stable.js +21 -0
  980. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_clamp_to_cone.d.ts +21 -0
  981. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_clamp_to_cone.d.ts.map +1 -0
  982. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_clamp_to_cone.js +49 -0
  983. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_slerp.d.ts +29 -0
  984. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_slerp.d.ts.map +1 -0
  985. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_slerp.js +86 -0
  986. package/src/shade/renderer/shader/chunk/grid/GRID_TILE_WINDOW_STRUCT.d.ts +24 -0
  987. package/src/shade/renderer/shader/chunk/grid/GRID_TILE_WINDOW_STRUCT.d.ts.map +1 -0
  988. package/src/shade/renderer/shader/chunk/grid/GRID_TILE_WINDOW_STRUCT.js +30 -0
  989. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_f32.d.ts +55 -0
  990. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_f32.d.ts.map +1 -0
  991. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_f32.js +101 -0
  992. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_vec4.d.ts +24 -0
  993. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_vec4.d.ts.map +1 -0
  994. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_vec4.js +70 -0
  995. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_window.d.ts +42 -0
  996. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_window.d.ts.map +1 -0
  997. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_window.js +88 -0
  998. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_get_vertices.d.ts.map +1 -1
  999. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_get_vertices.js +4 -1
  1000. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_lookup_nearest_cell.d.ts.map +1 -1
  1001. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_lookup_nearest_cell.js +4 -1
  1002. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_data.d.ts.map +1 -1
  1003. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_data.js +4 -1
  1004. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_position.d.ts.map +1 -1
  1005. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_position.js +4 -1
  1006. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_radiance.d.ts.map +1 -1
  1007. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_radiance.js +4 -1
  1008. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.d.ts.map +1 -1
  1009. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.js +6 -1
  1010. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_sample_depth_atlas.d.ts.map +1 -1
  1011. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_sample_depth_atlas.js +13 -1
  1012. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +67 -16
  1013. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.d.ts.map +1 -1
  1014. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.js +6 -1
  1015. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts +7 -1
  1016. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts.map +1 -1
  1017. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.js +29 -1
  1018. package/src/shade/renderer/shader/chunk/math/chunk_falloff_quadratic.d.ts +11 -0
  1019. package/src/shade/renderer/shader/chunk/math/chunk_falloff_quadratic.d.ts.map +1 -0
  1020. package/src/shade/renderer/shader/chunk/math/chunk_falloff_quadratic.js +20 -0
  1021. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts.map +1 -1
  1022. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.js +4 -1
  1023. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts.map +1 -1
  1024. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.js +3 -0
  1025. package/src/shade/renderer/shader/chunk/physics/fluid/chunk_vortex_swirl.d.ts +20 -0
  1026. package/src/shade/renderer/shader/chunk/physics/fluid/chunk_vortex_swirl.d.ts.map +1 -0
  1027. package/src/shade/renderer/shader/chunk/physics/fluid/chunk_vortex_swirl.js +39 -0
  1028. package/src/shade/renderer/shader/chunk/physics/kinematics/chunk_rigid_velocity_at_point.d.ts +12 -0
  1029. package/src/shade/renderer/shader/chunk/physics/kinematics/chunk_rigid_velocity_at_point.d.ts.map +1 -0
  1030. package/src/shade/renderer/shader/chunk/physics/kinematics/chunk_rigid_velocity_at_point.js +21 -0
  1031. package/src/shade/renderer/shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.d.ts +17 -0
  1032. package/src/shade/renderer/shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.d.ts.map +1 -0
  1033. package/src/shade/renderer/shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.js +19 -0
  1034. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_depth.d.ts.map +1 -1
  1035. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_depth.js +5 -1
  1036. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_world_space_normal.d.ts.map +1 -1
  1037. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_world_space_normal.js +4 -1
  1038. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_screen_space_to_view_space.d.ts.map +1 -1
  1039. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_screen_space_to_view_space.js +4 -1
  1040. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_validate_hit.d.ts.map +1 -1
  1041. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_validate_hit.js +3 -0
  1042. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.d.ts.map +1 -1
  1043. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.js +3 -5
  1044. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_box.d.ts +16 -0
  1045. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_box.d.ts.map +1 -0
  1046. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_box.js +28 -0
  1047. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_capsule.d.ts +18 -0
  1048. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_capsule.d.ts.map +1 -0
  1049. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_capsule.js +30 -0
  1050. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_cylinder.d.ts +18 -0
  1051. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_cylinder.d.ts.map +1 -0
  1052. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_cylinder.js +28 -0
  1053. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_sphere.d.ts +13 -0
  1054. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_sphere.d.ts.map +1 -0
  1055. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_sphere.js +20 -0
  1056. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_texture_region_sample_linear_uv.d.ts +7 -0
  1057. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_texture_region_sample_linear_uv.d.ts.map +1 -1
  1058. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_texture_region_sample_linear_uv.js +16 -41
  1059. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_kind.d.ts +10 -0
  1060. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_kind.d.ts.map +1 -0
  1061. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_kind.js +24 -0
  1062. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_local_bounds.d.ts +20 -0
  1063. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_local_bounds.d.ts.map +1 -0
  1064. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_local_bounds.js +54 -0
  1065. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_signed_distance.d.ts +23 -0
  1066. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_signed_distance.d.ts.map +1 -0
  1067. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_signed_distance.js +82 -0
  1068. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.d.ts +4 -3
  1069. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.d.ts.map +1 -1
  1070. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.js +4 -3
  1071. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_append_slot.d.ts +31 -0
  1072. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_append_slot.d.ts.map +1 -0
  1073. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_append_slot.js +60 -0
  1074. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_atomic_add.d.ts +15 -0
  1075. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_atomic_add.d.ts.map +1 -0
  1076. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_atomic_add.js +29 -0
  1077. package/src/shade/renderer/shader/chunk/texture/TEXTURE3D_TRILINEAR_CORNERS_STRUCT.d.ts +15 -0
  1078. package/src/shade/renderer/shader/chunk/texture/TEXTURE3D_TRILINEAR_CORNERS_STRUCT.d.ts.map +1 -0
  1079. package/src/shade/renderer/shader/chunk/texture/TEXTURE3D_TRILINEAR_CORNERS_STRUCT.js +20 -0
  1080. package/src/shade/renderer/shader/chunk/texture/chunk_texel_coordinate_to_uv3.d.ts +11 -0
  1081. package/src/shade/renderer/shader/chunk/texture/chunk_texel_coordinate_to_uv3.d.ts.map +1 -0
  1082. package/src/shade/renderer/shader/chunk/texture/chunk_texel_coordinate_to_uv3.js +18 -0
  1083. package/src/shade/renderer/shader/chunk/texture/chunk_uv3_to_texel_coordinate.d.ts +11 -0
  1084. package/src/shade/renderer/shader/chunk/texture/chunk_uv3_to_texel_coordinate.d.ts.map +1 -0
  1085. package/src/shade/renderer/shader/chunk/texture/chunk_uv3_to_texel_coordinate.js +18 -0
  1086. package/src/shade/renderer/shader/chunk/texture/sample/chunk_texture3d_trilinear_corners.d.ts +35 -0
  1087. package/src/shade/renderer/shader/chunk/texture/sample/chunk_texture3d_trilinear_corners.d.ts.map +1 -0
  1088. package/src/shade/renderer/shader/chunk/texture/sample/chunk_texture3d_trilinear_corners.js +159 -0
  1089. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +35 -2
  1090. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  1091. package/src/shade/renderer/shader/compiler/CodeChunk.js +65 -2
  1092. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts +2 -0
  1093. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts.map +1 -1
  1094. package/src/shade/renderer/shader/compiler/CodeChunkChoice.js +10 -0
  1095. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +272 -20
  1096. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts +1 -1
  1097. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts +1 -1
  1098. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts.map +1 -1
  1099. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.js +26 -2
  1100. package/src/shade/renderer/shader/graph/graph_prepare_bindings.d.ts.map +1 -1
  1101. package/src/shade/renderer/shader/graph/graph_prepare_bindings.js +69 -0
  1102. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts +94 -2
  1103. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts.map +1 -1
  1104. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.js +333 -2
  1105. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts +14 -1
  1106. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts.map +1 -1
  1107. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.js +28 -150
  1108. package/src/shade/renderer/shader/resource/encoder_prepare_shader_bindings_defaults.d.ts +5 -0
  1109. package/src/shade/renderer/shader/resource/encoder_prepare_shader_bindings_defaults.d.ts.map +1 -1
  1110. package/src/shade/renderer/shader/resource/encoder_prepare_shader_bindings_defaults.js +11 -1
  1111. package/src/shade/renderer/shadow/map/SHADOWMAP_RESOURCES.d.ts +12 -0
  1112. package/src/shade/renderer/shadow/map/SHADOWMAP_RESOURCES.d.ts.map +1 -0
  1113. package/src/shade/renderer/shadow/map/SHADOWMAP_RESOURCES.js +14 -0
  1114. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.d.ts.map +1 -1
  1115. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.js +3 -0
  1116. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_filtered.d.ts.map +1 -1
  1117. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_filtered.js +8 -1
  1118. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
  1119. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +3 -0
  1120. package/src/shade/renderer/shadow/ray/shader_screens_space_shadows.d.ts.map +1 -1
  1121. package/src/shade/renderer/shadow/ray/shader_screens_space_shadows.js +3 -0
  1122. package/src/shade/renderer/shadow/sdf/chunk_geometry_sdf_query_distance.d.ts.map +1 -1
  1123. package/src/shade/renderer/shadow/sdf/chunk_geometry_sdf_query_distance.js +3 -3
  1124. package/src/shade/renderer/shadow/sdf/chunk_sdf_geometry_raymarch.d.ts.map +1 -1
  1125. package/src/shade/renderer/shadow/sdf/chunk_sdf_geometry_raymarch.js +3 -3
  1126. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +5 -3
  1127. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -1
  1128. package/src/shade/renderer/shadow/vsm/VSMPageManager.js +86 -89
  1129. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts.map +1 -1
  1130. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.js +12 -9
  1131. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts +2 -2
  1132. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts.map +1 -1
  1133. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.js +13 -26
  1134. package/src/shade/renderer/texture/SAMPLER_LINEAR_RESOURCE.d.ts +7 -0
  1135. package/src/shade/renderer/texture/SAMPLER_LINEAR_RESOURCE.d.ts.map +1 -0
  1136. package/src/shade/renderer/texture/SAMPLER_LINEAR_RESOURCE.js +8 -0
  1137. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +66 -47
  1138. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -1
  1139. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +193 -117
  1140. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +20 -0
  1141. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -0
  1142. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +30 -0
  1143. package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts +2 -0
  1144. package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts.map +1 -1
  1145. package/src/shade/renderer/texture/draw_texture_as_rgba.js +2 -0
  1146. package/src/shade/renderer/texture/graph_draw_texture_3d_slice_as_rgba.d.ts +31 -0
  1147. package/src/shade/renderer/texture/graph_draw_texture_3d_slice_as_rgba.d.ts.map +1 -0
  1148. package/src/shade/renderer/texture/graph_draw_texture_3d_slice_as_rgba.js +116 -0
  1149. package/src/shade/renderer/texture/shader_draw_texture_3d_slice_as_rgba.d.ts +33 -0
  1150. package/src/shade/renderer/texture/shader_draw_texture_3d_slice_as_rgba.d.ts.map +1 -0
  1151. package/src/shade/renderer/texture/shader_draw_texture_3d_slice_as_rgba.js +90 -0
  1152. package/src/shade/renderer/texture/util/ZERO_UINT_PIXEL_TEXTURE.d.ts +10 -0
  1153. package/src/shade/renderer/texture/util/ZERO_UINT_PIXEL_TEXTURE.d.ts.map +1 -0
  1154. package/src/shade/renderer/texture/util/ZERO_UINT_PIXEL_TEXTURE.js +33 -0
  1155. package/src/shade/renderer/view/VIEW_RESOURCE.d.ts +7 -0
  1156. package/src/shade/renderer/view/VIEW_RESOURCE.d.ts.map +1 -0
  1157. package/src/shade/renderer/view/VIEW_RESOURCE.js +8 -0
  1158. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +7 -4
  1159. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
  1160. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +192 -13
  1161. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +8 -5
  1162. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  1163. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +9 -5
  1164. package/src/shade/renderer/volumetrics/NOTES.md +47 -0
  1165. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.d.ts.map +1 -1
  1166. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.js +12 -0
  1167. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +31 -5
  1168. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  1169. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +53 -12
  1170. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +27 -11
  1171. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  1172. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +30 -11
  1173. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOURCES.d.ts +17 -0
  1174. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOURCES.d.ts.map +1 -0
  1175. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOURCES.js +20 -0
  1176. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +13 -3
  1177. package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.d.ts.map +1 -1
  1178. package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.js +82 -76
  1179. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts +4 -3
  1180. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts.map +1 -1
  1181. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.js +4 -3
  1182. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts.map +1 -1
  1183. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.js +3 -0
  1184. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts.map +1 -1
  1185. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.js +3 -0
  1186. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts +7 -0
  1187. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts.map +1 -1
  1188. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js +152 -130
  1189. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +1 -1
  1190. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +5 -0
  1191. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +7 -9
  1192. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +1 -1
  1193. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +11 -9
  1194. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts +35 -0
  1195. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +1 -0
  1196. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.js +105 -0
  1197. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +15 -9
  1198. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +1 -1
  1199. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +26 -36
  1200. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts +10 -0
  1201. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts.map +1 -0
  1202. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.js +51 -0
  1203. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +11 -0
  1204. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +1 -1
  1205. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +19 -6
  1206. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +9 -5
  1207. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -1
  1208. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +11 -5
  1209. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  1210. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +25 -12
  1211. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts +35 -0
  1212. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts.map +1 -1
  1213. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.js +37 -0
  1214. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts +2 -1
  1215. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts.map +1 -1
  1216. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.js +8 -3
  1217. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts +45 -13
  1218. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts.map +1 -1
  1219. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.js +50 -69
  1220. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_carried.d.ts +14 -0
  1221. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_carried.d.ts.map +1 -0
  1222. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_carried.js +76 -0
  1223. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_scrolled.d.ts +14 -0
  1224. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_scrolled.d.ts.map +1 -0
  1225. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_scrolled.js +38 -0
  1226. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_tap.d.ts +21 -0
  1227. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_tap.d.ts.map +1 -0
  1228. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_tap.js +74 -0
  1229. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +6 -0
  1230. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -1
  1231. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +11 -2
  1232. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +7 -0
  1233. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  1234. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +14 -4
  1235. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  1236. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +17 -3
  1237. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.d.ts.map +1 -1
  1238. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.js +5 -0
  1239. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +1 -2
  1240. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  1241. package/src/shade/renderer/water/GPUWaterRenderer.js +15 -24
  1242. package/src/shade/renderer/water/chunk_water_gi.d.ts +10 -2
  1243. package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
  1244. package/src/shade/renderer/water/chunk_water_gi.js +70 -56
  1245. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts +2 -2
  1246. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts.map +1 -1
  1247. package/src/shade/renderer/water/optics/chunk_water_inscatter.js +5 -2
  1248. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +1 -2
  1249. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  1250. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +4 -2
  1251. package/src/shade/renderer/water/shader_water.d.ts +9 -12
  1252. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  1253. package/src/shade/renderer/water/shader_water.js +69 -47
  1254. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts +4 -1
  1255. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  1256. package/src/shade/renderer/water/surface/GPUWaterSurface.js +9 -3
  1257. package/src/shade/renderer/water/surface/WATER_SURFACE_RESOURCES.d.ts +15 -0
  1258. package/src/shade/renderer/water/surface/WATER_SURFACE_RESOURCES.d.ts.map +1 -0
  1259. package/src/shade/renderer/water/surface/WATER_SURFACE_RESOURCES.js +27 -0
  1260. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +2 -1
  1261. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -1
  1262. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +18 -9
  1263. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +0 -3
  1264. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -1
  1265. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +15 -3
  1266. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +2 -2
  1267. package/src/shade/renderer/water/surface/shader_water_cull.d.ts +9 -3
  1268. package/src/shade/renderer/water/surface/shader_water_cull.d.ts.map +1 -1
  1269. package/src/shade/renderer/water/surface/shader_water_cull.js +46 -22
  1270. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts +26 -1
  1271. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts.map +1 -1
  1272. package/src/shade/renderer/water/surface/shader_water_waves_derive.js +73 -9
  1273. package/src/shade/renderer/wind/GPUSceneWind.d.ts +127 -0
  1274. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -0
  1275. package/src/shade/renderer/wind/GPUSceneWind.js +410 -0
  1276. package/src/shade/renderer/wind/WIND_FIELD.d.ts +53 -0
  1277. package/src/shade/renderer/wind/WIND_FIELD.d.ts.map +1 -0
  1278. package/src/shade/renderer/wind/WIND_FIELD.js +60 -0
  1279. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts +36 -0
  1280. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts.map +1 -0
  1281. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.js +61 -0
  1282. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +17 -0
  1283. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -0
  1284. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +17 -0
  1285. package/src/shade/renderer/wind/chunk_wind_field_sample.d.ts +20 -0
  1286. package/src/shade/renderer/wind/chunk_wind_field_sample.d.ts.map +1 -0
  1287. package/src/shade/renderer/wind/chunk_wind_field_sample.js +26 -0
  1288. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +40 -0
  1289. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -0
  1290. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +92 -0
  1291. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +12 -0
  1292. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -0
  1293. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +22 -0
  1294. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +15 -0
  1295. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -0
  1296. package/src/shade/renderer/wind/wind_field_add_resources.js +22 -0
  1297. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +5 -2
  1298. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
  1299. package/src/shade/wgsl/emulator/CPUBitmapData.js +5 -2
  1300. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +5 -1
  1301. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  1302. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +75 -22
  1303. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  1304. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +90 -22
  1305. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +0 -87
  1306. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +0 -1
  1307. package/src/engine/physics/cloth/wind/ClothAmbientWind.js +0 -185
  1308. package/src/shade/renderer/geometry/sdf/chunk_sdf_slot_index_to_texture_offset.d.ts +0 -7
  1309. package/src/shade/renderer/geometry/sdf/chunk_sdf_slot_index_to_texture_offset.d.ts.map +0 -1
  1310. package/src/shade/renderer/geometry/sdf/chunk_sdf_slot_index_to_texture_offset.js +0 -25
  1311. package/src/shade/renderer/global_illumination/clipmap/GPUClipMap3D.d.ts +0 -43
  1312. package/src/shade/renderer/global_illumination/clipmap/GPUClipMap3D.d.ts.map +0 -1
  1313. package/src/shade/renderer/global_illumination/clipmap/GPUClipMap3D.js +0 -207
  1314. package/src/shade/renderer/global_illumination/clipmap/RadianceField.d.ts +0 -21
  1315. package/src/shade/renderer/global_illumination/clipmap/RadianceField.d.ts.map +0 -1
  1316. package/src/shade/renderer/global_illumination/clipmap/RadianceField.js +0 -40
  1317. package/src/shade/renderer/global_illumination/clipmap/chunk_clip_cascade_wrap_coord.d.ts +0 -13
  1318. package/src/shade/renderer/global_illumination/clipmap/chunk_clip_cascade_wrap_coord.d.ts.map +0 -1
  1319. package/src/shade/renderer/global_illumination/clipmap/chunk_clip_cascade_wrap_coord.js +0 -47
  1320. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts +0 -7
  1321. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts.map +0 -1
  1322. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.js +0 -115
  1323. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.d.ts +0 -7
  1324. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.d.ts.map +0 -1
  1325. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.js +0 -6
  1326. package/src/shade/renderer/light/cluster/chunk_cluster_keep_smallest.d.ts +0 -21
  1327. package/src/shade/renderer/light/cluster/chunk_cluster_keep_smallest.d.ts.map +0 -1
  1328. package/src/shade/renderer/light/cluster/chunk_cluster_keep_smallest.js +0 -47
  1329. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts +0 -21
  1330. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +0 -1
  1331. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts +0 -2
  1332. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts.map +0 -1
  1333. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.js +0 -24
  1334. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts +0 -2
  1335. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +0 -1
  1336. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +0 -21
  1337. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts +0 -2
  1338. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +0 -1
  1339. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +0 -34
  1340. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts +0 -3
  1341. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +0 -1
  1342. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts +0 -7
  1343. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +0 -1
  1344. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +0 -184
  1345. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts +0 -9
  1346. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +0 -1
  1347. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts +0 -9
  1348. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +0 -1
  1349. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +0 -111
  1350. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.d.ts +0 -9
  1351. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.d.ts.map +0 -1
  1352. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +0 -111
  1353. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Hauber.d.ts +0 -9
  1354. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Hauber.d.ts.map +0 -1
  1355. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Hauber.js +0 -22
  1356. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts +0 -10
  1357. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts.map +0 -1
  1358. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.js +0 -55
  1359. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts +0 -10
  1360. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts.map +0 -1
  1361. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.js +0 -47
  1362. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts +0 -10
  1363. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts.map +0 -1
  1364. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.js +0 -63
@@ -0,0 +1,1101 @@
1
+ # Cluster light assignment: the decided design and implementation plan (2026-10-16)
2
+
3
+ Status: **landed on master, 2026-10-16** (Part IV: the commits, what changed from the plan, and the
4
+ post-landing measurements). Alex closed every fork on 2026-10-16. Part I is the design as decided, Part II
5
+ the measurements behind it, Part III the implementation plan. Appendix A keeps the round-2 and round-3 record (`R3`, §0–§7). Where the record
6
+ conflicts with Parts I–III, Parts I–III win.
7
+
8
+ **Fixed constraints:**
9
+
10
+ - The grid stays 32 px × 24 slices.
11
+ - The input is the cull's atomic-appended `(id, type)` list, exactly as today. Nothing moves into
12
+ `graph_cull_lights`.
13
+ - The last slice is unbounded: [`depth_from_slice(23)`, ∞). That is intentional, and the tests handle the
14
+ unbounded cell in XY only.
15
+ - Every cell is served, empty space included. No stage reads depth or the HZB.
16
+ - Consumers keep today's product: `LIGHT_CLUSTER_METADATA {counts, offset}` + `cluster_data`, points then
17
+ spots.
18
+
19
+ ## Part I — The design
20
+
21
+ ### I.1 Decisions
22
+
23
+ | fork | decision (Alex) | in the design |
24
+ |---|---|---|
25
+ | F1 | count-then-write, no per-cell cap, counts 16 bits per type | the fine pass counts every hit, makes one exact allocation, writes all hits |
26
+ | F2 | yes | the light-scatter coarse mask runs at every light count. 1,024 survives only as a loop budget (I.3) |
27
+ | F3 | yes | the id-sorting prepass stays |
28
+ | F4 | G | the coarse unit is the 4×4×4 block, which is one fine workgroup |
29
+ | F5 | "per consumer, they decide on their own" | each consumer loop owns a budget constant and a doc line; the product imposes no limit (I.5) |
30
+ | F6 | "size off the coarse cull … one frame incorrectness is totally acceptable on overflow" | `cluster_data` is sized through `GPUCollectionLimits` from the prepass's tight bound; an overflowing frame truncates (I.4) |
31
+ | F7 | "don't bother" | 4×4×4 workgroup, subgroup-scan compaction as in A2/G. The order inside a cell is deterministic, not ascending (I.6) |
32
+
33
+ ### I.2 The passes
34
+
35
+ Six direct dispatches in one compute pass. No indirect dispatch and no readback on the frame's path.
36
+
37
+ | # | pass | threads | does |
38
+ |---|---|---|---|
39
+ | 1 | **mark** | one per culled entry; dispatch over the CPU-known clusterable count | ORs `(type, id)` into a per-type visibility bitmask sized by the light tables' extents |
40
+ | 2 | **compact** | one workgroup of 256 | ordered compaction of the bitmask into the light list sorted by (type, id). The bitmask is a FrameGraph transient the graph clears; compact reads it through a plain read-only view. Rounds of 256 threads × 64 bits = 16,384 table slots, with a workgroup-memory scan in thread order, so the order holds by construction, not by the subgroup lane mapping. The ids are table slots, so the rounds follow the tables' extents; the set bits never exceed the cull list's limit (16,383) |
41
+ | 3 | **prepare** | one per sorted light | one database read; writes the view-space proxy (sphere, spot apex/height/direction/cos, source radius) and the packed cell box (tile x/y from the sphere's exact tangent extents, slices from `cluster_depth_to_z_slice`); sums the **tight sizing bound** Σ cell-box volume (workgroup-memory sum, one global atomic per workgroup) |
42
+ | 4 | **coarse clear** | blocks × ⌈L/32⌉ words, from the device count | zeroes the per-block light masks |
43
+ | 5 | **coarse scatter** | one workgroup per sorted light | ORs the light's bit into every 4×4×4 block its cell box touches |
44
+ | 6 | **fine** | one 4×4×4 workgroup per block, one thread per cell | per 64-light chunk: skip if the block's two mask words are 0; else compact the survivors (subgroup exclusive add + per-subgroup offsets) into workgroup memory; each cell runs box + precise test (6-plane sphere; spot cone vs the cell's bounding sphere, unbounded last slice by the cone's own bounding sphere in XY). **Sweep 1** counts per type (uncapped), **one subgroup-aggregated allocation**, **sweep 2** writes, then metadata `{point \| spot << 16, offset}` |
45
+
46
+ **O() and zero-light cost:**
47
+
48
+ | pass | cost is O() in | at zero lights |
49
+ |---|---|---|
50
+ | mark, prepare | L | early exit |
51
+ | compact | table extent / 32 words, in rounds of 512 | one workgroup, one round per 16,384 slots |
52
+ | coarse clear | blocks × ⌈L/32⌉ | nothing |
53
+ | coarse scatter | Σ over lights of blocks covered | nothing |
54
+ | fine | cells × block survivors + hits (two sweeps); + O(cells) metadata write | O(cells) metadata write: the floor |
55
+
56
+ **Measured zero-light totals:** 7–8 µs on the 4090, 6–81 µs on the iGPU (II.1).
57
+
58
+ ### I.3 Per-thread loop budgets
59
+
60
+ | loop | budget | what is past it |
61
+ |---|---|---|
62
+ | compact | 64 bits per thread per round; one round per 16,384 table slots | nothing |
63
+ | scatter | coarse blocks / 64 per thread (≤ 48 at 4K) | nothing |
64
+ | fine, chunks | ⌈L/64⌉ (≤ 256 at the cull limit); an empty pair of words costs two loads | nothing |
65
+ | fine, survivors per chunk | ≤ 64 | nothing |
66
+ | the 1,024 figure (F2) | survives only as a loop budget: ≤ 1,024 lights is ≤ 16 fine chunks of 64 (32 lanes × 32 bits) | there is no speed switch at 1,024; the mask path always runs |
67
+
68
+ ### I.4 Sizing and overflow (F6)
69
+
70
+ 1. **The bound.** `prepare` accumulates **Σ over sorted lights of its cell box's cells**. This is the box
71
+ test's candidate count, which is an upper bound on hits, since the fine pass only rejects. Measured
72
+ tightness is in II.2.
73
+ - It costs nothing measurable when summed in `prepare` with a workgroup-memory sum and one global
74
+ atomic per workgroup (II.2). That is the design.
75
+ - Putting it in the scatter instead costs the iGPU 15–48 µs: two contended atomics per light.
76
+ 2. **The column.** The bound word is recorded with `graph_record_stat` into a new `GPUCollectionLimits`
77
+ column, `RasterizationCollectionType.LightClusterEntries` (element size 4 B). `cluster_data` is
78
+ allocated at `compute_buffer_size(LightClusterEntries) + 4` bytes (the leading offset word).
79
+ - Priming: `prime(LightClusterEntries, …)` from today's `estimate_cluster_data_limit` (64.5 words per
80
+ cell) on the first frame of a resolution, so nothing regresses before the first readback.
81
+ 3. **Overflow.** The fine pass's allocation atomic keeps counting past capacity. Each subgroup gets
82
+ `min(its count, what is left)` (points first), and later subgroups get 0.
83
+ - **That frame's truncated cells are non-deterministic.** Measured: with the pool at half the demand,
84
+ 71–149 cells differed between runs.
85
+ - The next frames grow the column. The limits' own runaway clamp staggers a large jump over up to about
86
+ 3 frames (its comment, `GPUCollectionLimits.#clamp_stats_against_runaway`; not measured here).
87
+ - `cluster_data` is a FrameGraph transient: the size is a per-frame request, not memory held between
88
+ frames.
89
+
90
+ ### I.5 Consumer budgets (F5)
91
+
92
+ The product imposes no limit. Each consumer loop owns a budget constant **in that consumer's file**, chosen
93
+ by whoever builds it and presented as a chosen number, not a derived one. Each budget carries a doc line on
94
+ what it drops (I.6).
95
+
96
+ | consumer | loop | where the constant goes |
97
+ |---|---|---|
98
+ | deferred direct shading; also forward, OIT resolve, AVBOIT draw and water, which include the same chunk | `deferred/chunk_shade_standard_material_direct.js:66` (points), `:87` (spots) | the chunk is shared by five passes. Either one constant in the chunk, or a constant per including shader passed in. That is the consumers' choice. Today they all inherit one loop |
99
+ | volumetrics irradiance | `volumetrics/shader_volumetrics_build_irradiance.js:154`, `:167` | that file |
100
+ | volumetrics lighting | `volumetrics/shader_volumetrics_build_lighting.js:312`, `:353` | that file |
101
+ | ReSTIR DI candidates | `restir/di/chunk_restir_generate_candidates.js:61`, `m_initial` iterations | **nothing more needed.** The loop is already bounded by `m_initial`. The cell's `count` only scales the uniform source pdf (`inv_source_pdf = count`) and picks a slot, so a longer list costs nothing per pixel. It must read the 16-bit fields through the helpers, which it already does |
102
+
103
+ **Why the budgets matter (measured, R3.2 dense scene):** a cell of about 1,800 lights made the consumer
104
+ stand-in 6–7× slower than the 128-capped list.
105
+
106
+ ### I.6 Order inside a cell, and what a budget drops (F7)
107
+
108
+ The fine pass writes survivors in sorted-list order, chunk by chunk (64 lights per chunk, ascending).
109
+ Inside a chunk, the order follows the **subgroup lane permutation** of the 4×4×4 workgroup, which is not
110
+ `local_invocation_index` order on either tested GPU.
111
+
112
+ - **The list is chunk-major ascending, permuted within 32-light windows.**
113
+ - **Deterministic frame to frame:** the permutation is fixed per device, driver and pipeline, and was
114
+ stable across every repeated run here. It may differ between GPUs.
115
+ - **Nothing in the design depends on ascending order:**
116
+ - there is no cap and no keep-smallest;
117
+ - the counts are exact;
118
+ - consumers sum light contributions (order changes only float rounding);
119
+ - ReSTIR samples uniformly by slot.
120
+ - **What a consumer budget B drops:** the list's tail after position B. That is every light of the later
121
+ chunks, plus, inside the chunk that straddles B, whichever lanes the permutation puts last. Plainly:
122
+ **past the budget it drops the highest ids, except within one 32-light window where the choice follows
123
+ the GPU's lane order.** It is deterministic on one machine, not identical across machines. Points and
124
+ spots are separate runs, so a per-loop budget applies per type.
125
+ - **Decals are different.** Their composite order is priority order, so the decal builder must not reuse
126
+ this compaction unchanged (III.6).
127
+
128
+ ## Part II — Measurements for the decided design
129
+
130
+ **Method.** As in Appendix §0: paired, timestamped, mirrored minimum, p10.
131
+
132
+ | | arms | iterations | foreign GPU load |
133
+ |---|---|---|---|
134
+ | RTX 4090 | A0 (today), A2 (round-1 cell-centric), the decided design ("final"), and the per-cell floor | 300 | 9–17% |
135
+ | AMD RDNA2 iGPU | same | 20 | none |
136
+
137
+ The final arm's sets equal the uncapped arm's in every cell, dense scene included (16-bit set check).
138
+
139
+ ### II.1 Assignment time (p10)
140
+
141
+ | config | 4090 A0 | 4090 A2 | **4090 final** | iGPU A0 | iGPU A2 | **iGPU final** |
142
+ |---|---:|---:|---:|---:|---:|---:|
143
+ | 640×360, 0 | 4.1 | 5.1 | **7.2** | 106.6 | 4.8 | **5.7** |
144
+ | 640×360, 16 | 10.2 | 9.2 | **11.3** | 123.7 | 13.6 | **14.0** |
145
+ | 640×360, 1,024 | 486.4 | 73.7 | **82.9** | 8.12 ms | 117.6 | **122.2** |
146
+ | 640×360, 4,096 | 2.14 ms | 302.1 | **332.8** | 36.18 ms | 499.9 | **515.8** |
147
+ | 1898×982, 0 | 31.7 | 5.1 | **7.2** | 906.6 | 21.0 | **22.6** |
148
+ | 1898×982, 16 | 39.9 | 8.2 | **11.3** | 953.8 | 69.5 | **61.6** |
149
+ | 1898×982, 1,024 | 729.1 | 56.3 | **62.5** | 60.59 ms | 618.4 | **474.0** |
150
+ | 1898×982, 4,096 | 3.16 ms | 221.2 | **239.6** | 271.8 ms | 2.64 ms | **2.07 ms** |
151
+ | 4K, 0 | 208.9 | 6.1 | **8.2** | 3.53 ms | 76.6 | **80.8** |
152
+ | 4K, 16 | 217.1 | 10.2 | **11.3** | 3.70 ms | 270.3 | **230.1** |
153
+ | 4K, 1,024 | 2.32 ms | 58.4 | **62.5** | 254.3 ms | 2.43 ms | **1.71 ms** |
154
+ | 4K, 4,096 | 10.76 ms | 236.5 | **254.0** | — ¹ | 10.33 ms | **7.77 ms** |
155
+
156
+ All values are µs unless marked ms. ¹ Not run: TDR margin.
157
+
158
+ - **Against today:**
159
+ - ≥ 1,024 lights: 5.9–42× faster on the 4090 and 66–149× on the iGPU;
160
+ - 0–16 lights at 1898×982 and 4K: 3.5–25× on the 4090 and 9–44× on the iGPU;
161
+ - **at 640×360 with 0–16 lights it is 1–3 µs slower than today on the 4090** (7.2 vs 4.1, 11.3 vs
162
+ 10.2): six dispatches against one, where today's pass has almost nothing to do.
163
+ - **Against A2:**
164
+ - 4090: +7–12% at ≥ 1,024 lights, and +1–3 µs at 0–16 lights. That is the mask path's two extra
165
+ dispatches (F2), measured before as ≤ 9 µs.
166
+ - iGPU: −11% to −30% at 1898×982 and 4K from 16 lights up; +3% to +18% at 640×360 and at 0 lights.
167
+
168
+ **Per pass at 1,024 lights, 1898×982:**
169
+
170
+ | | mark | compact | prepare | coarse clear | coarse scatter | fine |
171
+ |---|---:|---:|---:|---:|---:|---:|
172
+ | 4090 | 1.0 | 3.1 | 2.0 | 1.0 | 2.0 | 53.2 |
173
+ | iGPU | 11.0 | 4.9 | 9.7 | 3.0 | 26.4 | ~460 ² |
174
+
175
+ ² The iGPU's isolated per-pass run read **1,032 µs** for the fine pass alone, more than the whole chain's
176
+ 474 µs in the paired run. **Unexplained.** The chain total is the figure to use; the iGPU's per-pass
177
+ numbers for the fine pass are not reliable here.
178
+
179
+ **Registers (measured on the exact final kernels; NVIDIA 610.88 / AMD 2.0.302 Vulkan):**
180
+
181
+ | kernel | threads | NV regs | NV local | Ada occupancy | AMD VGPR | AMD scratch | AMD LDS |
182
+ |---|---:|---:|---:|---:|---:|---:|---:|
183
+ | fine | 64 | 48 | 0 | 83% | 42 | 0 | 1,024 |
184
+ | coarse scatter | 64 | 30 | 0 | 100% | 10 | 0 | 0 |
185
+ | coarse clear | 256 | 16 | 0 | 100% | 3 | 0 | 0 |
186
+ | mark | 64 | 16 | 0 | 100% | 3 | 0 | 0 |
187
+ | compact | 256 | 20 | 0 | 100% | 18 | 0 | 512 |
188
+ | prepare + bound | 64 | 27 | 0 | 100% | — ³ | — | — |
189
+
190
+ ³ My offline `vkstats.py` route failed to compile this pipeline on the AMD driver. That is a tooling result
191
+ and says nothing about what ships; Chrome runs it on that iGPU.
192
+
193
+ ### II.2 The sizing bound against actual hits (F6)
194
+
195
+ Identical on both GPUs (it is geometry). Bytes are bound × 4.
196
+
197
+ | scene | lights | hits (exact) | **tight bound** Σ cell-box volume | **tight / hits** | loose: Σ covered blocks' cells | loose / hits | tight bound reserves |
198
+ |---|---:|---:|---:|---:|---:|---:|---:|
199
+ | §2, 640×360 | 16 | 155 | 157 | **1.013** | 2,048 | 13.2 | 0.6 KB |
200
+ | §2, 640×360 | 1,024 | 29,096 | 30,229 | **1.039** | 167,616 | 5.8 | 121 KB |
201
+ | §2, 640×360 | 4,096 | 118,905 | 123,685 | **1.040** | 682,688 | 5.7 | 495 KB |
202
+ | §2, 1898×982 | 16 | 717 | 733 | **1.022** | 4,544 | 6.3 | 2.9 KB |
203
+ | §2, 1898×982 | 1,024 | 184,933 | 194,088 | **1.050** | 639,232 | 3.5 | 776 KB |
204
+ | §2, 1898×982 | 4,096 | 761,323 | 798,852 | **1.049** | 2,666,160 | 3.5 | 3.2 MB |
205
+ | §2, 4K | 16 | 2,854 | 2,972 | **1.041** | 12,288 | 4.3 | 12 KB |
206
+ | §2, 4K | 1,024 | 818,675 | 857,113 | **1.047** | 2,345,152 | 2.9 | 3.4 MB |
207
+ | §2, 4K | 4,096 | 3,356,945 | 3,517,641 | **1.048** | 9,901,376 | 2.9 | 14.1 MB |
208
+ | dense, 640×360 | 4,096 | 2,033,294 | 2,595,249 | **1.276** | 4,204,864 | 2.1 | 10.4 MB |
209
+ | dense, 1898×982 | 4,096 | 15,069,093 | 19,473,322 | **1.292** | 29,285,824 | 1.9 | 77.9 MB |
210
+ | dense, 4K | 4,096 | 67,654,718 | 86,909,083 | **1.285** | 128,367,424 | 1.9 | 347.6 MB |
211
+
212
+ **Reading it.**
213
+
214
+ - **The tight bound is close where Alex expected:** 1.01–1.05× in the §2 scene.
215
+ - **It is loose in the dense scene: +28–29%,** 17.6 MB over the hits at 1898×982 and 77 MB at 4K. The
216
+ slack is the box test's own: big spot lights whose box is the flat-capped cone's bounding sphere, and the
217
+ corner cells of a sphere's box.
218
+ - **The "survivors × block cells" form is far looser:** 1.9–13×. The design uses the cell-box sum.
219
+
220
+ **Cost of producing the bound** (paired, p10):
221
+
222
+ | config | 4090 none | 4090 in prepare | 4090 in scatter | iGPU none | iGPU in prepare | iGPU in scatter |
223
+ |---|---:|---:|---:|---:|---:|---:|
224
+ | 640×360, 4,096 | 334.9 | 334.9 | 335.9 | 517.2 | 509.2 | 559.0 |
225
+ | 1898×982, 4,096 | 237.6 | 237.6 | 239.6 | 2,071.9 | 2,063.0 | 2,101.8 |
226
+ | 4K, 4,096 | 250.9 | 250.9 | 254.0 | 7,751.9 | 7,751.3 | 7,727.3 |
227
+ | 1898×982, dense | 2,040.8 | 2,041.9 | 2,042.7 | — | — | — |
228
+
229
+ **In `prepare` it is free** within noise on both GPUs. In the scatter, its two per-light atomics cost the
230
+ iGPU up to 48 µs.
231
+
232
+ ## Part III — Implementation plan
233
+
234
+ ### III.1 Files
235
+
236
+ All paths are under `packages/meep-engine/src/shade/renderer/`.
237
+
238
+ **New:**
239
+
240
+ | file | what |
241
+ |---|---|
242
+ | `light/cluster/chunk_cluster_light_proxy.js` | WGSL: a point/spot record + view + cluster params → view-space proxy + packed cell box + box volume. A pure function, lifted from the bench's `prepare` |
243
+ | `light/cluster/chunk_cluster_cell.js` | WGSL: cell from `(x, y, z)` (4 eye planes from the tile's NDC edges, depths from `chunk_cluster_depth_from_z_slice`, bounding sphere when bounded); `sphere_vs_cell`; `spot_vs_cell` (cone vs the cell sphere, or the cone's own bounding sphere vs the planes for the unbounded slice) |
244
+ | `light/cluster/shader_cluster_light_mark.js` | pass 1 |
245
+ | `light/cluster/shader_cluster_light_compact.js` | pass 2 |
246
+ | `light/cluster/shader_cluster_light_prepare.js` | pass 3, with the bound |
247
+ | `light/cluster/shader_cluster_coarse_mark.js` | passes 4 + 5 (clear and scatter; two entry points or two shaders) |
248
+ | `light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.js` | the 4-cell block edge = the fine workgroup's edge |
249
+
250
+ **Changed:**
251
+
252
+ | file | change |
253
+ |---|---|
254
+ | `light/cluster/shader_cluster_assign_lights.js` | rewritten as pass 6 (fine pass). The private array, `frustum_slice` usage and per-pair corner rebuild go |
255
+ | `light/cluster/graph_assign_clsuters.js` | encodes the 6 dispatches in one compute pass; creates the sorted list, proxies, boxes, visibility and coarse masks, bound word; sizes `cluster_data` from `GPUCollectionLimits`; records the bound with `graph_record_stat` |
256
+ | `light/cluster/chunk_light_cluster_counts.js` | 16-bit fields; `LIGHT_CLUSTER_PER_TYPE_MAX` = 65,535 |
257
+ | `light/cluster/LIGHT_CLUSTER_METADATA.js` | doc: bits [0:15] point, [16:31] spot |
258
+ | `rasterize/expand/RasterizationCollectionType.js`, `rasterize/expand/GPUCollectionLimits.js` | new column `LightClusterEntries`, element size 4, initial global max |
259
+ | consumers (I.5) | a budget constant each, chosen by their owner |
260
+
261
+ **Deleted:**
262
+
263
+ - `light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.js`;
264
+ - `light/cluster/chunk_cluster_keep_smallest.js` and its `.spec.js`.
265
+
266
+ `chunk_cluster_slice_frustum`, `chunk_frustum_from_corners`, `chunk_frustum_to_corners` and
267
+ `chunk_plane_from_triangle` stay, because the decal builder still links them. The light path stops linking
268
+ them.
269
+
270
+ ### III.2 Order of work, and the spec that pins each step red-then-green
271
+
272
+ **Spec rules:** plain top-level `test()`, no mocks, spies, `.each` or hooks; helpers inside the spec;
273
+ assertions on public API or on what reaches the device. Each step's spec is run red against the code before
274
+ the step.
275
+
276
+ | # | step | spec (tier) | the red it catches |
277
+ |---|---|---|---|
278
+ | 1 | 16-bit count fields | `chunk_light_cluster_counts.spec.js` (tier 2, emulator): pack/unpack round-trips every `(p, s)` on a grid up to 16,383 each, the cull limit; point and spot never alias | today's 8-bit helpers fail at 256 |
279
+ | 2 | lift `chunk_cluster_cell` (no behaviour change: the bench's tests are A0fix's semantics) | `chunk_cluster_cell.spec.js` (tier 2), against geometry: a sphere strictly beyond one cell plane (distance > r) is rejected; a sphere containing a cell corner is accepted; a point light whose centre is inside the cell is accepted; for the last slice, a spot whose cone's bounding sphere is outside the XY planes is rejected and one crossing them is accepted | today's shipped spot test accepts every last-slice spot |
280
+ | 3 | lift `chunk_cluster_light_proxy` | `chunk_cluster_light_proxy.spec.js` (tier 2): for seeded point and spot lights, sampled points of the influence sphere project into cells inside the packed box (conservative); the box exceeds the sampled cells by at most one tile per side (tight); box volume equals the product of extents | a box from the centre only, or off by one at the screen edge |
281
+ | 4 | passes 1–3 (mark, compact, prepare) | tier 1 `*.wgsl_validity.spec.js` per shader; tier 2 for mark and for prepare's per-light outputs (each invocation independent); **compaction and the bound's workgroup reduction on tier 4** (headless Chrome verify function: shuffled cull list in, list sorted by (type, id) out, bound = Σ box volumes) | an unsorted output; a bound that misses a workgroup |
282
+ | 5 | passes 4–5 (coarse) | tier 2: per light, every cell of its box lies in a block whose mask has its bit; no block outside the box's blocks has it | a scatter that drops the box's last block row |
283
+ | 6 | pass 6 + graph wiring; delete the private array, keep-smallest and the local limit | **tier 3** (`SoftwareGPUDevice`, real `graph_assign_clsuters`): 6 dispatches in one pass, in order, with direct workgroup counts from the CPU-known light count and the grid; `cluster_data` size = `compute_buffer_size(LightClusterEntries) + 4`; the bound recorded into the limits' stat buffer. **Tier 4:** per-cell sets equal a brute-force reference that runs the step-2 chunks over every (cell, light) pair on the emulator (the oracle is the pinned chunks, not a second copy of the arithmetic), at 0 / 16 / 1,024 lights; no cell loses a light; counts above 255 in a dense scene | today's shader caps at 128 and drops lights; the old graph has 1 dispatch |
284
+ | 7 | sizing through `GPUCollectionLimits` | tier 3: a frame whose recorded bound exceeds the column's limit grows `compute_buffer_size(LightClusterEntries)` on the following frame (the `GPUCollectionLimits.spec.js` pattern); the first frame at a new resolution primes from `estimate_cluster_data_limit` | a buffer that stays at the estimate |
285
+ | 8 | consumer budgets, one consumer at a time, by its owner | per consumer, tier 2 on the lifted loop chunk: a cell list longer than the budget evaluates exactly `budget` entries and drops the tail; shorter lists are unaffected | the loop is unbounded today |
286
+
287
+ **Landing note.** Steps 1–3 are no-behaviour-change commits. Step 6 is the switch. Steps 7–8 can land after
288
+ 6, but 7 must land before scenes rely on dense clusters, since without it the buffer stays at the estimate.
289
+
290
+ ### III.3 Reuse map (final)
291
+
292
+ | piece | existing machinery reused |
293
+ |---|---|
294
+ | culled input | `graph_cull_lights` output, unchanged |
295
+ | sorted list | ordered compaction; one workgroup suffices at the cull limit. `graph_prefix_scan_csdldf` is the general scan if the cull limit ever rises |
296
+ | light records | `LIGHT_DATABASE_SPEC` marshalling reads, once per light instead of once per (cell, light) |
297
+ | proxy | `chunk_point_light_to_aabb3` / `chunk_spot_light_to_aabb3` semantics, `chunk_cone_to_bounding_box`, `chunk_cluster_depth_to_z_slice`; `chunk_sphere_screen_extents` (exists, one caller, written for +z forward: the proxy uses the −z form) |
298
+ | cell and tests | `chunk_cluster_depth_from_z_slice`; `chunk_sphere_intersects_frustum` semantics; `chunk_cone_intersects_sphere` verbatim |
299
+ | compaction and allocation | the A2/G subgroup scan; `chunk_vsm_append_mover`'s subgroup-aggregated allocation |
300
+ | sizing | `GPUCollectionLimits` + `graph_record_stat` |
301
+ | validity / emulator / software device / playground | the four testing tiers |
302
+
303
+ **Duplication removed:** the per-pair corner rebuild, the per-pair record re-read, the private array, and
304
+ `chunk_cluster_keep_smallest`.
305
+
306
+ ### III.4 What breaks
307
+
308
+ | what | impact |
309
+ |---|---|
310
+ | the 8-bit count readers | every consumer reads the counts through `chunk_light_cluster_counts`, so step 1 covers them all (grep-verified: no other masks) |
311
+ | `LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT` | no longer drives `estimate_cluster_data_limit` |
312
+ | order of lights within a cell | changes from the cull's atomic order (non-deterministic) to the I.6 order (deterministic). Lighting sums change in the last bits; a pixel-exact golden image would need re-baselining |
313
+ | crowded cells | in scenes with crowded cells, lights the cap dropped now shade, and consumer cost rises until the budgets (step 8) land |
314
+
315
+ ### III.5 CPU-side cost
316
+
317
+ Six dispatches in one compute pass replace one. At the frame-anatomy report's measured ≈ 4 kcyc per extra
318
+ dispatch in an open pass, that is ≈ 20 kcyc of Chrome's GPU-process thread per frame. This is
319
+ **predicted**: the price is measured, the count is from this design. No indirect dispatch.
320
+
321
+ ### III.6 Follow-up, out of scope: the decal builder
322
+
323
+ `engine/graphics3/decal/shader_cluster_assign_decals.js` has today's shape: a sorted 32-entry private
324
+ array, keep-largest by record index (priority).
325
+
326
+ It can take the same prepass → coarse → fine structure, but its composite **depends on priority order**.
327
+ So it needs an order-preserving compaction, either:
328
+
329
+ - the 1D-workgroup variant (measured ordered, fast; Appendix R3.1), or
330
+ - the LDS-ranked one (spec-proof);
331
+
332
+ not F7's lane order. It also needs its own decision on whether a cap stays. Not planned here.
333
+
334
+ ---
335
+
336
+ ## Part IV — As landed
337
+
338
+ ### IV.1 Commits
339
+
340
+ | step | commit | |
341
+ |---|---|---|
342
+ | plan | `a33e8a355` | this document and PROPOSAL_ALGORITHM |
343
+ | 1 | `7cccdc28a` | counts 16 bits per type |
344
+ | 2 | `cce95c4d7` | `chunk_cluster_cell` |
345
+ | 3 | `db5fac70c` | `chunk_cluster_light_proxy` |
346
+ | 4 | `0281b8eb1` | mark, compact, prepare |
347
+ | 5 | `b0291ed5a` | coarse clear and scatter |
348
+ | 6 | `c6b17e747` | the fine pass and the graph: the switch |
349
+ | 7 | `83cedf8d9` | `cluster_data` sized from the bound through `GPUCollectionLimits` |
350
+ | fix | `5fcb1201c` | dispatches sized by the tables' live lights, not their slots |
351
+ | 8 | `94665ac11` | consumer budgets |
352
+ | fix | `96f0fdf31` | the coarse clear one thread per mask word |
353
+
354
+ ### IV.2 What differs from Parts I–III
355
+
356
+ - **Compact** works in rounds of 16,384 table slots, since ids are slots and a table can hold more than the
357
+ cull list. It scans in workgroup memory in thread order, so the list is sorted by construction, not by the
358
+ subgroup lane mapping. The visibility bitmask is a FrameGraph transient the graph clears; compact reads it
359
+ through a plain read-only view. Nothing self-clears.
360
+ - **The bound saturates** at 2^32 − 1 rather than wrapping (measured: 1,000 whole-grid lights on a 16,384²
361
+ grid).
362
+ - **Six dispatches in one pass** needed `ComputeShader.dispatchInPass` and
363
+ `ShadeGPUCommandContext.bindComputePipeline`.
364
+ - **Dispatch sizes** come from the tables' live counts (`GPUTypedTable.count`), capped at the cull list's
365
+ 16,383. The coarse clear is one thread per mask word, folded into rows of 1,024 workgroups. Both were
366
+ measured regressions in the first landing (IV.3).
367
+ - **Priming:** the `LightClusterEntries` column is primed with 64.5 entries a cell whenever a grid needs
368
+ more than it holds, so it never drops below today's size.
369
+ - **Budgets (I.5),** chosen in tens: deferred 64, AVBOIT draw 32, MBOIT resolve 32, fog irradiance 32, fog
370
+ in-scatter 16, per type. The shared chunk takes the two budgets as parameters, and each including shader
371
+ passes its own. Water does not walk the clusters. Of the "five passes", three include the chunk:
372
+ deferred, AVBOIT draw and MBOIT resolve.
373
+
374
+ ### IV.3 Measured after landing
375
+
376
+ The assignment, p10 µs, paired in one process with A0 (the shader before step 6) and Part II's arm, mirrored:
377
+
378
+ | | 4090 A0 | 4090 landed | ×A0 | iGPU A0 | iGPU landed | ×A0 |
379
+ |---|---:|---:|---:|---:|---:|---:|
380
+ | 640×360, 0 | 4.1 | 2.0 | 2.0 | 104.6 | 3.7 | 28 |
381
+ | 640×360, 16 | 10.2 | 11.3 | 0.9 | 123.4 | 14.2 | 8.7 |
382
+ | 640×360, 1,024 | 486.4 | 78.8 | 6.2 | 8,109.8 | 122.2 | 66 |
383
+ | 640×360, 4,096 | 2,146.3 | 318.5 | 6.7 | 36,172.5 | 511.2 | 71 |
384
+ | 1898×982, 0 | 32.8 | 2.0 | 16 | 913.6 | 20.7 | 44 |
385
+ | 1898×982, 16 | 39.9 | 11.3 | 3.5 | 953.2 | 62.4 | 15 |
386
+ | 1898×982, 1,024 | 729.1 | 59.4 | 12 | 60,656.2 | 461.0 | 132 |
387
+ | 1898×982, 4,096 | 3,164.2 | 225.3 | 14 | 271,849.6 | 2,019.4 | 135 |
388
+ | 3840×2160, 0 | 208.9 | 4.1 | 51 | 3,519.3 | 80.4 | 44 |
389
+ | 3840×2160, 16 | 218.1 | 12.3 | 18 | 3,698.0 | 230.6 | 16 |
390
+ | 3840×2160, 1,024 | 2,325.5 | 60.4 | 39 | 254,395.6 | 1,650.1 | 154 |
391
+ | 3840×2160, 4,096 | 10,632.1 | 242.1 | 44 | not run ¹ | 7,564.2 | — |
392
+
393
+ ¹ A0 there takes about a second a pass on the iGPU. Part II did not run it either.
394
+
395
+ The landed code against Part II's arm in the same runs: 0.94–1.00 on the 4090 and 0.97–1.00 on the iGPU
396
+ wherever there are lights, and 0.29–1.00 with none (it skips the passes the arm ran).
397
+
398
+ Per-cell lists, tier 4, both GPUs, checked against `chunk_cluster_cell` on the emulator: every cell equal at
399
+ 0, 16 and 1,024 lights (1898×982) and in the dense 1,200-light scene (cells up to 694 points / 460 spots).
400
+ At 3840×2160 with 4,096 lights, one cell of 195,840 lacks a spot the oracle keeps. Its cap plane touches
401
+ the cell's bounding sphere within 6.2e-7 m at 20 m, below f32 resolution.
402
+
403
+ A playground (tonemap_sdr scene 1 with 300 bounded points and 100 spots added, camera frozen, TAA and SSAO
404
+ off): the landed build is bit-identical run to run. Against the build before step 6 it differs in 2–6 of
405
+ 1.34 M channels by one code; that build differs from itself by 4.
406
+
407
+ # Appendix A — the round-2 and round-3 record
408
+
409
+ Superseded wherever it conflicts with Parts I–III.
410
+
411
+ ## A.0 Round 2: hierarchical, linked list, small-set path
412
+
413
+ (Round 2 status.) Proposal only, nothing built for landing. This round implements what Alex picked out of the two
414
+ first-round proposals (`PROPOSAL_ALGORITHM_2026_10_16.md`, `PROPOSAL_STRUCTURE_2026_10_16.md`): a hierarchy
415
+ that bins in 2D first and then walks the slices, a linked-list output instead of per-thread arrays, and a
416
+ small-set path. The fused-cull idea and the 64 px tile tweak are dropped.
417
+
418
+ ## R3. Round 3: decided — G, count-then-write, no per-cell cap (added 2026-10-16)
419
+
420
+ Alex pinned **G** (F4) and settled **F1**: count-then-write into today's product, **with the per-cell cap
421
+ removed** and `LIGHT_CLUSTER_METADATA.counts` widened to **16 bits per type** (point in bits 0–15, spot in
422
+ bits 16–31). The sections after this one are the round-2 record. Where they talk about the cap,
423
+ keep-smallest or the 8-bit fields, this section supersedes them. All of this is still a proposal: nothing is
424
+ built for landing.
425
+
426
+ The coarse path used is **mask always** (F2's recommendation): light-scatter coarse masks at every light
427
+ count.
428
+
429
+ ### R3.1 The arm: "G ctw uncapped"
430
+
431
+ 1. Prepass, as before: id-sorted (F3).
432
+ 2. Coarse clear + light scatter.
433
+ 3. Fine pass:
434
+ - **Sweep 1** counts every hit per type. **No cap.**
435
+ - **One allocation** covers the exact total: one subgroup-aggregated `atomicAdd` per subgroup, skipped
436
+ when the subgroup's total is 0.
437
+ - **Sweep 2** writes all of them: points, then spots, ascending id.
438
+ - Metadata `{counts: point | spot << 16, offset}`.
439
+
440
+ keep-smallest is gone: no cell drops lights unless the global pool overflows (R3.4).
441
+
442
+ **Per-thread loop budgets:**
443
+
444
+ | loop | budget | past it |
445
+ |---|---|---|
446
+ | prepass compaction | 64 bits | — |
447
+ | coarse scatter | coarse blocks / 64; ≤ 48 at 4K | — |
448
+ | fine sweeps | ≤ W/2 word pairs × ≤ 64 survivors per pair; W ≤ 512 at the cull limit, so ≤ 256 pairs | nothing is dropped: the cull limit bounds W |
449
+
450
+ **Ordering finding, and the fix.** The 4×4×4 workgroup's `subgroup_invocation_id` is not in
451
+ `local_invocation_index` order on this hardware. Subgroups are index/32, but the lanes are permuted inside
452
+ one. So the subgroup-scan compaction inherited from A2 left each cell's list deterministic but *not
453
+ ascending* inside 32-light windows, on both GPUs.
454
+
455
+ That also explains round 1's "borderline light flips between compiled variants" (and the one A2 ≠ G cell at
456
+ 640×360 × 4,096 in §1): it was this permutation picking a different 128th light at the cap, not codegen.
457
+ Capped A2 therefore keeps a near-smallest set, not the smallest, where the cap binds.
458
+
459
+ The fix measured below runs the fine pass as a **1D 64-thread workgroup**, with the cell decoded from the
460
+ index (x = i & 3, y = (i >> 2) & 3, z = i >> 4). Lanes then follow the index on both GPUs, and the lists
461
+ come out ascending, with 0 violations in every configuration.
462
+
463
+ - WGSL does not promise this lane order.
464
+ - The spec-proof alternative ranks survivors through a 64-bit keep mask in workgroup memory ("ranked 3D"
465
+ below). It costs the iGPU +16–38%. (My offline `vkstats.py` route failed to compile it on
466
+ the AMD driver: a tooling result, not a statement about what ships.)
467
+
468
+ **Registers.** Uncapped G (1D) is identical to capped:
469
+
470
+ | | regs | local mem | shared mem | occupancy | scratch |
471
+ |---|---:|---:|---:|---:|---:|
472
+ | NVIDIA | 48 | 0 | 1,296 B | 83% | — |
473
+ | AMD | 42 VGPR / 76 SGPR | — | 1 KiB LDS | — | 0 |
474
+
475
+ The 16-bit consumer stand-in compiles to the same 32 regs / 21 VGPR as the 8-bit one.
476
+
477
+ **Correctness.** At every configuration below:
478
+
479
+ - uncapped ⊇ capped;
480
+ - uncapped = capped wherever the cap did not bind;
481
+ - capped G = A2, except the permutation cell;
482
+ - lists ascending.
483
+
484
+ ### R3.2 Measured: capped vs uncapped (same scene as §2; p10, mirrored minimum)
485
+
486
+ | config | 4090 capped | 4090 uncapped | 4090 uncapped, ranked 3D | iGPU capped | iGPU uncapped | iGPU uncapped, ranked 3D | words capped | words uncapped | worst cell, capped (pt/sp) | worst cell, uncapped (pt/sp) |
487
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
488
+ | 640×360, 0 | 6.1 | 6.6 | 6.1 | 5.4 | 5.5 | 5.7 | 0 | 0 | 0/0 | 0/0 |
489
+ | 640×360, 16 | 11.3 | 11.3 | 11.3 | 13.4 | 13.4 | 13.8 | 155 | 155 | 2/1 | 2/1 |
490
+ | 640×360, 1,024 | 85.0 | 84.0 | 76.8 | 123.5 | 121.6 | 145.0 | 29,096 | 29,096 | 37/22 | 37/22 |
491
+ | 640×360, 4,096 | 337.9 | 333.8 | 306.2 | 539.0 | 518.4 | 600.6 | 118,708 | 118,905 | 128/81 | 143/81 |
492
+ | 1898×982, 0 | 7.2 | 7.2 | 7.2 | 21.7 | 21.7 | 23.7 | 0 | 0 | 0/0 | 0/0 |
493
+ | 1898×982, 16 | 11.3 | 11.3 | 11.3 | 60.4 | 60.2 | 61.9 | 717 | 717 | 2/1 | 2/1 |
494
+ | 1898×982, 1,024 | 62.5 | 62.5 | 58.4 | 485.4 | 473.8 | 644.8 | 184,933 | 184,933 | 33/20 | 33/20 |
495
+ | 1898×982, 4,096 | 241.7 | 238.6 | 223.2 | 2.15 ms | 2.09 ms | 2.72 ms | 761,323 | 761,323 | 125/72 | 125/72 |
496
+ | 4K, 0 | 8.2 | 8.2 | 8.2 | 77.2 | 77.1 | 86.4 | 0 | 0 | 0/0 | 0/0 |
497
+ | 4K, 16 | 11.3 | 11.3 | 11.3 | 225.2 | 225.2 | 232.1 | 2,854 | 2,854 | 2/1 | 2/1 |
498
+ | 4K, 1,024 | 62.5 | 61.4 | 63.1 | 1.75 ms | 1.71 ms | 2.35 ms | 818,675 | 818,675 | 35/21 | 35/21 |
499
+ | 4K, 4,096 | 255.0 | 251.9 | 252.9 | 8.10 ms | 7.82 ms | 10.34 ms | 3,356,922 | 3,356,945 | 128/75 | 132/75 |
500
+
501
+ **Consumer stand-in, capped vs uncapped (p10):**
502
+
503
+ | config | 4090 capped | 4090 uncapped | iGPU capped | iGPU uncapped |
504
+ |---|---:|---:|---:|---:|
505
+ | 640×360, 1,024 | 14.3 | 14.3 | 785 | 785 |
506
+ | 640×360, 4,096 | 45.1 | 44.0 | 2.94 ms | 2.94 ms |
507
+ | 1898×982, 1,024 | 61.4 | 61.4 | 5.18 ms | 5.18 ms |
508
+ | 1898×982, 4,096 | 198.7 | 197.6 | 19.02 ms | 19.02 ms |
509
+ | 4K, 1,024 | 256.0 | 253.9 | 23.02 ms | 23.02 ms |
510
+ | 4K, 4,096 | 833.5 | 829.4 | 84.67 ms | 84.70 ms |
511
+
512
+ At 0 and 16 lights they are identical. **In this scene removing the cap costs nothing**: the cap binds in a
513
+ handful of cells, and the uncapped arm is 0–4% faster because it drops the cap compares.
514
+
515
+ **A dense stress scene, to make the cap bind.** 4,096 lights (2,048 point + 2,048 spot) with a 10–30 m
516
+ range, packed into 2–40 m of depth. The uncapped pool is sized to its demand (6× today's) so that nothing
517
+ is truncated (p10):
518
+
519
+ | | 4090 640×360 | 4090 1898×982 | 4090 4K | iGPU 640×360 | iGPU 1898×982 |
520
+ |---|---:|---:|---:|---:|---:|
521
+ | assignment, capped | 1.36 ms | 1.19 ms | 1.26 ms | 1.80 ms | 10.0 ms |
522
+ | assignment, uncapped | 2.25 ms | 2.05 ms | 2.72 ms | 3.17 ms | 21.4 ms |
523
+ | consumer, capped | 93 µs | 564 µs | 2.43 ms | 7.15 ms | 58.6 ms |
524
+ | consumer, uncapped | 630 µs | 3.52 ms | 17.8 ms | 50.1 ms | 379 ms |
525
+ | cells over 128 of one type (uncapped) | 1,440 of 5,760 | 11,160 of 44,640 | 48,960 of 195,840 | 1,440 | 11,160 |
526
+ | worst cell, uncapped (pt/sp) | 1,821/767 | 1,755/708 | 1,791/734 | 1,821/767 | 1,755/708 |
527
+ | `cluster_data` words, capped / uncapped | 0.33 M / 2.03 M | 2.52 M / 15.07 M | 11.08 M / 67.65 M | same | same |
528
+
529
+ **Reading it.** Where the cap binds, removing it makes the assignment 1.6–2.2× slower. The consumer gets
530
+ 6.2–7.3× slower, because its per-pixel loop grows with the cell. In exchange, it shades exactly the lights
531
+ that reach the pixel instead of the 128 smallest ids. Today 25% of the cells at 1898×982 lose lights in this
532
+ scene.
533
+
534
+ ### R3.3 Demand against today's capacity
535
+
536
+ `estimate_cluster_data_limit` sizes `cluster_data` at max(⌈C/2⌉ · 128 + ⌊C/2⌋, 64 · C) ≈ **64.5 words per
537
+ cell**. Today's assign shader truncates at that capacity, and that sizing rule is the
538
+ `LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT` cap in disguise.
539
+
540
+ | 4,096 lights | cells | capacity (words) | uncapped demand | demand / capacity |
541
+ |---|---:|---:|---:|---:|
542
+ | 640×360, §2 scene | 5,760 | 371,520 | 118,905 | 32.0% |
543
+ | 1898×982, §2 scene | 44,640 | 2,879,280 | 761,323 | 26.4% |
544
+ | 4K, §2 scene | 195,840 | 12,631,680 | 3,356,945 | 26.6% |
545
+ | 640×360, dense | 5,760 | 371,520 | 2,033,294 | **547%** |
546
+ | 1898×982, dense | 44,640 | 2,879,280 | 15,069,093 | **523%** |
547
+ | 4K, dense | 195,840 | 12,631,680 | 67,654,718 | **536%** (271 MB) |
548
+
549
+ There is no cap-derived upper bound any more. The worst case is cells × the cull limit (16,383) words.
550
+
551
+ ### R3.4 Pool overflow (measured)
552
+
553
+ **Mechanism.** The fine pass allocates one block per subgroup, in whatever order the subgroups reach the
554
+ atomic.
555
+
556
+ - When the counter passes capacity, a subgroup's cells get `min(count, what is left)`: points first, then
557
+ spots, ascending.
558
+ - Later subgroups get 0.
559
+ - **Which cells lose lights is not deterministic.**
560
+
561
+ **Measured.** Uncapped G at 1898×982 × 4,096 lights, with the pool forced to half its demand (380,661 of
562
+ 761,323 words), run 4 times:
563
+
564
+ - every run wrote exactly the capacity;
565
+ - the set of truncated cells differed between runs in **71, 71 and 149 cells** (against run 0).
566
+
567
+ **Covering it.**
568
+
569
+ 1. **Sizing feedback (reuse):** `GPUCollectionLimits` (`rasterize/expand/GPUCollectionLimits.js`) already
570
+ reads back per-collection demand counters a frame late and grows the buffers; `cluster_data` becomes
571
+ one more collection there. (Decided in Part I: the counter is the coarse cell-box bound.) A frame that
572
+ overflows loses lights non-deterministically in the cells above; the next frame is sized to fit.
573
+ 2. **Initial size:** keep `estimate_cluster_data_limit`'s 64.5 words per cell as the starting point and
574
+ let the feedback grow it. It is no longer tied to a cap.
575
+ 3. **Deterministic overflow (option, unmeasured):** allocate by a prefix scan over per-cell counts in
576
+ cell order (`graph_prefix_scan_csdldf`) instead of the subgroup atomic. Overflow would then truncate the
577
+ highest cell indices, the same ones every frame. It costs a count pass, a scan, and the write pass. That
578
+ is fork F6.
579
+
580
+ ### R3.5 Consumer loop budget (fork F5 — facts, no number)
581
+
582
+ With no per-cell cap, a consumer's light loop is bounded only by the cull list (16,383 lights).
583
+
584
+ **Today it is bounded by the cap:** 128 per type written, but the field allows 255.
585
+
586
+ **The loops:**
587
+
588
+ | consumer | where | loop over | bound today |
589
+ |---|---|---|---|
590
+ | deferred direct shading | `deferred/chunk_shade_standard_material_direct.js:66` (points), `:87` (spots) | the cell's point / spot list | count field |
591
+ | forward / OIT resolve / AVBOIT draw / water | the same chunk, via `rasterize/forward/chunk_forward_shade_standard_fragment.js`, `rasterize/native/oit/oit_resolve_fragment_body.js`, `rasterize/native/avboit/avboit_draw_fragment_body.js` (water's `shader_water_avboit.js` uses the AVBOIT body) | same | count field |
592
+ | volumetrics irradiance | `volumetrics/shader_volumetrics_build_irradiance.js:154`, `:167` | the froxel cell's points / spots | count field |
593
+ | volumetrics lighting | `volumetrics/shader_volumetrics_build_lighting.js:312`, `:353` | same | count field |
594
+ | ReSTIR DI candidates | `restir/di/chunk_restir_generate_candidates.js:61` | `m_initial` candidates, sampling uniformly over `count` | its own `m_initial` (unchanged) |
595
+
596
+ **The measured cost of a long list** is in R3.2's dense table: the consumer grew 6–7× when the worst cell
597
+ went from 128 to ~1,800 lights.
598
+
599
+ **The question for Alex (F5).** Does each of these loops get its own budget? A budget means a constant per
600
+ consumer and a doc line on what is dropped past it: with ascending ids, the highest ids in the cell,
601
+ deterministically.
602
+
603
+ The alternatives are to leave them bounded only by the cull limit, or to use ReSTIR-style sampling as the
604
+ budgeted path for crowded cells. No number is proposed here.
605
+
606
+ ### R3.6 What breaks with 16-bit count fields, and what goes away
607
+
608
+ **Changes:**
609
+
610
+ | file | change |
611
+ |---|---|
612
+ | `light/cluster/chunk_light_cluster_counts.js` | `light_cluster_count_point` → `counts & 0xFFFFu`; `light_cluster_count_spot` → `counts >> 16u`; `light_cluster_pack_counts` → `(p & 0xFFFFu) \| (s << 16u)`. Every consumer goes through these helpers, so no consumer source changes: `chunk_shade_standard_material_direct.js:63–64`, `chunk_restir_generate_candidates.js:50–51`, `shader_volumetrics_build_irradiance.js:151–152`, `shader_volumetrics_build_lighting.js:309–310`. Verified by grep: no other reader masks the field. |
613
+ | `LIGHT_CLUSTER_PER_TYPE_MAX` (same file) | 255 → 65,535. Grep finds no other user. 16 bits cannot saturate: the cull list holds ≤ 16,383 lights. |
614
+ | `light/cluster/LIGHT_CLUSTER_METADATA.js` | doc comment: bits [0:15] point, [16:31] spot. The reserved bits "decals, other future light types" are gone. Decals have their own `DECAL_CLUSTER_METADATA`. |
615
+ | `light/cluster/graph_assign_clsuters.js` | `estimate_cluster_data_limit` no longer derives from `LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT` (R3.3), and the buffer joins `GPUCollectionLimits`. |
616
+
617
+ **Goes away:**
618
+
619
+ - `LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.js`;
620
+ - `chunk_cluster_keep_smallest.js` and its spec;
621
+ - the private `local_lights` array, and today's `shader_cluster_assign_lights.js`, replaced by G's passes.
622
+
623
+ **Unchanged:**
624
+
625
+ - the consumer contract (offset + points then spots);
626
+ - the grid;
627
+ - the cull pass;
628
+ - the unbounded last slice.
629
+
630
+ **Reuse map additions:**
631
+
632
+ - sizing: `GPUCollectionLimits`;
633
+ - the deterministic-overflow option: `graph_prefix_scan_csdldf`;
634
+ - everything else: §5's map.
635
+
636
+ ### R3.7 Forks still open
637
+
638
+ - **F2:** mask always (recommended) vs the 1,024 switch.
639
+ - **F3:** sort (recommended).
640
+ - **F5:** consumer loop budgets (R3.5).
641
+ - **F6:** overflow allocation:
642
+ - subgroup atomic + grow-on-feedback: measured, non-deterministic on the overflowing frame — recommended,
643
+ because overflow is a sizing transient once the feedback is in;
644
+ - cell-ordered scan: deterministic truncation, one more pass, unmeasured.
645
+ - **F7:** lane order:
646
+ - 1D 64-thread fine pass: measured ascending on both GPUs, fast — recommended, with the spec caveat
647
+ stated;
648
+ - LDS-ranked 3D: spec-proof, +16–38% on the iGPU.
649
+
650
+ **Constraints kept:**
651
+
652
+ - The grid stays 32 px × 24 slices.
653
+ - The input is the cull's atomic-appended `(id, type)` list and its count, exactly as today. Nothing moves
654
+ into `graph_cull_lights`.
655
+ - The last slice stays unbounded: [`depth_from_slice(23)`, ∞). The precise tests handle an unbounded cell
656
+ in XY only, the `A0fix` way. The first round's "defect" wording is withdrawn: the unbounded slice is
657
+ intentional, and only the spot test needs that treatment there.
658
+ - Every cell of the 32 px × 24 grid is served, empty space included. No stage reads depth or the HZB to
659
+ skip cells: clusters are the 3D structure, and that generality is why they were chosen.
660
+ - (Round 2) The per-type cap stays today's (`LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT`, keep-smallest). Its value
661
+ is not derived from anything here. **Superseded by R3: no per-cell cap.**
662
+
663
+ **Measurement method.** Every number is **measured**: paired in one process, every arm in its own
664
+ timestamped pass, the order alternating per iteration, behind a ballast pass.
665
+
666
+ | | RTX 4090 | AMD Radeon iGPU (RDNA2, 2 CUs, `--use-adapter-luid=0,120673`) |
667
+ |---|---|---|
668
+ | iterations | 300 | 20 |
669
+ | per-iteration value | **minimum of two mirrored runs** (A..Z then Z..A) | **minimum of two mirrored runs** |
670
+ | reported statistic | p10 | p10 |
671
+ | foreign GPU load | 1% at the start of the final run | none (no other client) |
672
+
673
+ 4090 numbers are relative on that device. The scene, the shipped WGSL, the real `GPUDatabase` and the
674
+ engine camera are as in round 1, §6.
675
+
676
+ ## 0. Summary
677
+
678
+ 1. **2D first, then slices, as specified (H), loses at 4K and on the modest GPU, and wins on the 4090 at
679
+ ≤1898×982.**
680
+ - 4090, 1,024 lights: 36 µs at 1898×982 vs A2's 56 µs, but 102 µs at 4K vs 57.
681
+ - iGPU: 1.43 ms vs 0.62 ms (1898×982), and 6.1 ms vs 2.4 ms (4K).
682
+ - **Why:** each tile walks its survivors serially, so the work is O(Σ tile–light pairs), which grows with
683
+ the pixel count. Only the 1–4 lanes inside a survivor's slice range do work. Packing 4 tiles per
684
+ workgroup (100% occupancy instead of 50%) gains ≤ 12%.
685
+ 2. **The hierarchy that wins on both GPUs is coarse-to-fine with a 3D coarse unit: "G".** G is A2's shape:
686
+ - **coarse unit:** a 4×4×4 cell block, which is one workgroup;
687
+ - **small set:** the coarse cull is an in-workgroup box test per light;
688
+ - **scalable path:** each light marks the blocks it covers in a per-block bitmask, one workgroup per
689
+ light, no gather;
690
+ - **fine stage:** every cell runs the precise test on its block's survivors, in id order.
691
+ 3. **Linked list against count-then-write, same hierarchy (G):**
692
+ - **assignment:** the list's single sweep is 20–31% faster on the 4090 and 25–31% on the iGPU.
693
+ - **compaction into today's product** (UE's `LightGridCompactCS` shape) costs 9–125 µs on the 4090 and
694
+ 0.4–15 ms on the iGPU.
695
+ - **consumers walking the list directly** pay +8–30% per consumer pass on the 4090 and +6–27% on the
696
+ iGPU (stand-in shading pass).
697
+ - **Net:** on the iGPU count-then-write wins against both list options for any consumer count ≥ 1. On the
698
+ 4090 the list wins only with 1–2 consumers.
699
+ - **Fork F1; recommendation: count-then-write into today's product.** It has no per-thread arrays
700
+ either: counts live in registers and survivors in workgroup memory.
701
+ 4. **The small-set threshold: derived 1,024, measured crossover device-specific.**
702
+ - **Derivation:** 32 lanes × 32 bits. 32 is the minimum subgroup width both adapters report, and it is
703
+ also 24 slices rounded up to the next power of two.
704
+ - **Measured crossover between the in-workgroup box test and the light-scatter mask:**
705
+ - 4090: the box path wins up to 1,024 lights (by 3–9 µs) and ties at 4,096.
706
+ - iGPU: the mask path wins at **every** count at 1898×982 and 4K (−17% at 16 lights, −31% at 4K with
707
+ 1,024).
708
+ - **Fork F2; recommendation: one path, the mask, everywhere.**
709
+ 5. **Recommended: G**, run as:
710
+ - id-sorting prepass (3 small direct dispatches);
711
+ - light-scatter coarse mask (2 direct dispatches);
712
+ - fine pass, count-then-write into today's `{counts, offset}` (1 direct dispatch).
713
+
714
+ No indirect dispatch.
715
+
716
+ | lights | 4090 | iGPU |
717
+ |---:|---:|---:|
718
+ | 0 | 4–6 µs | 5–81 µs |
719
+ | 1,024 | 62–85 µs | 0.12–1.74 ms |
720
+ | 4,096 | 240–340 µs | 0.53–8.1 ms |
721
+ | **today, 1,024** | **0.49–2.5 ms** | **8.1–256 ms** |
722
+
723
+ ## 1. What was built
724
+
725
+ All arms produce **identical per-cell sets to A2** at 1898×982 × {0, 16, 1,024, 4,096} lights, 640×360 ×
726
+ 4,096 and 4K × 4,096. That includes cells at the cap of 128, where keep-smallest decides. One cell at
727
+ 640×360 with 4,096 lights differs at the cap; R3.1 traces that to subgroup lane order in the A2-shaped
728
+ compaction, not codegen. Walking a list gives the same sets as compacting it. The two consumer read paths agree to within
729
+ summation order (≤ 3e-6).
730
+
731
+ ### 1.1 Prepass (owned by the assignment; what it buys)
732
+
733
+ | variant | dispatches | what it does | cost (4090 / iGPU) |
734
+ |---|---|---|---|
735
+ | **unsorted** (the cull's own order) | 1 | per culled entry: one database read, a view-space record, a packed tile rect + slice range | 1–3 µs / 8–27 µs |
736
+ | **id-sorted** | 3 | per-type visibility bits (mark), one-workgroup ordered compaction, then the same records in (type, id) order | +2–4 µs / +3–25 µs over unsorted |
737
+
738
+ **What sorting buys:**
739
+
740
+ - keep-smallest falls out as "the first CAP hits per type";
741
+ - the order within a cell is deterministic (today the order follows the cull's `atomicAdd`);
742
+ - types are grouped, so there are fewer divergent branches.
743
+
744
+ Without sorting, keep-smallest is still exact (§3.3) but costs a walk on overflow, and the order stays the
745
+ cull's. Measured on the 4090: sorted H vs unsorted H is +5 µs at ≤1,024 lights and −72 µs at 640×360 with
746
+ 4,096 (163 vs 235 µs). That is fork F3.
747
+
748
+ **One workgroup for the compaction suffices** because 256 threads × 64 bits covers 16,384 lights, which is
749
+ the cull list's own limit (16,383).
750
+
751
+ ### 1.2 H: 2D tiles first, then the 24 slices (as specified)
752
+
753
+ **Stage 1, tile bitmask over the light list:**
754
+
755
+ - **Small set (L ≤ 1,024, read on the device):** inside the stage-2 workgroup, lane *w* tests lights
756
+ 32w…32w+31 against its tile. The tile's whole mask is one register per lane. There is no mask in memory
757
+ and no extra pass.
758
+ - **Above 1,024:** a separate gather pass in the structural session's BT form. One thread per (tile, word)
759
+ runs 32 rect tests and writes the whole word, with no atomics. Its dispatch is only encoded when the
760
+ CPU-known light count exceeds 1,024. Its threads leave when the device count says the small path runs.
761
+
762
+ **Stage 2:** one 32-thread workgroup per tile, lane *z* owns cell (tile, z).
763
+
764
+ 1. Per chunk of 32 words, the tile reserves **one pool block** (one global atomic per tile and chunk). Its
765
+ size is the sum of the survivors' slice extents.
766
+ 2. All lanes walk the survivors in list order.
767
+ 3. A lane whose cell passes the precise test links a node at block + survivor prefix + (z − z0), and
768
+ prepends it to its own per-type head.
769
+
770
+ No head atomics are needed, because one lane owns one cell. About 5% of reserved nodes end up as holes (a
771
+ cell in the slice range that fails the precise test).
772
+
773
+ **H2 (variant):** survivors are listed in workgroup memory; the lanes precise-test them in parallel into a
774
+ 24-bit slice mask each; then lane *z* walks the masks. Allocation is exact.
775
+
776
+ **O():**
777
+
778
+ | stage | cost |
779
+ |---|---|
780
+ | stage 1 | O(tiles × L) rect tests, 32 per thread |
781
+ | stage 2 | O(Σ over tiles of survivors) serial walk steps per tile + O(hits) node writes |
782
+ | zero lights | O(cells) head writes (8 + 4 B/cell) + one prepass dispatch |
783
+
784
+ ### 1.3 G: the coarse unit is a 3D block (A2's shape), small set and scalable path
785
+
786
+ **Coarse unit:** the 4×4×4 workgroup.
787
+
788
+ **Small set (L ≤ 1,024):** per chunk of 64 lights, thread *i* box-tests light *i* against the block. The
789
+ survivors are compacted in order into workgroup memory (subgroup exclusive add plus per-subgroup offsets).
790
+ The per-chunk survivor bits are the block's mask held two words at a time in the lanes, and never written.
791
+
792
+ **Scalable path:**
793
+
794
+ 1. One workgroup per light (direct dispatch over the CPU-known count) ORs the light's bit into every block
795
+ its cell box covers. That is light-centric, O(Σ blocks per light).
796
+ 2. The block masks are cleared first: O(blocks × W).
797
+ 3. The fine pass reads its block's words two at a time and skips empty pairs with one uniform load.
798
+
799
+ The round-1 bench called this coarse-mask scatter "A3". A gather-built coarse mask (BT at block level) was
800
+ measured and **rejected**: it repeats exactly the O(blocks × L) box tests the small path does. On the iGPU
801
+ that is 0.99 ms at 1898×982 and 4.3 ms at 4K with 4,096 lights.
802
+
803
+ **Fine stage, per cell, over its block's survivors:** box test, then the precise test (A2's tightness:
804
+ 6-plane sphere, cone vs the cell's bounding sphere, unbounded last slice in XY only).
805
+
806
+ - **Count-then-write (`G ctw`):** sweep 1 counts per type, capped. One subgroup-aggregated allocation,
807
+ then sweep 2 writes today's `{counts, offset}` + list. Points come before spots and the order is
808
+ ascending id.
809
+ - **Linked list (`G list`):** one sweep. One pool reservation per block and chunk, sized by the survivors'
810
+ box ∩ block cell counts. Each survivor owns a sub-block at an in-order prefix, so the node is
811
+ base + prefix + the cell's index inside the survivor's box.
812
+
813
+ **O():**
814
+
815
+ | stage | small set | scalable path |
816
+ |---|---|---|
817
+ | coarse | O(blocks × L) box tests, in-workgroup, L/64 chunks per thread | O(Σ blocks per light) `atomicOr` + O(blocks × W) clear |
818
+ | fine | O(cells × survivors per block) precise tests + O(hits) writes | same; ×2 sweeps for count-then-write |
819
+ | zero lights | O(cells) metadata write + prepass dispatches | same |
820
+
821
+ ## 2. Measured
822
+
823
+ ### 2.1 Assignment (p10)
824
+
825
+ **RTX 4090:**
826
+
827
+ | config | A0 today | A2 | H | H + compaction | G ctw (1,024 switch) | G ctw (mask always) | G list | G list (mask always) | G list + compaction | floor |
828
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
829
+ | 640×360, 0 | 3.1 | 4.1 | 2.0 | 4.1 | 4.1 | — | 4.1 | — | 6.1 | 1.0 |
830
+ | 640×360, 16 | 11.3 | 9.2 | 7.2 | 9.2 | 9.2 | 12.3 | 8.2 | 11.3 | 9.9 | 1.0 |
831
+ | 640×360, 1,024 | 489.5 | 74.8 | 43.0 | 53.3 | 74.8 | 85.0 | 59.4 | 62.5 | 68.6 | 1.0 |
832
+ | 640×360, 4,096 | 2.16 ms | 303.1 | 235.5 | 269.3 | 329.7 | 340.0 | 229.4 | 227.3 | 261.1 | 1.0 |
833
+ | 1898×982, 0 | 32.8 | 5.1 | 4.1 | 6.1 | 5.1 | — | 5.1 | — | 6.1 | 1.0 |
834
+ | 1898×982, 16 | 41.0 | 8.2 | 8.2 | 10.2 | 8.2 | 11.3 | 8.2 | 10.2 | 10.2 | 1.0 |
835
+ | 1898×982, 1,024 | 734.2 | 56.3 | 35.8 | 47.1 | 57.3 | 63.5 | 46.1 | 50.2 | 56.3 | 1.0 |
836
+ | 1898×982, 4,096 | 3.38 ms | 221.2 | 138.2 | 180.2 | 241.7 | 244.7 | 171.0 | 169.0 | 207.9 | 1.0 |
837
+ | 4K, 0 | 206.8 | 6.1 | 13.3 | 16.1 | 6.1 | — | 6.1 | — | 9.2 | 2.0 |
838
+ | 4K, 16 | 217.1 | 10.2 | 19.5 | 22.5 | 10.2 | 11.3 | 10.2 | 11.3 | 12.3 | 2.0 |
839
+ | 4K, 1,024 | 2.52 ms | 57.3 | 102.4 | 133.1 | 59.4 | 62.5 | 47.1 | 49.1 | 72.7 | 2.0 |
840
+ | 4K, 4,096 | 10.77 ms | 236.5 | 436.2 | 562.2 | 255.0 | 256.0 | 176.1 | 174.1 | 285.7 | 2.0 |
841
+
842
+ **AMD iGPU:**
843
+
844
+ | config | A0 today | A2 | H | H + compaction | G ctw (1,024 switch) | G ctw (mask always) | G list | G list (mask always) | G list + compaction | floor |
845
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
846
+ | 640×360, 0 | 105.6 | 4.9 | 6.5 | 9.0 | 5.2 | — | 4.4 | — | 6.7 | 1.2 |
847
+ | 640×360, 16 | 124.6 | 13.4 | 24.8 | 27.2 | 14.1 | 13.5 | 11.9 | 11.9 | 14.4 | 1.2 |
848
+ | 640×360, 1,024 | 8.11 ms | 117.1 | 253.5 | 314.5 | 121.3 | 123.8 | 91.0 | 100.0 | 125.4 | 1.2 |
849
+ | 640×360, 4,096 | 36.23 ms | 495.2 | 1.50 ms | 1.85 ms | 528.4 | 531.0 | 383.2 | 378.3 | 641.7 | 1.2 |
850
+ | 1898×982, 0 | 953.1 | 21.0 | 51.0 | 72.3 | 22.2 | — | 17.7 | — | 40.0 | 9.2 |
851
+ | 1898×982, 16 | 959.0 | 69.6 | 157.0 | 179.3 | 73.7 | 61.4 | 60.2 | 50.0 | 83.6 | 9.4 |
852
+ | 1898×982, 1,024 | 60.61 ms | 618.2 | 1.43 ms | 2.13 ms | 638.7 | 483.0 | 479.8 | 354.0 | 859.6 | 9.3 |
853
+ | 1898×982, 4,096 | 272.0 ms | 2.65 ms | 8.62 ms | 11.84 ms | 2.21 ms | 2.13 ms | 1.53 ms | 1.46 ms | 3.69 ms | 9.3 |
854
+ | 4K, 0 | 3.64 ms | 76.6 | 222.1 | 304.0 | 80.9 | — | 61.0 | — | 144.7 | 28.4 |
855
+ | 4K, 16 | 4.01 ms | 270.7 | 668.8 | 760.1 | 288.8 | 229.7 | 233.3 | 181.6 | 323.3 | 30.7 |
856
+ | 4K, 1,024 | 256.2 ms | 2.43 ms | 6.08 ms | 9.28 ms | 2.51 ms | 1.74 ms | 1.89 ms | 1.24 ms | 3.95 ms | 29.7 |
857
+ | 4K, 4,096 | — ¹ | 10.33 ms | 36.0 ms | 50.4 ms | 8.33 ms | 8.06 ms | 5.88 ms | 5.63 ms | 15.34 ms | 28.8 |
858
+
859
+ All values are µs unless marked ms. ¹ Not run: a single dispatch would come too close to the 2 s TDR.
860
+
861
+ - At zero lights, the "mask always" columns equal the switch columns (W = 0).
862
+ - The "mask always" columns are a separate paired run (switch vs always, the same four arms interleaved).
863
+ Within that run, the switch arms read within 3% of the main table.
864
+
865
+ ### 2.2 Where the time goes (per pass, p10, 1,024 lights)
866
+
867
+ | | 4090 1898×982 | 4090 4K | iGPU 1898×982 | iGPU 4K |
868
+ |---|---:|---:|---:|---:|
869
+ | prepass, sorted: 3 passes | 6.1 | 7.1 | 20.8 | 24.5 |
870
+ | H walk (stage 2; small-set stage 1 inside) | 33.8 | 100.4 | 1,763 | 6,042 |
871
+ | H compaction | 11.3 | 29.7 | 742 | 3,126 |
872
+ | G fine, count-then-write | 50.2 | 53.2 | 647 | 2,521 |
873
+ | G fine, list | 39.9 | 39.9 | 479 | 1,888 |
874
+ | G list compaction | 10.2 | 25.6 | 410 | 1,711 |
875
+
876
+ At 4,096 lights the scalable coarse stage of G costs:
877
+
878
+ | | 4090 1898×982 | 4090 4K | iGPU 1898×982 | iGPU 4K |
879
+ |---|---:|---:|---:|---:|
880
+ | clear + `atomicOr` scatter | 4.1 µs | 6.1 µs | 132 µs | 612 µs |
881
+
882
+ **Why H's walk loses at 4K.** Its cost tracks Σ over tiles of survivors. That roughly triples from
883
+ 1898×982 to 4K (33.8 → 100.4 µs), while G's fine pass stays flat (50 → 53 µs), because G amortizes one
884
+ survivor iteration over 64 cells.
885
+
886
+ **What the H walker's occupancy says.** NVIDIA: 53 regs, 50% occupancy, capped by the 32-thread groups.
887
+ The 4-tiles-per-workgroup variant reaches 100% (40 regs) and gains only 4–12%, so the serial walk is the
888
+ limit.
889
+
890
+ ### 2.3 Consumers: list walked directly vs today's compacted list (stand-in shading pass, p10)
891
+
892
+ **The stand-in pass.** Full screen, a ray-cast ground plane, the cell's lights read by id from the light
893
+ database, a distance and cone falloff summed. It is not the 80-register deferred pass, so the walk's
894
+ latency would be hidden better there; that part is **unmeasured**.
895
+
896
+ | config | 4090 compacted | 4090 list walk | Δ | iGPU compacted | iGPU list walk | Δ |
897
+ |---|---:|---:|---:|---:|---:|---:|
898
+ | 640×360, 1,024 | 14.3 | 17.4 | +21% | 783 | 827 | +6% |
899
+ | 640×360, 4,096 | 44.0 | 57.3 | +30% | 2.93 ms | 3.26 ms | +11% |
900
+ | 1898×982, 1,024 | 62.5 | 67.6 | +8% | 5.17 ms | 5.50 ms | +6% |
901
+ | 1898×982, 4,096 | 199.7 | 227.3 | +14% | 19.0 ms | 24.0 ms | +26% |
902
+ | 4K, 1,024 | 257.0 | 277.5 | +8% | 23.0 ms | 27.1 ms | +18% |
903
+ | 4K, 4,096 | 839.7 | 938.0 | +12% | 84.4 ms | 107.5 ms | +27% |
904
+
905
+ At 0 and 16 lights the difference is 0 on both GPUs.
906
+
907
+ **Break-even.** The cost of each output option, with N consumer passes reading the lights:
908
+
909
+ - **count-then-write:** the assignment alone;
910
+ - **list + compaction:** the list assignment plus the compaction pass;
911
+ - **list walked directly:** the list assignment plus N × the walk penalty.
912
+
913
+ | | count-then-write | list + compaction | list walked directly |
914
+ |---|---:|---:|---:|
915
+ | 4090, 1898×982, 1,024 | 57 | 56 | 46 + N × 5 |
916
+ | iGPU, 1898×982, 1,024 (mask always) | 483 | 764 | 354 + N × 321 |
917
+ | iGPU, 4K, 1,024 (mask always) | 1,742 | 2,955 | 1,244 + N × 4,120 |
918
+
919
+ Today the lists feed:
920
+
921
+ - the deferred direct shading chunk (`chunk_shade_standard_material_direct`);
922
+ - the volumetrics irradiance and lighting builds;
923
+ - ReSTIR DI candidate generation;
924
+ - the OIT/AVBOIT raster passes;
925
+ - water.
926
+
927
+ So N ≥ 2 whenever more than one of these runs in a frame. **On the iGPU, count-then-write wins for N ≥ 1.**
928
+
929
+ ### 2.4 Registers, occupancy, scratch (NVIDIA 610.88 Vulkan; AMD 2.0.302 Vulkan, compiling Tint's own SPIR-V)
930
+
931
+ | pipeline | threads | NV regs | NV local | NV shared | Ada occupancy | AMD VGPR | AMD SGPR | AMD scratch | AMD LDS |
932
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|---:|
933
+ | A0 today | 64 | 72 | 1,024 | 1,792 | 58% | 72 | 48 | 1,344 | 0 |
934
+ | A2 | 64 | 48 | 0 | 520 | 83% | 41 | 68 | 0 | 1,024 |
935
+ | **G ctw (fine)** | 64 | 48 | 0 | 528 | 83% | 42 | 76 | 0 | 1,024 |
936
+ | **G list (fine)** | 64 | 48 | 0 | 1,044 | 83% | 42 | 86 | 0 | 1,536 |
937
+ | G coarse scatter (`A3_scatter`) / clear | 64 / 256 | 30 / 16 | 0 | 0 | 100% | 10 / 3 | 29 / 12 | 0 | 0 |
938
+ | G coarse gather (rejected) | 64 | 20 | 0 | 0 | 100% | 12 | 19 | 0 | 0 |
939
+ | H prep (unsorted) | 64 | 27 | 0 | 0 | 100% | 30 | 28 | 0 | 0 |
940
+ | H BT (stage 1, large) | 64 | 16 | 0 | 0 | 100% | 35 | 12 | 0 | 0 |
941
+ | H walk (stage 2) | 32 | 53 | 0 | 140 | 50% | ² | ² | ² | ² |
942
+ | H walk, 4 tiles per workgroup | 128 | 40 | 0 | 548 | 100% | ² | ² | ² | ² |
943
+ | H2 walk (survivor-parallel) | 32 | 55 | 0 | 9,872 | 19% | ² | ² | ² | ² |
944
+ | compaction (UE shape) | 64 | 18 | 0 | 0 | 100% | 17 | 24 | 0 | 0 |
945
+ | consumer, compacted / list walk | 64 | 32 / 32 | 0 | 0 | 100% | 21 / 20 | 40 / 40 | 0 | 0 |
946
+ | sorted prepass: mark / compact / lights | 64 / 256 / 64 | 16 / 20 / 27 | 0 | 0 / 512 / 0 | 100% | 3 / 18 / 30 | — | 0 | 0 / 512 / 0 |
947
+
948
+ ² My offline `vkstats.py` route failed to compile the H walkers on the AMD driver. That is a tooling result
949
+ and says nothing about what ships; Chrome runs them on that iGPU, which is where the timings come from. No
950
+ figures, no prediction.
951
+
952
+ **Every new pipeline: 0 scratch, 0 local memory.**
953
+
954
+ ## 3. The linked list: semantics
955
+
956
+ ### 3.1 Layout
957
+
958
+ - Per cell, two heads (point, spot): 8 B.
959
+ - Per cell, a count word, which only the compaction reads.
960
+ - A node pool of `vec2u(light id, next)`.
961
+
962
+ **Memory.** Pool demand was 1.05× the hit count, the holes being the precise-test rejections inside a
963
+ reserved box. That fits inside today's `cluster_data` budget, about 64.5 words per cell:
964
+
965
+ | config | demand (nodes) | capacity in today's bytes (nodes) |
966
+ |---|---:|---:|
967
+ | 1898×982, 4,096 lights | 798,852 | 1,439,640 |
968
+ | 640×360, 4,096 lights | 123,685 | 185,760 |
969
+ | 4K, 4,096 lights | 3,517,641 | 6,315,840 |
970
+
971
+ ### 3.2 Determinism
972
+
973
+ **The set:**
974
+
975
+ - Exact, keep-smallest per type, every frame, in both the sorted and the unsorted builds (§3.3).
976
+ - This assumes **no pool overflow.** On overflow, the reservations past capacity are dropped, and which
977
+ tiles or blocks lose depends on the order of the reservation atomics. That is non-deterministic, the
978
+ same class as today's `cluster_data` truncation.
979
+ - It needs the same sizing feedback loop (read back the reservation counter, grow).
980
+
981
+ **The order within a cell:**
982
+
983
+ - **Sorted build:** deterministic. A lane prepends in survivor order (ascending id), so walking yields
984
+ descending id; the compaction writes it reversed, giving ascending. Node *indices* vary from frame to
985
+ frame (reservation order); the traversal order does not.
986
+ - **Unsorted build:** the cull's append order, as today.
987
+
988
+ ### 3.3 Keep-smallest
989
+
990
+ - **Sorted:** free. The first CAP hits per type are the smallest ids.
991
+ - **Unsorted:** at overflow, the lane walks its own list (≤ CAP nodes in global memory, dependent loads)
992
+ and overwrites the largest id if the newcomer is smaller. That is today's `cluster_keep_smallest`, moved
993
+ from a private array to the node pool. It costs only in overflowing cells.
994
+ - **Verified:** identical sets at 4K × 4,096, where cells sit at the cap (128 point / 75 spot).
995
+
996
+ ## 4. The small-set path and its threshold
997
+
998
+ ### 4.1 Derivation (H, as asked)
999
+
1000
+ - The stage-2 workgroup is 32 lanes: the 24 slices rounded up to a power of two. 32 is also the minimum
1001
+ subgroup width both adapters report (`subgroupMinSize` = 32 on Ada and on RDNA2).
1002
+ - One u32 per lane holds 32 lights' bits.
1003
+ - So a whole tile mask stays in registers up to **32 × 32 = 1,024 lights**. Up to that, stage 1 needs no
1004
+ memory and no pass.
1005
+ - Above it, the mask goes to memory (BT), and the walker loops ⌈W/32⌉ chunks. That is ≤ 16 at the cull
1006
+ list's 16,383 limit; doc line: none is dropped, the chunk loop is the budget.
1007
+
1008
+ ### 4.2 G has the same number
1009
+
1010
+ At ≤ 1,024 lights a block's coarse survivors for a 64-light chunk are two lane-held words, and the chunk
1011
+ loop is ≤ 16 iterations of 64 threads.
1012
+
1013
+ ### 4.3 Measured crossover between G's two coarse sources
1014
+
1015
+ | | 4090 1898×982 | 4090 4K | iGPU 1898×982 | iGPU 4K |
1016
+ |---|---:|---:|---:|---:|
1017
+ | 16 lights: box / mask | 8.2 / 11.3 | 10.2 / 11.3 | 73.3 / 61.4 | 287 / 230 |
1018
+ | 1,024 lights: box / mask | 57.3 / 63.5 | 59.4 / 62.5 | 638 / 483 | 2,512 / 1,742 |
1019
+ | 4,096 lights: box / mask | 241.7 / 244.7 | 254 / 256 | 2,228 / 2,132 | 8,480 / 8,064 |
1020
+
1021
+ (µs; count-then-write; 640×360 is within ±3% on the iGPU and favours the box path on the 4090.)
1022
+
1023
+ **Why the crossover moves:**
1024
+
1025
+ - On the iGPU, barriers and subgroup operations are expensive. The mask lets a block with no lights skip a
1026
+ chunk with one uniform load instead of a compaction round.
1027
+ - On the 4090 those are cheap, and the mask's two extra dispatches cost more.
1028
+
1029
+ So the threshold that holds the budget (1,024) is not the threshold that minimizes time, and the latter
1030
+ depends on the device.
1031
+
1032
+ ## 5. Ranked proposal
1033
+
1034
+ 1. **G, count-then-write into today's product, mask path always** (forks F1 and F2 at their
1035
+ recommendations).
1036
+ - **Passes:** id-sorted prepass, coarse clear + light scatter, fine pass: 6 direct dispatches, no
1037
+ indirect.
1038
+ - **Consumers:** unchanged.
1039
+ - **Determinism:** set and order, keep-smallest exact.
1040
+ - **Per-thread budgets:**
1041
+
1042
+ | stage | per-thread budget |
1043
+ |---|---|
1044
+ | prepass compact | 64 bits |
1045
+ | scatter | coarse blocks / 64 (≤ 48 at 4K) |
1046
+ | fine | ≤ W/2 word pairs × ≤ 64 survivors per pair |
1047
+
1048
+ - **Cost:** 4090 4–6 µs at 0 lights, 62–85 µs at 1,024 (switch: 57–75 µs). iGPU 5–81 µs at 0 lights,
1049
+ 0.12–1.74 ms at 1,024. 65–147× faster than today on the iGPU at 1,024.
1050
+ 2. **G with a linked list, walked by consumers** — only if F1 goes the other way. Fastest assignment on
1051
+ both GPUs (4090 46–59 µs, iGPU 0.10–1.24 ms at 1,024). It pays per consumer pass, which loses on the
1052
+ iGPU for any N ≥ 1.
1053
+ 3. **H (2D then slices)** — recommended only for a 4090-class device at ≤ ~2 Mpx. It loses 2–4.5× on the
1054
+ iGPU, and at 4K on the 4090. Kept in the record because it is the shape that was asked for.
1055
+
1056
+ ### Reuse map
1057
+
1058
+ | piece | existing machinery |
1059
+ |---|---|
1060
+ | sorted prepass | the bench's mark/compact; generalizes to `graph_prefix_scan_csdldf` beyond one workgroup |
1061
+ | per-light record + box | `chunk_point_light_to_aabb3`, `chunk_spot_light_to_aabb3`, `chunk_cluster_depth_to_z_slice`, `chunk_sphere_screen_extents` |
1062
+ | precise tests | `chunk_sphere_intersects_frustum` semantics, `chunk_cone_intersects_sphere` (cell sphere once per cell) |
1063
+ | subgroup allocation | `chunk_vsm_append_mover` |
1064
+ | ordered compaction | `chunk_subgroup_active_count_bits` pattern, `workgroupUniformLoad` |
1065
+ | tile / block gather (BT) | the structural session's R1 bin step, which is the rejected gather here |
1066
+ | compaction | UE 5.4 `LightGridCompactCS` (VERIFIED, round 1 §2.1) |
1067
+ | decals | `shader_cluster_assign_decals` takes the same fine pass with keep-largest; not built |
1068
+
1069
+ ## 6. Forks for Alex
1070
+
1071
+ - **F1. Output: count-then-write into today's `{counts, offset}`, or a linked list?**
1072
+ - The list's single sweep is 20–31% cheaper to build.
1073
+ - Compacting it UE-style costs more than that on both GPUs.
1074
+ - Walking it directly costs +6–30% in every consumer pass.
1075
+ - *Recommendation:* **count-then-write.** It has no per-thread array, which was the thing to get rid of:
1076
+ counts live in registers and survivors in workgroup memory. The list only wins on a 4090-class device
1077
+ with one or two consumers.
1078
+ - **F2. Small-set switch at 1,024 (derived) or the mask path always?** *Recommendation:* **mask always.**
1079
+ It wins at every count on the modest GPU (−17% to −31% at 1898×982 and 4K). It costs the 4090 ≤ 9 µs
1080
+ below 1,024. The derived threshold stays the loop budget, not a speed switch.
1081
+ - **F3. Sort in the prepass (+2 dispatches) or keep the cull's order?** *Recommendation:* **sort.** For
1082
+ 2–4 µs (4090) and 3–25 µs (iGPU) it buys keep-smallest for free, a deterministic order, and type
1083
+ grouping. Without it, keep-smallest needs the overflow walk of §3.3.
1084
+ - **F4. The 2D-first stage at 32 px (H) against the 3D block (G).** *Recommendation:* **G.** The data in
1085
+ §2.1 and §2.2 is the reason. H's 2D binning does reduce the culling dimension, but its walk then repeats
1086
+ every light once per tile.
1087
+
1088
+ ## 7. Method notes and data
1089
+
1090
+ - **Bench:** `H:/tmp/clusteralgo/bench/` (scratchpad copy):
1091
+ - `h_arms.js`: H, H2, G, the compaction and the consumers;
1092
+ - `arms.js`, `bench.js`;
1093
+ - jobs `job_hcheck.js` (correctness) and `job_htime.js` (timing);
1094
+ - results `final_nv3.json`, `final_amd2.json`, `thr_nv.json`, `thr_amd.json`;
1095
+ - SPIR-V and driver statistics: `H:/tmp/clusteralgo/hdumps`, `hvkstats.json`.
1096
+ - **Earlier 4090 runs this round** were taken under 50–70% foreign GPU load and showed contamination. They
1097
+ are superseded by the mirrored run quoted here.
1098
+ - **Not measured:**
1099
+ - the real deferred pass's sensitivity to the list walk;
1100
+ - decals;
1101
+ - a GPU between the two tested.