@woosh/meep-engine 3.47.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 (1770) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +12 -2
  3. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  4. package/editor/particles/effect/ParticleReferenceSimulation.js +30 -4
  5. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  6. package/editor/view/particles/effect/ParticleGraphEditorView.js +3 -1
  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/async/WORKER_SYSTEM_PLAN.md +27 -11
  77. package/src/engine/ecs/fow/FogOfWarVisibilityPredicate.d.ts.map +1 -1
  78. package/src/engine/ecs/fow/FogOfWarVisibilityPredicate.js +1 -3
  79. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  80. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +13 -0
  81. package/src/engine/ecs/terrain/util/obtainTerrain.d.ts.map +1 -1
  82. package/src/engine/ecs/terrain/util/obtainTerrain.js +5 -0
  83. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +2 -2
  84. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -1
  85. package/src/engine/graphics/ecs/particles/ParticleEffect.js +7 -7
  86. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +8 -0
  87. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -1
  88. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +11 -3
  89. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts +26 -0
  90. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts.map +1 -0
  91. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.js +91 -0
  92. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +8 -21
  93. package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -1
  94. package/src/engine/graphics/ecs/water/WaterWaves.js +8 -31
  95. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts +4 -0
  96. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -1
  97. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +5 -5
  98. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_1_2.d.ts +9 -0
  99. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_1_2.d.ts.map +1 -0
  100. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_1_2.js +19 -0
  101. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +21 -0
  102. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -1
  103. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +78 -0
  104. package/src/engine/graphics3/GPUFluidSystem.d.ts +266 -0
  105. package/src/engine/graphics3/GPUFluidSystem.d.ts.map +1 -0
  106. package/src/engine/graphics3/GPUFluidSystem.js +1613 -0
  107. package/src/engine/graphics3/GPUParticleEmitterSystem.js +2 -2
  108. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  109. package/src/engine/graphics3/GraphicsEngine.js +8 -1
  110. package/src/engine/graphics3/ParticipatingMedia.d.ts +90 -1
  111. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -1
  112. package/src/engine/graphics3/ParticipatingMedia.js +145 -5
  113. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts +6 -2
  114. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts.map +1 -1
  115. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.js +29 -4
  116. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.d.ts +10 -0
  117. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.d.ts.map +1 -0
  118. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.js +38 -0
  119. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +32 -22
  120. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -1
  121. package/src/engine/graphics3/ParticipatingMediaSystem.js +236 -45
  122. package/src/engine/graphics3/WaterSystem.d.ts +9 -2
  123. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  124. package/src/engine/graphics3/WaterSystem.js +53 -15
  125. package/src/engine/network/NetworkSession.d.ts +16 -5
  126. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  127. package/src/engine/network/NetworkSession.js +104 -7
  128. package/src/engine/network/README.md +27 -1
  129. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +40 -18
  130. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  131. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +180 -190
  132. package/src/engine/network/replication/Replicator.d.ts +15 -4
  133. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  134. package/src/engine/network/replication/Replicator.js +50 -16
  135. package/src/engine/network/state/RecordArrivalRing.d.ts +57 -0
  136. package/src/engine/network/state/RecordArrivalRing.d.ts.map +1 -0
  137. package/src/engine/network/state/RecordArrivalRing.js +144 -0
  138. package/src/engine/physics/cloth/MEASUREMENTS.md +393 -0
  139. package/src/engine/physics/cloth/PLAN.md +106 -7
  140. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -1
  141. package/src/engine/physics/cloth/collider/ClothColliderKind.js +14 -7
  142. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +19 -5
  143. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -1
  144. package/src/engine/physics/cloth/collider/ClothColliderRecord.js +28 -5
  145. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +3 -2
  146. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
  147. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +26 -108
  148. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +6 -5
  149. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  150. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +18 -28
  151. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +6 -21
  152. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  153. package/src/engine/physics/cloth/ecs/ClothInstance.js +6 -22
  154. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +5 -3
  155. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  156. package/src/engine/physics/cloth/ecs/ClothSystem.js +10 -3
  157. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +38 -28
  158. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  159. package/src/engine/physics/cloth/ecs/ClothWorld.js +140 -43
  160. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +2 -1
  161. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  162. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +6 -1
  163. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  164. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +20 -10
  165. package/src/engine/physics/cloth/playground/README.md +8 -4
  166. package/src/engine/physics/cloth/playground/collide.html +5 -3
  167. package/src/engine/physics/cloth/playground/collide_main.js +14 -13
  168. package/src/engine/physics/cloth/playground/wind.html +4 -4
  169. package/src/engine/physics/cloth/playground/wind_build.d.ts +3 -2
  170. package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -1
  171. package/src/engine/physics/cloth/playground/wind_build.js +4 -3
  172. package/src/engine/physics/cloth/playground/wind_main.js +58 -19
  173. package/src/engine/physics/cloth/solver/ClothState.d.ts +30 -2
  174. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  175. package/src/engine/physics/cloth/solver/ClothState.js +62 -4
  176. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +11 -3
  177. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  178. package/src/engine/physics/cloth/solver/cloth_self_find.js +52 -11
  179. package/src/engine/physics/cloth/solver/cloth_self_radius.d.ts +42 -0
  180. package/src/engine/physics/cloth/solver/cloth_self_radius.d.ts.map +1 -0
  181. package/src/engine/physics/cloth/solver/cloth_self_radius.js +64 -0
  182. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +99 -24
  183. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  184. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +102 -25
  185. package/src/engine/physics/cloth/solver/cloth_step.d.ts +5 -1
  186. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  187. package/src/engine/physics/cloth/solver/cloth_step.js +13 -3
  188. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +0 -1
  189. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  190. package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -14
  191. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +23 -4
  192. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  193. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +36 -8
  194. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  195. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +4 -2
  196. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +36 -35
  197. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -1
  198. package/src/engine/physics/cloth/wind/AbstractClothWind.js +36 -35
  199. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +46 -25
  200. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  201. package/src/engine/physics/cloth/wind/ClothFluidWind.js +70 -30
  202. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts +96 -0
  203. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts.map +1 -0
  204. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.js +441 -0
  205. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +9 -7
  206. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  207. package/src/engine/physics/cloth/wind/cloth_sample_air.js +9 -7
  208. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +1 -1
  209. package/src/engine/physics/ecs/PhysicsSystem.d.ts +1 -1
  210. package/src/engine/physics/fluid/FluidAtmosphere.d.ts +80 -0
  211. package/src/engine/physics/fluid/FluidAtmosphere.d.ts.map +1 -0
  212. package/src/engine/physics/fluid/FluidAtmosphere.js +78 -0
  213. package/src/engine/physics/fluid/FluidField.d.ts +14 -2
  214. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  215. package/src/engine/physics/fluid/FluidField.js +26 -6
  216. package/src/engine/physics/fluid/FluidSimulator.d.ts +5 -1
  217. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  218. package/src/engine/physics/fluid/FluidSimulator.js +13 -2
  219. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +1382 -0
  220. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts +10 -4
  221. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts.map +1 -1
  222. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +13 -4
  223. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts +47 -0
  224. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts.map +1 -0
  225. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.js +72 -0
  226. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts +67 -0
  227. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts.map +1 -0
  228. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.js +307 -0
  229. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +6 -6
  230. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
  231. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +24 -13
  232. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -1
  233. package/src/engine/physics/fluid/ecs/FluidSystem.js +79 -15
  234. package/src/engine/physics/fluid/ecs/FluidWorkerCore.d.ts.map +1 -1
  235. package/src/engine/physics/fluid/ecs/FluidWorkerCore.js +17 -5
  236. package/src/engine/physics/fluid/ecs/GPUFluidComponent.d.ts +82 -0
  237. package/src/engine/physics/fluid/ecs/GPUFluidComponent.d.ts.map +1 -0
  238. package/src/engine/physics/fluid/ecs/GPUFluidComponent.js +124 -0
  239. package/src/engine/physics/fluid/ecs/GPUFluidComponentSerializationAdapter.d.ts +30 -0
  240. package/src/engine/physics/fluid/ecs/GPUFluidComponentSerializationAdapter.d.ts.map +1 -0
  241. package/src/engine/physics/fluid/ecs/GPUFluidComponentSerializationAdapter.js +51 -0
  242. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts +19 -10
  243. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts.map +1 -1
  244. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +64 -14
  245. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.d.ts +4 -1
  246. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.d.ts.map +1 -1
  247. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.js +9 -1
  248. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.d.ts +1 -0
  249. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.d.ts.map +1 -1
  250. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +9 -7
  251. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.d.ts +5 -3
  252. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.d.ts.map +1 -1
  253. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.js +5 -3
  254. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.d.ts +20 -2
  255. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.d.ts.map +1 -1
  256. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.js +34 -6
  257. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +46 -3
  258. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts.map +1 -1
  259. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +53 -3
  260. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +73 -13
  261. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  262. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +207 -88
  263. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts +35 -0
  264. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts.map +1 -0
  265. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.js +72 -0
  266. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts +34 -10
  267. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -1
  268. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +139 -150
  269. package/src/engine/physics/fluid/effector/ImpulseFluidEffectorSerializationAdapter.d.ts +26 -0
  270. package/src/engine/physics/fluid/effector/ImpulseFluidEffectorSerializationAdapter.d.ts.map +1 -0
  271. package/src/engine/physics/fluid/effector/ImpulseFluidEffectorSerializationAdapter.js +51 -0
  272. package/src/engine/physics/fluid/effector/VortexFluidEffector.d.ts +55 -0
  273. package/src/engine/physics/fluid/effector/VortexFluidEffector.d.ts.map +1 -0
  274. package/src/engine/physics/fluid/effector/VortexFluidEffector.js +255 -0
  275. package/src/engine/physics/fluid/effector/VortexFluidEffectorSerializationAdapter.d.ts +25 -0
  276. package/src/engine/physics/fluid/effector/VortexFluidEffectorSerializationAdapter.d.ts.map +1 -0
  277. package/src/engine/physics/fluid/effector/VortexFluidEffectorSerializationAdapter.js +52 -0
  278. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +22 -20
  279. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  280. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +181 -185
  281. package/src/engine/physics/fluid/effector/WakeFluidEffectorSerializationAdapter.d.ts +31 -0
  282. package/src/engine/physics/fluid/effector/WakeFluidEffectorSerializationAdapter.d.ts.map +1 -0
  283. package/src/engine/physics/fluid/effector/WakeFluidEffectorSerializationAdapter.js +56 -0
  284. package/src/engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.d.ts +52 -0
  285. package/src/engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.d.ts.map +1 -0
  286. package/src/engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.js +68 -0
  287. package/src/engine/physics/fluid/effector/record/FluidEffectorRecordKind.d.ts +10 -0
  288. package/src/engine/physics/fluid/effector/record/FluidEffectorRecordKind.d.ts.map +1 -0
  289. package/src/engine/physics/fluid/effector/record/FluidEffectorRecordKind.js +31 -0
  290. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_deposit.d.ts +25 -0
  291. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_deposit.d.ts.map +1 -0
  292. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_deposit.js +105 -0
  293. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.d.ts +17 -0
  294. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.d.ts.map +1 -0
  295. package/src/engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.js +47 -0
  296. package/src/engine/physics/fluid/effector/record/fluid_effector_record_create.d.ts +54 -0
  297. package/src/engine/physics/fluid/effector/record/fluid_effector_record_create.d.ts.map +1 -0
  298. package/src/engine/physics/fluid/effector/record/fluid_effector_record_create.js +34 -0
  299. package/src/engine/physics/fluid/effector/record/fluid_effector_record_deposit.d.ts +98 -0
  300. package/src/engine/physics/fluid/effector/record/fluid_effector_record_deposit.d.ts.map +1 -0
  301. package/src/engine/physics/fluid/effector/record/fluid_effector_record_deposit.js +409 -0
  302. package/src/engine/physics/fluid/effector/record/fluid_effector_record_resolve.d.ts +25 -0
  303. package/src/engine/physics/fluid/effector/record/fluid_effector_record_resolve.d.ts.map +1 -0
  304. package/src/engine/physics/fluid/effector/record/fluid_effector_record_resolve.js +78 -0
  305. package/src/engine/physics/fluid/effector/record/fluid_record_apply.d.ts +27 -0
  306. package/src/engine/physics/fluid/effector/record/fluid_record_apply.d.ts.map +1 -0
  307. package/src/engine/physics/fluid/effector/record/fluid_record_apply.js +151 -0
  308. package/src/engine/physics/fluid/fluid_apply_atmosphere.d.ts +42 -0
  309. package/src/engine/physics/fluid/fluid_apply_atmosphere.d.ts.map +1 -0
  310. package/src/engine/physics/fluid/fluid_apply_atmosphere.js +148 -0
  311. package/src/engine/physics/fluid/fluid_atmosphere_to_grid.d.ts +16 -0
  312. package/src/engine/physics/fluid/fluid_atmosphere_to_grid.d.ts.map +1 -0
  313. package/src/engine/physics/fluid/fluid_atmosphere_to_grid.js +47 -0
  314. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts +32 -0
  315. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts.map +1 -0
  316. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js +50 -0
  317. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +24 -0
  318. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -0
  319. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +61 -0
  320. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts +58 -0
  321. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts.map +1 -0
  322. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.js +35 -0
  323. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_evaluate.d.ts +34 -0
  324. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_evaluate.d.ts.map +1 -0
  325. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_evaluate.js +90 -0
  326. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_extent.d.ts +17 -0
  327. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_extent.d.ts.map +1 -0
  328. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_extent.js +44 -0
  329. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts +98 -0
  330. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts.map +1 -0
  331. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.js +281 -0
  332. package/src/engine/physics/fluid/prototype.js +2 -0
  333. package/src/engine/physics/narrowphase/rigid_subject_pose.d.ts.map +1 -1
  334. package/src/engine/physics/narrowphase/rigid_subject_pose.js +3 -43
  335. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +4 -4
  336. package/src/shade/assets/textures/split_sum.bin +0 -0
  337. package/src/shade/device/ShadeGPUCommandContext.d.ts +20 -0
  338. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  339. package/src/shade/device/ShadeGPUCommandContext.js +25 -8
  340. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts +6 -2
  341. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts.map +1 -1
  342. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.js +7 -3
  343. package/src/shade/device/mock/SoftwareGPUDevice.d.ts +15 -0
  344. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  345. package/src/shade/device/mock/SoftwareGPUDevice.js +21 -0
  346. package/src/shade/device/pipeline/ComputePipelineManager.d.ts +20 -0
  347. package/src/shade/device/pipeline/ComputePipelineManager.d.ts.map +1 -1
  348. package/src/shade/device/pipeline/ComputePipelineManager.js +80 -6
  349. package/src/shade/device/pipeline/PipelineEnquiry.d.ts +52 -0
  350. package/src/shade/device/pipeline/PipelineEnquiry.d.ts.map +1 -0
  351. package/src/shade/device/pipeline/PipelineEnquiry.js +63 -0
  352. package/src/shade/device/pipeline/RenderPipelineManager.d.ts +21 -0
  353. package/src/shade/device/pipeline/RenderPipelineManager.d.ts.map +1 -1
  354. package/src/shade/device/pipeline/RenderPipelineManager.js +84 -4
  355. package/src/shade/playground/avboit/main.d.ts.map +1 -1
  356. package/src/shade/playground/avboit/main.js +9 -6
  357. package/src/shade/playground/contact_shadows/ContactShadowLab.d.ts +137 -0
  358. package/src/shade/playground/contact_shadows/ContactShadowLab.d.ts.map +1 -0
  359. package/src/shade/playground/contact_shadows/ContactShadowLab.js +654 -0
  360. package/src/shade/playground/contact_shadows/README.md +126 -0
  361. package/src/shade/playground/contact_shadows/index.html +191 -0
  362. package/src/shade/playground/contact_shadows/main.d.ts +2 -0
  363. package/src/shade/playground/contact_shadows/main.d.ts.map +1 -0
  364. package/src/shade/playground/contact_shadows/main.js +888 -0
  365. package/src/shade/playground/contact_shadows/scenes.d.ts +48 -0
  366. package/src/shade/playground/contact_shadows/scenes.d.ts.map +1 -0
  367. package/src/shade/playground/contact_shadows/scenes.js +620 -0
  368. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.d.ts +36 -0
  369. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.d.ts.map +1 -0
  370. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.js +245 -0
  371. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.d.ts +15 -0
  372. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.d.ts.map +1 -0
  373. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.js +120 -0
  374. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.d.ts +55 -0
  375. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.d.ts.map +1 -0
  376. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.js +216 -0
  377. package/src/shade/playground/contact_shadows/shader_contact_lab_view.d.ts +20 -0
  378. package/src/shade/playground/contact_shadows/shader_contact_lab_view.d.ts.map +1 -0
  379. package/src/shade/playground/contact_shadows/shader_contact_lab_view.js +114 -0
  380. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.d.ts +11 -0
  381. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.d.ts.map +1 -0
  382. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.js +90 -0
  383. package/src/shade/playground/contact_shadows/textures.d.ts +16 -0
  384. package/src/shade/playground/contact_shadows/textures.d.ts.map +1 -0
  385. package/src/shade/playground/contact_shadows/textures.js +123 -0
  386. package/src/shade/playground/particle_ecs/README.md +21 -1
  387. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +10 -0
  388. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -1
  389. package/src/shade/playground/particle_ecs/bonfire_effects.js +10 -0
  390. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts +48 -0
  391. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts.map +1 -0
  392. package/src/shade/playground/particle_ecs/bonfire_wind.js +83 -0
  393. package/src/shade/playground/particle_ecs/effects/embers.json +1695 -1633
  394. package/src/shade/playground/particle_ecs/effects/flame.json +1994 -1881
  395. package/src/shade/playground/particle_ecs/effects/smoke.json +113 -15
  396. package/src/shade/playground/particle_ecs/effects/soot.json +214 -145
  397. package/src/shade/playground/particle_ecs/index.html +21 -0
  398. package/src/shade/playground/particle_ecs/main.js +35 -1
  399. package/src/shade/playground/path_traced_media/main.js +12 -10
  400. package/src/shade/playground/render_submitted_frames.d.ts +20 -0
  401. package/src/shade/playground/render_submitted_frames.d.ts.map +1 -0
  402. package/src/shade/playground/render_submitted_frames.js +29 -0
  403. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  404. package/src/shade/playground/skinned_blas_refit/main.js +4 -6
  405. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
  406. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +267 -270
  407. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  408. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +3 -6
  409. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  410. package/src/shade/playground/skinned_mesh_soup/main.js +4 -5
  411. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +438 -438
  412. package/src/shade/playground/ssr_motion/README.md +24 -22
  413. package/src/shade/playground/ssr_motion/main.js +150 -149
  414. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +1 -1
  415. package/src/shade/playground/ssr_reprojection/main.js +5 -3
  416. package/src/shade/playground/ssr_variance/capture.js +1 -1
  417. package/src/shade/playground/ssr_variance/main.js +247 -246
  418. package/src/shade/playground/submit_frame.d.ts +25 -0
  419. package/src/shade/playground/submit_frame.d.ts.map +1 -0
  420. package/src/shade/playground/submit_frame.js +36 -0
  421. package/src/shade/playground/tonemap_sdr/README.md +90 -0
  422. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts +105 -0
  423. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts.map +1 -0
  424. package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +389 -0
  425. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.d.ts +32 -0
  426. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.d.ts.map +1 -0
  427. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.js +104 -0
  428. package/src/shade/playground/tonemap_sdr/index.html +90 -0
  429. package/src/shade/playground/tonemap_sdr/main.d.ts +2 -0
  430. package/src/shade/playground/tonemap_sdr/main.d.ts.map +1 -0
  431. package/src/shade/playground/tonemap_sdr/main.js +306 -0
  432. package/src/shade/playground/tonemap_sdr/scenes.d.ts +26 -0
  433. package/src/shade/playground/tonemap_sdr/scenes.d.ts.map +1 -0
  434. package/src/shade/playground/tonemap_sdr/scenes.js +404 -0
  435. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  436. package/src/shade/playground/volumetrics_froxel/main.js +91 -4
  437. package/src/shade/playground/water_refraction/README.md +30 -20
  438. package/src/shade/playground/water_refraction/index.html +1 -1
  439. package/src/shade/playground/water_refraction/main.js +19 -3
  440. package/src/shade/playground/water_refraction/world.d.ts.map +1 -1
  441. package/src/shade/playground/water_refraction/world.js +2 -1
  442. package/src/shade/playground/water_surface/README.md +15 -7
  443. package/src/shade/playground/water_surface/index.html +2 -1
  444. package/src/shade/playground/water_surface/main.js +39 -7
  445. package/src/shade/playground/water_surface/world.d.ts +2 -5
  446. package/src/shade/playground/water_surface/world.d.ts.map +1 -1
  447. package/src/shade/playground/water_surface/world.js +9 -8
  448. package/src/shade/renderer/INDIRECT_LIGHTING.d.ts +13 -0
  449. package/src/shade/renderer/INDIRECT_LIGHTING.d.ts.map +1 -0
  450. package/src/shade/renderer/INDIRECT_LIGHTING.js +14 -0
  451. package/src/shade/renderer/Renderer.d.ts +35 -3
  452. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  453. package/src/shade/renderer/Renderer.js +260 -57
  454. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSET_RESOURCES.d.ts +17 -0
  455. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSET_RESOURCES.d.ts.map +1 -0
  456. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSET_RESOURCES.js +19 -0
  457. package/src/shade/renderer/ShadeToneMappingMode.d.ts +14 -0
  458. package/src/shade/renderer/ShadeToneMappingMode.d.ts.map +1 -0
  459. package/src/shade/renderer/ShadeToneMappingMode.js +30 -0
  460. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +9 -0
  461. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  462. package/src/shade/renderer/animation/GPUAnimationManager.js +14 -0
  463. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  464. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +5 -3
  465. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +7 -0
  466. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  467. package/src/shade/renderer/buffer/table/GPUDatabase.js +19 -4
  468. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts +32 -2
  469. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts.map +1 -1
  470. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.js +231 -62
  471. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +12 -0
  472. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  473. package/src/shade/renderer/buffer/table/GPUTypedTable.js +51 -14
  474. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts +8 -0
  475. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  476. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +12 -0
  477. package/src/shade/renderer/camera/CAMERA_RESOURCE.d.ts +7 -0
  478. package/src/shade/renderer/camera/CAMERA_RESOURCE.d.ts.map +1 -0
  479. package/src/shade/renderer/camera/CAMERA_RESOURCE.js +8 -0
  480. package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
  481. package/src/shade/renderer/camera/GPUCameraContext.js +19 -8
  482. package/src/shade/renderer/deferred/GBUFFER_RESOURCES.d.ts +22 -0
  483. package/src/shade/renderer/deferred/GBUFFER_RESOURCES.d.ts.map +1 -0
  484. package/src/shade/renderer/deferred/GBUFFER_RESOURCES.js +25 -0
  485. package/src/shade/renderer/deferred/LOCAL_LIGHT_SHADING.d.ts +12 -0
  486. package/src/shade/renderer/deferred/LOCAL_LIGHT_SHADING.d.ts.map +1 -0
  487. package/src/shade/renderer/deferred/LOCAL_LIGHT_SHADING.js +13 -0
  488. package/src/shade/renderer/deferred/LocalLightShading.d.ts +10 -0
  489. package/src/shade/renderer/deferred/LocalLightShading.d.ts.map +1 -0
  490. package/src/shade/renderer/deferred/LocalLightShading.js +12 -0
  491. package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.d.ts.map +1 -1
  492. package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.js +15 -11
  493. package/src/shade/renderer/deferred/TonemapDisplaySettings.d.ts +50 -0
  494. package/src/shade/renderer/deferred/TonemapDisplaySettings.d.ts.map +1 -0
  495. package/src/shade/renderer/deferred/TonemapDisplaySettings.js +142 -0
  496. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.d.ts.map +1 -1
  497. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.js +10 -1
  498. package/src/shade/renderer/deferred/chunk_sample_volumetrics.d.ts.map +1 -1
  499. package/src/shade/renderer/deferred/chunk_sample_volumetrics.js +11 -1
  500. package/src/shade/renderer/deferred/chunk_shade_directional_lights.d.ts +1 -2
  501. package/src/shade/renderer/deferred/chunk_shade_directional_lights.d.ts.map +1 -1
  502. package/src/shade/renderer/deferred/chunk_shade_directional_lights.js +4 -2
  503. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.d.ts +10 -3
  504. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.d.ts.map +1 -1
  505. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.js +27 -5
  506. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_deferred.d.ts +16 -0
  507. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_deferred.d.ts.map +1 -0
  508. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_deferred.js +23 -0
  509. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_heavy.d.ts +3 -2
  510. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_heavy.d.ts.map +1 -1
  511. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_heavy.js +17 -16
  512. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.d.ts +3 -2
  513. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.d.ts.map +1 -1
  514. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.js +13 -2
  515. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.d.ts.map +1 -1
  516. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.js +4 -1
  517. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.d.ts.map +1 -1
  518. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.js +4 -1
  519. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.d.ts.map +1 -1
  520. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.js +7 -0
  521. package/src/shade/renderer/deferred/shader_deferred_main.d.ts +11 -6
  522. package/src/shade/renderer/deferred/shader_deferred_main.d.ts.map +1 -1
  523. package/src/shade/renderer/deferred/shader_deferred_main.js +69 -87
  524. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts +6 -0
  525. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  526. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +22 -18
  527. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts +9 -0
  528. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts.map +1 -0
  529. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.js +66 -0
  530. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts +10 -0
  531. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts.map +1 -0
  532. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.js +80 -0
  533. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts +6 -0
  534. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts.map +1 -1
  535. package/src/shade/renderer/deferred/shader_tonemap_LDR.js +27 -7
  536. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts +9 -0
  537. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts.map +1 -0
  538. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.js +71 -0
  539. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts +10 -0
  540. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts.map +1 -0
  541. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.js +76 -0
  542. package/src/shade/renderer/fluid/FluidCascadePlacement.d.ts +142 -0
  543. package/src/shade/renderer/fluid/FluidCascadePlacement.d.ts.map +1 -0
  544. package/src/shade/renderer/fluid/FluidCascadePlacement.js +349 -0
  545. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +383 -0
  546. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -0
  547. package/src/shade/renderer/fluid/GPUFluidCascade.js +1217 -0
  548. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +191 -0
  549. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -0
  550. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +463 -0
  551. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_FILL_STRUCT.d.ts +27 -0
  552. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_FILL_STRUCT.d.ts.map +1 -0
  553. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_FILL_STRUCT.js +43 -0
  554. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_GHOSTS.d.ts +31 -0
  555. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_GHOSTS.d.ts.map +1 -0
  556. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_GHOSTS.js +38 -0
  557. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts +46 -0
  558. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts.map +1 -0
  559. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.js +61 -0
  560. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts +25 -0
  561. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts.map +1 -0
  562. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.js +41 -0
  563. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts +52 -0
  564. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts.map +1 -0
  565. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.js +146 -0
  566. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts +41 -0
  567. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -0
  568. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +238 -0
  569. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.d.ts +32 -0
  570. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.d.ts.map +1 -0
  571. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.js +141 -0
  572. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts +34 -0
  573. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -0
  574. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +101 -0
  575. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts +31 -0
  576. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts.map +1 -0
  577. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.js +126 -0
  578. package/src/shade/renderer/fluid/fluid_cascade_ruler.d.ts +15 -0
  579. package/src/shade/renderer/fluid/fluid_cascade_ruler.d.ts.map +1 -0
  580. package/src/shade/renderer/fluid/fluid_cascade_ruler.js +38 -0
  581. package/src/shade/renderer/fluid/fluid_cascade_window.d.ts +41 -0
  582. package/src/shade/renderer/fluid/fluid_cascade_window.d.ts.map +1 -0
  583. package/src/shade/renderer/fluid/fluid_cascade_window.js +49 -0
  584. package/src/shade/renderer/fluid/forcing/FLUID_DATABASE_SPEC.d.ts +68 -0
  585. package/src/shade/renderer/fluid/forcing/FLUID_DATABASE_SPEC.d.ts.map +1 -0
  586. package/src/shade/renderer/fluid/forcing/FLUID_DATABASE_SPEC.js +103 -0
  587. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts +71 -0
  588. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts.map +1 -0
  589. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.js +100 -0
  590. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts +21 -0
  591. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts.map +1 -0
  592. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.js +35 -0
  593. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_EXTRACT_STRUCT.d.ts +18 -0
  594. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_EXTRACT_STRUCT.d.ts.map +1 -0
  595. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_EXTRACT_STRUCT.js +27 -0
  596. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_QUERY_STRUCT.d.ts +17 -0
  597. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_QUERY_STRUCT.d.ts.map +1 -0
  598. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_QUERY_STRUCT.js +28 -0
  599. package/src/shade/renderer/fluid/forcing/FLUID_OBSTACLE_PLANE_STRUCT.d.ts +12 -0
  600. package/src/shade/renderer/fluid/forcing/FLUID_OBSTACLE_PLANE_STRUCT.d.ts.map +1 -0
  601. package/src/shade/renderer/fluid/forcing/FLUID_OBSTACLE_PLANE_STRUCT.js +16 -0
  602. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +289 -0
  603. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -0
  604. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +1487 -0
  605. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts +32 -0
  606. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts.map +1 -0
  607. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.js +87 -0
  608. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_leaf.d.ts +28 -0
  609. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_leaf.d.ts.map +1 -0
  610. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_leaf.js +99 -0
  611. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts +29 -0
  612. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts.map +1 -0
  613. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.js +67 -0
  614. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +38 -0
  615. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -0
  616. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +287 -0
  617. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_command.d.ts +18 -0
  618. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_command.d.ts.map +1 -0
  619. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_command.js +64 -0
  620. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_extract.d.ts +22 -0
  621. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_extract.d.ts.map +1 -0
  622. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_extract.js +168 -0
  623. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_query.d.ts +31 -0
  624. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_query.d.ts.map +1 -0
  625. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_query.js +208 -0
  626. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts +35 -0
  627. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts.map +1 -0
  628. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.js +50 -0
  629. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +162 -0
  630. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -0
  631. package/src/shade/renderer/fluid/mac/FluidMacPasses.js +384 -0
  632. package/src/shade/renderer/fluid/mac/FluidMacVelocitySet.d.ts +40 -0
  633. package/src/shade/renderer/fluid/mac/FluidMacVelocitySet.d.ts.map +1 -0
  634. package/src/shade/renderer/fluid/mac/FluidMacVelocitySet.js +77 -0
  635. package/src/shade/renderer/fluid/mac/V3_MAC_LATTICE_TAP_STRUCT.d.ts +14 -0
  636. package/src/shade/renderer/fluid/mac/V3_MAC_LATTICE_TAP_STRUCT.d.ts.map +1 -0
  637. package/src/shade/renderer/fluid/mac/V3_MAC_LATTICE_TAP_STRUCT.js +19 -0
  638. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts +35 -0
  639. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts.map +1 -0
  640. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.js +178 -0
  641. package/src/shade/renderer/fluid/mac/chunk_v3_mac_advect_maccormack.d.ts +17 -0
  642. package/src/shade/renderer/fluid/mac/chunk_v3_mac_advect_maccormack.d.ts.map +1 -0
  643. package/src/shade/renderer/fluid/mac/chunk_v3_mac_advect_maccormack.js +156 -0
  644. package/src/shade/renderer/fluid/mac/chunk_v3_mac_clip_trace.d.ts +31 -0
  645. package/src/shade/renderer/fluid/mac/chunk_v3_mac_clip_trace.d.ts.map +1 -0
  646. package/src/shade/renderer/fluid/mac/chunk_v3_mac_clip_trace.js +63 -0
  647. package/src/shade/renderer/fluid/mac/chunk_v3_mac_compute_divergence.d.ts +27 -0
  648. package/src/shade/renderer/fluid/mac/chunk_v3_mac_compute_divergence.d.ts.map +1 -0
  649. package/src/shade/renderer/fluid/mac/chunk_v3_mac_compute_divergence.js +42 -0
  650. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_carrier.d.ts +25 -0
  651. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_carrier.d.ts.map +1 -0
  652. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_carrier.js +67 -0
  653. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_pinned.d.ts +23 -0
  654. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_pinned.d.ts.map +1 -0
  655. package/src/shade/renderer/fluid/mac/chunk_v3_mac_face_pinned.js +38 -0
  656. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts +33 -0
  657. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts.map +1 -0
  658. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.js +231 -0
  659. package/src/shade/renderer/fluid/mac/chunk_v3_mac_subtract_pressure_gradient.d.ts +30 -0
  660. package/src/shade/renderer/fluid/mac/chunk_v3_mac_subtract_pressure_gradient.d.ts.map +1 -0
  661. package/src/shade/renderer/fluid/mac/chunk_v3_mac_subtract_pressure_gradient.js +66 -0
  662. package/src/shade/renderer/fluid/mac/chunk_v3_mac_vorticity_confinement.d.ts +27 -0
  663. package/src/shade/renderer/fluid/mac/chunk_v3_mac_vorticity_confinement.d.ts.map +1 -0
  664. package/src/shade/renderer/fluid/mac/chunk_v3_mac_vorticity_confinement.js +65 -0
  665. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +43 -0
  666. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -0
  667. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +245 -0
  668. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts +31 -0
  669. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts.map +1 -0
  670. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.js +109 -0
  671. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts +38 -0
  672. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts.map +1 -0
  673. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.js +222 -0
  674. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts +26 -0
  675. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts.map +1 -0
  676. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.js +92 -0
  677. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts +32 -0
  678. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts.map +1 -0
  679. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.js +181 -0
  680. package/src/shade/renderer/fluid/pressure/FLUID_MG.d.ts +112 -0
  681. package/src/shade/renderer/fluid/pressure/FLUID_MG.d.ts.map +1 -0
  682. package/src/shade/renderer/fluid/pressure/FLUID_MG.js +140 -0
  683. package/src/shade/renderer/fluid/pressure/FLUID_MG_PASS_STRUCT.d.ts +29 -0
  684. package/src/shade/renderer/fluid/pressure/FLUID_MG_PASS_STRUCT.d.ts.map +1 -0
  685. package/src/shade/renderer/fluid/pressure/FLUID_MG_PASS_STRUCT.js +45 -0
  686. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +156 -0
  687. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts.map +1 -0
  688. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.js +605 -0
  689. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_coarse_word.d.ts +18 -0
  690. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_coarse_word.d.ts.map +1 -0
  691. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_coarse_word.js +48 -0
  692. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_level0_word.d.ts +17 -0
  693. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_level0_word.d.ts.map +1 -0
  694. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_level0_word.js +47 -0
  695. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_prolong.d.ts +21 -0
  696. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_prolong.d.ts.map +1 -0
  697. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_prolong.js +47 -0
  698. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_relax.d.ts +27 -0
  699. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_relax.d.ts.map +1 -0
  700. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_relax.js +79 -0
  701. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_restrict.d.ts +18 -0
  702. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_restrict.d.ts.map +1 -0
  703. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_restrict.js +35 -0
  704. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_word.d.ts +17 -0
  705. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_word.d.ts.map +1 -0
  706. package/src/shade/renderer/fluid/pressure/chunk_fluid_mg_word.js +34 -0
  707. package/src/shade/renderer/fluid/pressure/chunk_fluid_pressure_ghost.d.ts +21 -0
  708. package/src/shade/renderer/fluid/pressure/chunk_fluid_pressure_ghost.d.ts.map +1 -0
  709. package/src/shade/renderer/fluid/pressure/chunk_fluid_pressure_ghost.js +34 -0
  710. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarse_weights.d.ts +10 -0
  711. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarse_weights.d.ts.map +1 -0
  712. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarse_weights.js +45 -0
  713. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.d.ts +17 -0
  714. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.d.ts.map +1 -0
  715. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.js +126 -0
  716. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_level0_weights.d.ts +10 -0
  717. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_level0_weights.d.ts.map +1 -0
  718. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_level0_weights.js +44 -0
  719. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts +18 -0
  720. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts.map +1 -0
  721. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js +149 -0
  722. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts +30 -0
  723. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts.map +1 -0
  724. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js +183 -0
  725. package/src/shade/renderer/fluid/publish/FLUID_WIND_PUBLISH_STRUCT.d.ts +9 -0
  726. package/src/shade/renderer/fluid/publish/FLUID_WIND_PUBLISH_STRUCT.d.ts.map +1 -0
  727. package/src/shade/renderer/fluid/publish/FLUID_WIND_PUBLISH_STRUCT.js +12 -0
  728. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts +49 -0
  729. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts.map +1 -0
  730. package/src/shade/renderer/fluid/publish/FluidWindPublish.js +136 -0
  731. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.d.ts +24 -0
  732. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.d.ts.map +1 -0
  733. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.js +37 -0
  734. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts +41 -0
  735. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -0
  736. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +122 -0
  737. package/src/shade/renderer/fluid/query/FLUID_QUERY_DATABASE_SPEC.d.ts +66 -0
  738. package/src/shade/renderer/fluid/query/FLUID_QUERY_DATABASE_SPEC.d.ts.map +1 -0
  739. package/src/shade/renderer/fluid/query/FLUID_QUERY_DATABASE_SPEC.js +88 -0
  740. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +157 -0
  741. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts.map +1 -0
  742. package/src/shade/renderer/fluid/query/GPUFluidQueries.js +709 -0
  743. package/src/shade/renderer/fluid/query/shader_fluid_query_gather.d.ts +47 -0
  744. package/src/shade/renderer/fluid/query/shader_fluid_query_gather.d.ts.map +1 -0
  745. package/src/shade/renderer/fluid/query/shader_fluid_query_gather.js +140 -0
  746. package/src/shade/renderer/geometry/GEOMETRY_ATTRIBUTE_DATA_RESOURCE.d.ts +7 -0
  747. package/src/shade/renderer/geometry/GEOMETRY_ATTRIBUTE_DATA_RESOURCE.d.ts.map +1 -0
  748. package/src/shade/renderer/geometry/GEOMETRY_ATTRIBUTE_DATA_RESOURCE.js +8 -0
  749. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +619 -606
  750. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts +3 -2
  751. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts.map +1 -1
  752. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.js +50 -44
  753. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts +12 -9
  754. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts.map +1 -1
  755. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.js +447 -363
  756. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts +7 -4
  757. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts.map +1 -1
  758. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.js +13 -6
  759. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts +21 -0
  760. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts.map +1 -0
  761. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.js +75 -0
  762. package/src/shade/renderer/geometry/meshlet/MESHLET_METADATA_RESOURCE.d.ts +7 -0
  763. package/src/shade/renderer/geometry/meshlet/MESHLET_METADATA_RESOURCE.d.ts.map +1 -0
  764. package/src/shade/renderer/geometry/meshlet/MESHLET_METADATA_RESOURCE.js +9 -0
  765. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  766. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +58 -9
  767. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +35 -25
  768. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  769. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +99 -196
  770. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts.map +1 -1
  771. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +125 -129
  772. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +1 -1
  773. package/src/shade/renderer/global_illumination/brick4/gpu/BRICK4_RESOURCE.d.ts +7 -0
  774. package/src/shade/renderer/global_illumination/brick4/gpu/BRICK4_RESOURCE.d.ts.map +1 -0
  775. package/src/shade/renderer/global_illumination/brick4/gpu/BRICK4_RESOURCE.js +8 -0
  776. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  777. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +5 -0
  778. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  779. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +7 -1
  780. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_load_probe.d.ts.map +1 -1
  781. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_load_probe.js +4 -1
  782. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_by_position.d.ts.map +1 -1
  783. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_by_position.js +4 -1
  784. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_sample_probes.d.ts.map +1 -1
  785. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_node_sample_probes.js +3 -0
  786. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.d.ts.map +1 -1
  787. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.js +4 -1
  788. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.d.ts.map +1 -1
  789. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.js +3 -0
  790. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.d.ts.map +1 -1
  791. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.js +4 -0
  792. package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.d.ts +15 -0
  793. package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.d.ts.map +1 -1
  794. package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.js +57 -57
  795. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  796. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +5 -0
  797. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.d.ts.map +1 -1
  798. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.js +3 -0
  799. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
  800. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +7 -1
  801. package/src/shade/renderer/global_illumination/probe/octahedral/LPV_SHADER_RESOURCE_GROUP.d.ts +39 -0
  802. package/src/shade/renderer/global_illumination/probe/octahedral/LPV_SHADER_RESOURCE_GROUP.d.ts.map +1 -1
  803. package/src/shade/renderer/global_illumination/probe/octahedral/LPV_SHADER_RESOURCE_GROUP.js +57 -4
  804. package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.js +3 -3
  805. package/src/shade/renderer/global_illumination/probe/octahedral/graph_sample_light_probes.d.ts.map +1 -1
  806. package/src/shade/renderer/global_illumination/probe/octahedral/graph_sample_light_probes.js +4 -0
  807. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_radiance_sample_reflection.d.ts.map +1 -1
  808. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_radiance_sample_reflection.js +3 -0
  809. package/src/shade/renderer/global_illumination/shader_resolve_indirect_lighting.d.ts.map +1 -1
  810. package/src/shade/renderer/global_illumination/shader_resolve_indirect_lighting.js +4 -0
  811. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_DEFINITION.d.ts +10 -0
  812. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_DEFINITION.d.ts.map +1 -0
  813. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_DEFINITION.js +25 -0
  814. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_LAYOUT.d.ts +55 -0
  815. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_LAYOUT.d.ts.map +1 -0
  816. package/src/shade/renderer/gpu_primitive/bvh/BVH_REFIT_DEFERRED_LAYOUT.js +63 -0
  817. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +248 -2
  818. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.d.ts +7 -0
  819. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.d.ts.map +1 -1
  820. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.js +45 -38
  821. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.d.ts +2 -0
  822. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.d.ts.map +1 -1
  823. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.js +81 -79
  824. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.d.ts +2 -0
  825. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.d.ts.map +1 -1
  826. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.js +5 -3
  827. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.d.ts +21 -0
  828. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.d.ts.map +1 -0
  829. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.js +42 -0
  830. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.d.ts +19 -0
  831. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.d.ts.map +1 -0
  832. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.js +44 -0
  833. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.d.ts +23 -11
  834. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.d.ts.map +1 -1
  835. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.js +171 -102
  836. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_repair.d.ts +23 -0
  837. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_repair.d.ts.map +1 -0
  838. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_repair.js +80 -0
  839. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +25 -5
  840. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts.map +1 -1
  841. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +189 -23
  842. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_refit_lbvh.d.ts +55 -0
  843. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_refit_lbvh.d.ts.map +1 -0
  844. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_refit_lbvh.js +197 -0
  845. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts +27 -0
  846. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts.map +1 -0
  847. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js +222 -0
  848. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts +5 -4
  849. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  850. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +20 -19
  851. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts +3 -4
  852. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  853. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +6 -23
  854. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts +6 -6
  855. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  856. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +11 -8
  857. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_prepare.d.ts +24 -0
  858. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_prepare.d.ts.map +1 -0
  859. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_prepare.js +99 -0
  860. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_repair.d.ts +17 -0
  861. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_repair.d.ts.map +1 -0
  862. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit_repair.js +63 -0
  863. package/src/shade/renderer/gpu_primitive/chunk_collection_u32_append.d.ts +19 -0
  864. package/src/shade/renderer/gpu_primitive/chunk_collection_u32_append.d.ts.map +1 -0
  865. package/src/shade/renderer/gpu_primitive/chunk_collection_u32_append.js +44 -0
  866. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +11 -0
  867. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  868. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +14 -3
  869. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.d.ts +10 -0
  870. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.d.ts.map +1 -1
  871. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.js +13 -3
  872. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +10 -0
  873. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  874. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +14 -0
  875. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.d.ts +26 -0
  876. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.d.ts.map +1 -0
  877. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.js +52 -0
  878. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.d.ts +32 -0
  879. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.d.ts.map +1 -0
  880. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.js +89 -0
  881. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +10 -0
  882. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  883. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +20 -1
  884. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +10 -0
  885. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  886. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +294 -281
  887. package/src/shade/renderer/light/GPULightCollection.d.ts +8 -0
  888. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  889. package/src/shade/renderer/light/GPULightCollection.js +18 -1
  890. package/src/shade/renderer/light/LIGHT_DATA_RESOURCE.d.ts +7 -0
  891. package/src/shade/renderer/light/LIGHT_DATA_RESOURCE.d.ts.map +1 -0
  892. package/src/shade/renderer/light/LIGHT_DATA_RESOURCE.js +8 -0
  893. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_LIST.d.ts +7 -0
  894. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_LIST.d.ts.map +1 -0
  895. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_LIST.js +16 -0
  896. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.d.ts +12 -0
  897. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.d.ts.map +1 -0
  898. package/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.js +33 -0
  899. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_ASSIGNMENT_SETTINGS.d.ts +7 -0
  900. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_ASSIGNMENT_SETTINGS.d.ts.map +1 -0
  901. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_ASSIGNMENT_SETTINGS.js +24 -0
  902. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.d.ts +8 -0
  903. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.d.ts.map +1 -0
  904. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_COARSE_BLOCK.js +7 -0
  905. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_METADATA.d.ts.map +1 -1
  906. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_METADATA.js +2 -3
  907. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_RESOURCES.d.ts +17 -0
  908. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_RESOURCES.d.ts.map +1 -0
  909. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_RESOURCES.js +22 -0
  910. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +524 -0
  911. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +1101 -0
  912. package/src/shade/renderer/light/cluster/chunk_cluster_cell.d.ts +19 -0
  913. package/src/shade/renderer/light/cluster/chunk_cluster_cell.d.ts.map +1 -0
  914. package/src/shade/renderer/light/cluster/chunk_cluster_cell.js +133 -0
  915. package/src/shade/renderer/light/cluster/chunk_cluster_from_fragment_coord.d.ts.map +1 -1
  916. package/src/shade/renderer/light/cluster/chunk_cluster_from_fragment_coord.js +6 -1
  917. package/src/shade/renderer/light/cluster/chunk_cluster_light_proxy.d.ts +19 -0
  918. package/src/shade/renderer/light/cluster/chunk_cluster_light_proxy.d.ts.map +1 -0
  919. package/src/shade/renderer/light/cluster/chunk_cluster_light_proxy.js +95 -0
  920. package/src/shade/renderer/light/cluster/chunk_light_cluster_counts.d.ts +6 -4
  921. package/src/shade/renderer/light/cluster/chunk_light_cluster_counts.d.ts.map +1 -1
  922. package/src/shade/renderer/light/cluster/chunk_light_cluster_counts.js +10 -8
  923. package/src/shade/renderer/light/cluster/chunk_light_cluster_metadata_by_position.d.ts.map +1 -1
  924. package/src/shade/renderer/light/cluster/chunk_light_cluster_metadata_by_position.js +4 -1
  925. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts +16 -0
  926. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  927. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +234 -218
  928. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts +33 -1
  929. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  930. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +184 -73
  931. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts +10 -1
  932. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts.map +1 -1
  933. package/src/shade/renderer/light/cluster/graph_build_light_clusters.js +19 -2
  934. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts +14 -2
  935. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts.map +1 -1
  936. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.js +230 -139
  937. package/src/shade/renderer/light/cluster/shader_cluster_coarse_mark.d.ts +19 -0
  938. package/src/shade/renderer/light/cluster/shader_cluster_coarse_mark.d.ts.map +1 -0
  939. package/src/shade/renderer/light/cluster/shader_cluster_coarse_mark.js +134 -0
  940. package/src/shade/renderer/light/cluster/shader_cluster_light_compact.d.ts +11 -0
  941. package/src/shade/renderer/light/cluster/shader_cluster_light_compact.d.ts.map +1 -0
  942. package/src/shade/renderer/light/cluster/shader_cluster_light_compact.js +114 -0
  943. package/src/shade/renderer/light/cluster/shader_cluster_light_mark.d.ts +9 -0
  944. package/src/shade/renderer/light/cluster/shader_cluster_light_mark.d.ts.map +1 -0
  945. package/src/shade/renderer/light/cluster/shader_cluster_light_mark.js +59 -0
  946. package/src/shade/renderer/light/cluster/shader_cluster_light_prepare.d.ts +14 -0
  947. package/src/shade/renderer/light/cluster/shader_cluster_light_prepare.d.ts.map +1 -0
  948. package/src/shade/renderer/light/cluster/shader_cluster_light_prepare.js +142 -0
  949. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts +7 -0
  950. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts.map +1 -0
  951. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.js +7 -0
  952. package/src/shade/renderer/light/environment/ENVIRONMENT_SH_RESOURCE.d.ts +7 -0
  953. package/src/shade/renderer/light/environment/ENVIRONMENT_SH_RESOURCE.d.ts.map +1 -0
  954. package/src/shade/renderer/light/environment/ENVIRONMENT_SH_RESOURCE.js +8 -0
  955. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +10 -0
  956. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  957. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +13 -0
  958. package/src/shade/renderer/light/environment/sh_exponential/README.md +2 -1
  959. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  960. package/src/shade/renderer/lightmap/GPULightMap.js +5 -0
  961. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
  962. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +7 -1
  963. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
  964. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +7 -1
  965. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_density.d.ts.map +1 -1
  966. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_density.js +4 -0
  967. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_uv_checker.d.ts.map +1 -1
  968. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_uv_checker.js +4 -0
  969. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_flat.d.ts.map +1 -1
  970. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_flat.js +4 -0
  971. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_sh.d.ts.map +1 -1
  972. package/src/shade/renderer/lightmap/debug/shader_lightmap_debug_view_sh.js +4 -0
  973. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  974. package/src/shade/renderer/material/GPUMaterialManager.d.ts +16 -4
  975. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  976. package/src/shade/renderer/material/GPUMaterialManager.js +38 -8
  977. package/src/shade/renderer/material/standard/SHADING_MATERIAL_RESOURCE_GROUP.d.ts +22 -0
  978. package/src/shade/renderer/material/standard/SHADING_MATERIAL_RESOURCE_GROUP.d.ts.map +1 -1
  979. package/src/shade/renderer/material/standard/SHADING_MATERIAL_RESOURCE_GROUP.js +33 -9
  980. package/src/shade/renderer/particles/DESIGN.md +65 -9
  981. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  982. package/src/shade/renderer/particles/GPUParticleSystem.js +3 -0
  983. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +453 -0
  984. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +5 -1
  985. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  986. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +13 -5
  987. package/src/shade/renderer/particles/data/particle_emitter_record.js +2 -2
  988. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  989. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +21 -9
  990. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  991. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +12 -0
  992. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts +60 -0
  993. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  994. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +156 -0
  995. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  996. package/src/shade/renderer/particles/graph/particle_node_parameters.js +1 -0
  997. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  998. package/src/shade/renderer/particles/graph/particle_node_presentation.js +8 -0
  999. package/src/shade/renderer/particles/graph_particles.d.ts +4 -1
  1000. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  1001. package/src/shade/renderer/particles/graph_particles.js +13 -0
  1002. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +13 -0
  1003. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  1004. package/src/shade/renderer/particles/isa/InstructionStream.js +13 -0
  1005. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +1 -0
  1006. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  1007. package/src/shade/renderer/particles/isa/ParticleVMISA.js +8 -0
  1008. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +2 -1
  1009. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  1010. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +28 -6
  1011. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +1 -1
  1012. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  1013. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +7 -0
  1014. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +2 -2
  1015. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  1016. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +8 -8
  1017. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
  1018. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +6 -4
  1019. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +7 -6
  1020. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  1021. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +91 -58
  1022. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +1 -1
  1023. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  1024. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +5 -2
  1025. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -1
  1026. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +5 -2
  1027. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  1028. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +5 -2
  1029. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -1
  1030. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +5 -2
  1031. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +16 -1
  1032. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  1033. package/src/shade/renderer/particles/vm/ParticleVMReference.js +35 -2
  1034. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  1035. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +8 -0
  1036. package/src/shade/renderer/particles/vm/chunk_particle_vm_wind_field.d.ts +20 -0
  1037. package/src/shade/renderer/particles/vm/chunk_particle_vm_wind_field.d.ts.map +1 -0
  1038. package/src/shade/renderer/particles/vm/chunk_particle_vm_wind_field.js +25 -0
  1039. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts +4 -1
  1040. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  1041. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +8 -0
  1042. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -1
  1043. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +109 -106
  1044. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -1
  1045. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +71 -68
  1046. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  1047. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +5 -0
  1048. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  1049. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +8 -2
  1050. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  1051. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +11 -1
  1052. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +4 -4
  1053. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -3
  1054. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts +7 -0
  1055. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts.map +1 -1
  1056. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +18 -0
  1057. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts.map +1 -1
  1058. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.js +1 -0
  1059. package/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.d.ts.map +1 -1
  1060. package/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.js +6 -4
  1061. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +11 -0
  1062. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  1063. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +16 -0
  1064. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +10 -0
  1065. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  1066. package/src/shade/renderer/postprocess/gtao/GTAO.js +16 -0
  1067. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  1068. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +32 -10
  1069. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  1070. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +11 -8
  1071. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  1072. package/src/shade/renderer/postprocess/ssr/SSR.js +49 -52
  1073. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  1074. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +3 -0
  1075. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts +28 -0
  1076. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts.map +1 -0
  1077. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.js +79 -0
  1078. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts +30 -0
  1079. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts.map +1 -0
  1080. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.js +66 -0
  1081. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts +11 -0
  1082. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -0
  1083. package/src/shade/renderer/postprocess/ssr/resolve/{build_ssr_resolve_shader.js → ssr_resolve_shader.js} +98 -87
  1084. package/src/shade/renderer/postprocess/taa/TAA.d.ts +12 -0
  1085. package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
  1086. package/src/shade/renderer/postprocess/taa/TAA.js +15 -0
  1087. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts +7 -0
  1088. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  1089. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +13 -0
  1090. package/src/shade/renderer/rasterize/TemplatePassDescriptor.d.ts +31 -3
  1091. package/src/shade/renderer/rasterize/TemplatePassDescriptor.d.ts.map +1 -1
  1092. package/src/shade/renderer/rasterize/TemplatePassDescriptor.js +79 -4
  1093. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.d.ts +17 -0
  1094. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.d.ts.map +1 -1
  1095. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.js +35 -4
  1096. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts +7 -0
  1097. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
  1098. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +182 -169
  1099. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.d.ts.map +1 -1
  1100. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.js +4 -0
  1101. package/src/shade/renderer/rasterize/expand/RasterizationCollectionType.d.ts +1 -0
  1102. package/src/shade/renderer/rasterize/expand/RasterizationCollectionType.js +5 -0
  1103. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts +10 -0
  1104. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  1105. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +20 -1
  1106. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.d.ts +10 -0
  1107. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.d.ts.map +1 -1
  1108. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.js +18 -1
  1109. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts +10 -0
  1110. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  1111. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +20 -1
  1112. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts +7 -0
  1113. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
  1114. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +187 -170
  1115. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts +10 -0
  1116. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  1117. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +19 -1
  1118. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts +13 -0
  1119. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  1120. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +25 -1
  1121. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts +10 -0
  1122. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  1123. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +20 -0
  1124. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts +25 -0
  1125. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts.map +1 -0
  1126. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.js +33 -0
  1127. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_brick4.d.ts +10 -0
  1128. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_brick4.d.ts.map +1 -0
  1129. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_brick4.js +38 -0
  1130. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_environment.d.ts +9 -0
  1131. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_environment.d.ts.map +1 -0
  1132. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_environment.js +30 -0
  1133. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment.d.ts +10 -0
  1134. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment.d.ts.map +1 -0
  1135. package/src/shade/renderer/rasterize/forward/{chunk_forward_shade_standard_fragment_brick4.js → chunk_forward_shade_standard_fragment.js} +66 -33
  1136. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -3
  1137. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  1138. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -3
  1139. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +9 -4
  1140. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -1
  1141. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +11 -5
  1142. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +8 -6
  1143. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  1144. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +27 -45
  1145. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts +18 -0
  1146. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts.map +1 -0
  1147. package/src/shade/renderer/rasterize/native/avboit/{shader_avboit_draw_brick4.js → shader_avboit_draw.js} +26 -21
  1148. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +3 -3
  1149. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts +3 -2
  1150. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  1151. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +26 -47
  1152. package/src/shade/renderer/rasterize/native/oit/oit_resolve_fragment_body.d.ts +12 -8
  1153. package/src/shade/renderer/rasterize/native/oit/oit_resolve_fragment_body.d.ts.map +1 -1
  1154. package/src/shade/renderer/rasterize/native/oit/oit_resolve_fragment_body.js +128 -123
  1155. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +3 -3
  1156. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts +11 -2
  1157. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts.map +1 -1
  1158. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +21 -13
  1159. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts +15 -0
  1160. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  1161. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +35 -2
  1162. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts +14 -0
  1163. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  1164. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +32 -4
  1165. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +17 -0
  1166. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  1167. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +34 -4
  1168. package/src/shade/renderer/restir/di/RESTIR_RADIANCE_RESOURCE.d.ts +7 -0
  1169. package/src/shade/renderer/restir/di/RESTIR_RADIANCE_RESOURCE.d.ts.map +1 -0
  1170. package/src/shade/renderer/restir/di/RESTIR_RADIANCE_RESOURCE.js +7 -0
  1171. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts +5 -3
  1172. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
  1173. package/src/shade/renderer/restir/di/chunk_restir_resolve.js +8 -3
  1174. package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
  1175. package/src/shade/renderer/restir/di/graph_restir_di.js +1 -0
  1176. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  1177. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +5 -1
  1178. package/src/shade/renderer/restir/reservoir/shader.d.ts.map +1 -1
  1179. package/src/shade/renderer/restir/reservoir/shader.js +7 -4
  1180. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +7 -0
  1181. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  1182. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +13 -1
  1183. package/src/shade/renderer/scene/GPUSceneContext.d.ts +19 -1
  1184. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  1185. package/src/shade/renderer/scene/GPUSceneContext.js +40 -1
  1186. package/src/shade/renderer/scene/MESH_INSTANCE_METADATA_STRUCT.d.ts.map +1 -1
  1187. package/src/shade/renderer/scene/MESH_INSTANCE_METADATA_STRUCT.js +5 -0
  1188. package/src/shade/renderer/scene/SCENE_DATABASE_RESOURCE.d.ts +7 -0
  1189. package/src/shade/renderer/scene/SCENE_DATABASE_RESOURCE.d.ts.map +1 -0
  1190. package/src/shade/renderer/scene/SCENE_DATABASE_RESOURCE.js +8 -0
  1191. package/src/shade/renderer/scene/SceneManager.d.ts +9 -0
  1192. package/src/shade/renderer/scene/SceneManager.d.ts.map +1 -1
  1193. package/src/shade/renderer/scene/SceneManager.js +11 -0
  1194. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.d.ts +11 -0
  1195. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.d.ts.map +1 -1
  1196. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.js +17 -0
  1197. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +11 -0
  1198. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
  1199. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +18 -1
  1200. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +14 -0
  1201. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  1202. package/src/shade/renderer/scene/rows/GPUSceneRows.js +114 -10
  1203. package/src/shade/renderer/shader/ComputeShader.d.ts +33 -0
  1204. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  1205. package/src/shade/renderer/shader/ComputeShader.js +107 -0
  1206. package/src/shade/renderer/shader/ImageShader.d.ts +27 -8
  1207. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  1208. package/src/shade/renderer/shader/ImageShader.js +70 -1
  1209. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +27 -0
  1210. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  1211. package/src/shade/renderer/shader/ShaderDescriptor.js +149 -1
  1212. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +394 -0
  1213. package/src/shade/renderer/shader/chunk/brdf/chunk_BRDF_GGX.d.ts +4 -1
  1214. package/src/shade/renderer/shader/chunk/brdf/chunk_BRDF_GGX.d.ts.map +1 -1
  1215. package/src/shade/renderer/shader/chunk/brdf/chunk_BRDF_GGX.js +7 -4
  1216. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.d.ts +4 -1
  1217. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.d.ts.map +1 -1
  1218. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.js +9 -9
  1219. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts +10 -1
  1220. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts.map +1 -1
  1221. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js +16 -5
  1222. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts +82 -0
  1223. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -0
  1224. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +286 -0
  1225. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_frontier.d.ts +47 -0
  1226. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_frontier.d.ts.map +1 -0
  1227. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_frontier.js +121 -0
  1228. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.d.ts +17 -0
  1229. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.d.ts.map +1 -0
  1230. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.js +45 -0
  1231. package/src/shade/renderer/shader/chunk/camera/chunk_screen_coordinate_to_view.js +3 -3
  1232. package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.d.ts +22 -0
  1233. package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.d.ts.map +1 -0
  1234. package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js +38 -0
  1235. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_contains.d.ts +11 -0
  1236. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_contains.d.ts.map +1 -0
  1237. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_contains.js +20 -0
  1238. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.d.ts +19 -0
  1239. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.d.ts.map +1 -0
  1240. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.js +71 -0
  1241. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_storage_coord.d.ts +15 -0
  1242. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_storage_coord.d.ts.map +1 -0
  1243. package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_storage_coord.js +25 -0
  1244. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_P3.d.ts +17 -0
  1245. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_P3.d.ts.map +1 -0
  1246. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_P3.js +26 -0
  1247. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.d.ts +1 -1
  1248. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.js +62 -62
  1249. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +318 -0
  1250. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +237 -0
  1251. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts +17 -0
  1252. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts.map +1 -0
  1253. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js +22 -0
  1254. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.d.ts +14 -1
  1255. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.d.ts.map +1 -1
  1256. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.js +28 -15
  1257. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts +16 -0
  1258. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts.map +1 -1
  1259. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.js +122 -110
  1260. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_intersects_aabb3.d.ts +14 -0
  1261. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_intersects_aabb3.d.ts.map +1 -0
  1262. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_intersects_aabb3.js +24 -0
  1263. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_signed_distance_to_point.d.ts +3 -0
  1264. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_signed_distance_to_point.d.ts.map +1 -1
  1265. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_signed_distance_to_point.js +9 -10
  1266. package/src/shade/renderer/shader/chunk/geometry/chunk_point_closest_on_line.d.ts +11 -0
  1267. package/src/shade/renderer/shader/chunk/geometry/chunk_point_closest_on_line.d.ts.map +1 -0
  1268. package/src/shade/renderer/shader/chunk/geometry/chunk_point_closest_on_line.js +28 -0
  1269. package/src/shade/renderer/shader/chunk/geometry/chunk_point_distance_to_line.d.ts +3 -2
  1270. package/src/shade/renderer/shader/chunk/geometry/chunk_point_distance_to_line.d.ts.map +1 -1
  1271. package/src/shade/renderer/shader/chunk/geometry/chunk_point_distance_to_line.js +8 -17
  1272. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_u32.d.ts.map +1 -1
  1273. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_u32.js +3 -0
  1274. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec2f.d.ts.map +1 -1
  1275. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec2f.js +4 -1
  1276. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec3f.d.ts.map +1 -1
  1277. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_attribute_vec3f.js +4 -1
  1278. package/src/shade/renderer/shader/chunk/geometry/plane/chunk_point_distance_above_plane.d.ts +8 -0
  1279. package/src/shade/renderer/shader/chunk/geometry/plane/chunk_point_distance_above_plane.d.ts.map +1 -1
  1280. package/src/shade/renderer/shader/chunk/geometry/plane/chunk_point_distance_above_plane.js +8 -0
  1281. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.d.ts +20 -0
  1282. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.d.ts.map +1 -0
  1283. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.js +33 -0
  1284. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_angle_stable.d.ts +14 -0
  1285. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_angle_stable.d.ts.map +1 -0
  1286. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_angle_stable.js +21 -0
  1287. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_clamp_to_cone.d.ts +21 -0
  1288. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_clamp_to_cone.d.ts.map +1 -0
  1289. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_clamp_to_cone.js +49 -0
  1290. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_slerp.d.ts +29 -0
  1291. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_slerp.d.ts.map +1 -0
  1292. package/src/shade/renderer/shader/chunk/geometry/vec3/chunk_v3_slerp.js +86 -0
  1293. package/src/shade/renderer/shader/chunk/grid/GRID_TILE_WINDOW_STRUCT.d.ts +24 -0
  1294. package/src/shade/renderer/shader/chunk/grid/GRID_TILE_WINDOW_STRUCT.d.ts.map +1 -0
  1295. package/src/shade/renderer/shader/chunk/grid/GRID_TILE_WINDOW_STRUCT.js +30 -0
  1296. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_f32.d.ts +55 -0
  1297. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_f32.d.ts.map +1 -0
  1298. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_f32.js +101 -0
  1299. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_vec4.d.ts +24 -0
  1300. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_vec4.d.ts.map +1 -0
  1301. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_halo_vec4.js +70 -0
  1302. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_window.d.ts +42 -0
  1303. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_window.d.ts.map +1 -0
  1304. package/src/shade/renderer/shader/chunk/grid/chunk_grid_tile_window.js +88 -0
  1305. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.d.ts +4 -0
  1306. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.d.ts.map +1 -1
  1307. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.js +12 -1
  1308. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_get_vertices.d.ts.map +1 -1
  1309. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_get_vertices.js +4 -1
  1310. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_lookup_nearest_cell.d.ts.map +1 -1
  1311. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_lookup_nearest_cell.js +4 -1
  1312. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_data.d.ts.map +1 -1
  1313. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_data.js +4 -1
  1314. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_position.d.ts.map +1 -1
  1315. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_probe_get_position.js +4 -1
  1316. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_radiance.d.ts.map +1 -1
  1317. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_radiance.js +4 -1
  1318. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.d.ts.map +1 -1
  1319. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.js +6 -1
  1320. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_sample_depth_atlas.d.ts.map +1 -1
  1321. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_sample_depth_atlas.js +13 -1
  1322. package/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.d.ts.map +1 -1
  1323. package/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js +7 -0
  1324. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +159 -0
  1325. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.d.ts.map +1 -1
  1326. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.js +29 -5
  1327. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts +24 -0
  1328. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts.map +1 -0
  1329. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.js +84 -0
  1330. package/src/shade/renderer/shader/chunk/material/chunk_re_indirect_specular_physical.d.ts.map +1 -1
  1331. package/src/shade/renderer/shader/chunk/material/chunk_re_indirect_specular_physical.js +2 -0
  1332. package/src/shade/renderer/shader/chunk/math/chunk_falloff_quadratic.d.ts +11 -0
  1333. package/src/shade/renderer/shader/chunk/math/chunk_falloff_quadratic.d.ts.map +1 -0
  1334. package/src/shade/renderer/shader/chunk/math/chunk_falloff_quadratic.js +20 -0
  1335. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts.map +1 -1
  1336. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.js +4 -1
  1337. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts.map +1 -1
  1338. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.js +3 -0
  1339. package/src/shade/renderer/shader/chunk/physics/fluid/chunk_vortex_swirl.d.ts +20 -0
  1340. package/src/shade/renderer/shader/chunk/physics/fluid/chunk_vortex_swirl.d.ts.map +1 -0
  1341. package/src/shade/renderer/shader/chunk/physics/fluid/chunk_vortex_swirl.js +39 -0
  1342. package/src/shade/renderer/shader/chunk/physics/kinematics/chunk_rigid_velocity_at_point.d.ts +12 -0
  1343. package/src/shade/renderer/shader/chunk/physics/kinematics/chunk_rigid_velocity_at_point.d.ts.map +1 -0
  1344. package/src/shade/renderer/shader/chunk/physics/kinematics/chunk_rigid_velocity_at_point.js +21 -0
  1345. package/src/shade/renderer/shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.d.ts +17 -0
  1346. package/src/shade/renderer/shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.d.ts.map +1 -0
  1347. package/src/shade/renderer/shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.js +19 -0
  1348. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_depth.d.ts.map +1 -1
  1349. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_depth.js +5 -1
  1350. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_world_space_normal.d.ts.map +1 -1
  1351. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_load_world_space_normal.js +4 -1
  1352. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_screen_space_to_view_space.d.ts.map +1 -1
  1353. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_screen_space_to_view_space.js +4 -1
  1354. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_validate_hit.d.ts.map +1 -1
  1355. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_validate_hit.js +3 -0
  1356. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.d.ts +43 -0
  1357. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.d.ts.map +1 -0
  1358. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.js +319 -0
  1359. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.d.ts.map +1 -1
  1360. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.js +3 -5
  1361. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_box.d.ts +16 -0
  1362. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_box.d.ts.map +1 -0
  1363. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_box.js +28 -0
  1364. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_capsule.d.ts +18 -0
  1365. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_capsule.d.ts.map +1 -0
  1366. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_capsule.js +30 -0
  1367. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_cylinder.d.ts +18 -0
  1368. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_cylinder.d.ts.map +1 -0
  1369. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_cylinder.js +28 -0
  1370. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_sphere.d.ts +13 -0
  1371. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_sphere.d.ts.map +1 -0
  1372. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf3_sphere.js +20 -0
  1373. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_texture_region_sample_linear_uv.d.ts +7 -0
  1374. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_texture_region_sample_linear_uv.d.ts.map +1 -1
  1375. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_texture_region_sample_linear_uv.js +16 -41
  1376. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_kind.d.ts +10 -0
  1377. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_kind.d.ts.map +1 -0
  1378. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_kind.js +24 -0
  1379. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_local_bounds.d.ts +20 -0
  1380. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_local_bounds.d.ts.map +1 -0
  1381. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_local_bounds.js +54 -0
  1382. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_signed_distance.d.ts +23 -0
  1383. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_signed_distance.d.ts.map +1 -0
  1384. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_signed_distance.js +82 -0
  1385. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.d.ts +4 -3
  1386. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.d.ts.map +1 -1
  1387. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.js +4 -3
  1388. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_append_slot.d.ts +31 -0
  1389. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_append_slot.d.ts.map +1 -0
  1390. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_append_slot.js +60 -0
  1391. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_atomic_add.d.ts +15 -0
  1392. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_atomic_add.d.ts.map +1 -0
  1393. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_atomic_add.js +29 -0
  1394. package/src/shade/renderer/shader/chunk/texture/TEXTURE3D_TRILINEAR_CORNERS_STRUCT.d.ts +15 -0
  1395. package/src/shade/renderer/shader/chunk/texture/TEXTURE3D_TRILINEAR_CORNERS_STRUCT.d.ts.map +1 -0
  1396. package/src/shade/renderer/shader/chunk/texture/TEXTURE3D_TRILINEAR_CORNERS_STRUCT.js +20 -0
  1397. package/src/shade/renderer/shader/chunk/texture/chunk_texel_coordinate_to_uv3.d.ts +11 -0
  1398. package/src/shade/renderer/shader/chunk/texture/chunk_texel_coordinate_to_uv3.d.ts.map +1 -0
  1399. package/src/shade/renderer/shader/chunk/texture/chunk_texel_coordinate_to_uv3.js +18 -0
  1400. package/src/shade/renderer/shader/chunk/texture/chunk_uv3_to_texel_coordinate.d.ts +11 -0
  1401. package/src/shade/renderer/shader/chunk/texture/chunk_uv3_to_texel_coordinate.d.ts.map +1 -0
  1402. package/src/shade/renderer/shader/chunk/texture/chunk_uv3_to_texel_coordinate.js +18 -0
  1403. package/src/shade/renderer/shader/chunk/texture/sample/chunk_texture3d_trilinear_corners.d.ts +35 -0
  1404. package/src/shade/renderer/shader/chunk/texture/sample/chunk_texture3d_trilinear_corners.d.ts.map +1 -0
  1405. package/src/shade/renderer/shader/chunk/texture/sample/chunk_texture3d_trilinear_corners.js +159 -0
  1406. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +67 -1
  1407. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  1408. package/src/shade/renderer/shader/compiler/CodeChunk.js +205 -2
  1409. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts +76 -0
  1410. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts.map +1 -0
  1411. package/src/shade/renderer/shader/compiler/CodeChunkChoice.js +176 -0
  1412. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +932 -0
  1413. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts +86 -0
  1414. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts.map +1 -0
  1415. package/src/shade/renderer/shader/compiler/ShaderSwitch.js +178 -0
  1416. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts +67 -0
  1417. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts.map +1 -0
  1418. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.js +229 -0
  1419. package/src/shade/renderer/shader/graph/graph_prepare_bindings.d.ts.map +1 -1
  1420. package/src/shade/renderer/shader/graph/graph_prepare_bindings.js +69 -0
  1421. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts +94 -2
  1422. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts.map +1 -1
  1423. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.js +333 -2
  1424. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts +14 -1
  1425. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts.map +1 -1
  1426. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.js +28 -150
  1427. package/src/shade/renderer/shader/resource/encoder_prepare_shader_bindings_defaults.d.ts +5 -0
  1428. package/src/shade/renderer/shader/resource/encoder_prepare_shader_bindings_defaults.d.ts.map +1 -1
  1429. package/src/shade/renderer/shader/resource/encoder_prepare_shader_bindings_defaults.js +11 -1
  1430. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.d.ts +14 -0
  1431. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.d.ts.map +1 -0
  1432. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.js +13 -0
  1433. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.d.ts +65 -0
  1434. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.d.ts.map +1 -0
  1435. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.js +252 -0
  1436. package/src/shade/renderer/shadow/contact/FINDINGS.md +413 -0
  1437. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.d.ts +29 -0
  1438. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.d.ts.map +1 -0
  1439. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.js +105 -0
  1440. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.d.ts +29 -0
  1441. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.d.ts.map +1 -0
  1442. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.js +39 -0
  1443. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.d.ts +29 -0
  1444. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.d.ts.map +1 -0
  1445. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.js +92 -0
  1446. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.d.ts +29 -0
  1447. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.d.ts.map +1 -0
  1448. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.js +128 -0
  1449. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.d.ts +52 -0
  1450. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.d.ts.map +1 -0
  1451. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.js +358 -0
  1452. package/src/shade/renderer/shadow/map/SHADOWMAP_RESOURCES.d.ts +12 -0
  1453. package/src/shade/renderer/shadow/map/SHADOWMAP_RESOURCES.d.ts.map +1 -0
  1454. package/src/shade/renderer/shadow/map/SHADOWMAP_RESOURCES.js +14 -0
  1455. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.d.ts +10 -0
  1456. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.d.ts.map +1 -0
  1457. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.js +12 -0
  1458. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.d.ts +13 -0
  1459. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.d.ts.map +1 -0
  1460. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.js +14 -0
  1461. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.d.ts.map +1 -1
  1462. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.js +3 -0
  1463. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts +14 -8
  1464. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts.map +1 -1
  1465. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.js +20 -86
  1466. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.d.ts +14 -0
  1467. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.d.ts.map +1 -0
  1468. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.js +79 -0
  1469. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_filtered.d.ts.map +1 -1
  1470. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_filtered.js +8 -1
  1471. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
  1472. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +3 -0
  1473. package/src/shade/renderer/shadow/ray/shader_ray_shadow_code.d.ts.map +1 -1
  1474. package/src/shade/renderer/shadow/ray/shader_ray_shadow_code.js +12 -12
  1475. package/src/shade/renderer/shadow/ray/shader_screens_space_shadows.d.ts.map +1 -1
  1476. package/src/shade/renderer/shadow/ray/shader_screens_space_shadows.js +3 -0
  1477. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
  1478. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +153 -151
  1479. package/src/shade/renderer/shadow/sdf/chunk_geometry_sdf_query_distance.d.ts.map +1 -1
  1480. package/src/shade/renderer/shadow/sdf/chunk_geometry_sdf_query_distance.js +3 -3
  1481. package/src/shade/renderer/shadow/sdf/chunk_sdf_geometry_raymarch.d.ts.map +1 -1
  1482. package/src/shade/renderer/shadow/sdf/chunk_sdf_geometry_raymarch.js +3 -3
  1483. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +5 -3
  1484. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -1
  1485. package/src/shade/renderer/shadow/vsm/VSMPageManager.js +86 -89
  1486. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts.map +1 -1
  1487. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.js +12 -9
  1488. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.d.ts +13 -0
  1489. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.d.ts.map +1 -0
  1490. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.js +48 -0
  1491. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts +2 -2
  1492. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts.map +1 -1
  1493. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.js +13 -26
  1494. package/src/shade/renderer/texture/GPUTextureContext.d.ts +10 -0
  1495. package/src/shade/renderer/texture/GPUTextureContext.d.ts.map +1 -1
  1496. package/src/shade/renderer/texture/GPUTextureContext.js +24 -0
  1497. package/src/shade/renderer/texture/SAMPLER_LINEAR_RESOURCE.d.ts +7 -0
  1498. package/src/shade/renderer/texture/SAMPLER_LINEAR_RESOURCE.d.ts.map +1 -0
  1499. package/src/shade/renderer/texture/SAMPLER_LINEAR_RESOURCE.js +8 -0
  1500. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +238 -0
  1501. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -0
  1502. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +747 -0
  1503. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +20 -0
  1504. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -0
  1505. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +30 -0
  1506. package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts +2 -0
  1507. package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts.map +1 -1
  1508. package/src/shade/renderer/texture/draw_texture_as_rgba.js +2 -0
  1509. package/src/shade/renderer/texture/graph_draw_texture_3d_slice_as_rgba.d.ts +31 -0
  1510. package/src/shade/renderer/texture/graph_draw_texture_3d_slice_as_rgba.d.ts.map +1 -0
  1511. package/src/shade/renderer/texture/graph_draw_texture_3d_slice_as_rgba.js +116 -0
  1512. package/src/shade/renderer/texture/shader_draw_texture_3d_slice_as_rgba.d.ts +33 -0
  1513. package/src/shade/renderer/texture/shader_draw_texture_3d_slice_as_rgba.d.ts.map +1 -0
  1514. package/src/shade/renderer/texture/shader_draw_texture_3d_slice_as_rgba.js +90 -0
  1515. package/src/shade/renderer/texture/util/ZERO_UINT_PIXEL_TEXTURE.d.ts +10 -0
  1516. package/src/shade/renderer/texture/util/ZERO_UINT_PIXEL_TEXTURE.d.ts.map +1 -0
  1517. package/src/shade/renderer/texture/util/ZERO_UINT_PIXEL_TEXTURE.js +33 -0
  1518. package/src/shade/renderer/view/VIEW_RESOURCE.d.ts +7 -0
  1519. package/src/shade/renderer/view/VIEW_RESOURCE.d.ts.map +1 -0
  1520. package/src/shade/renderer/view/VIEW_RESOURCE.js +8 -0
  1521. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +33 -6
  1522. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
  1523. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +299 -16
  1524. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +11 -4
  1525. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  1526. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +14 -4
  1527. package/src/shade/renderer/volumetrics/NOTES.md +97 -0
  1528. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.d.ts.map +1 -1
  1529. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.js +42 -1
  1530. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +74 -10
  1531. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  1532. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +136 -10
  1533. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +30 -5
  1534. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  1535. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +97 -68
  1536. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOURCES.d.ts +17 -0
  1537. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOURCES.d.ts.map +1 -0
  1538. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOURCES.js +20 -0
  1539. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +336 -0
  1540. package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.d.ts.map +1 -1
  1541. package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.js +82 -76
  1542. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts +8 -4
  1543. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts.map +1 -1
  1544. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.js +22 -9
  1545. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts +19 -0
  1546. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts.map +1 -0
  1547. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.js +56 -0
  1548. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts.map +1 -1
  1549. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.js +3 -0
  1550. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts +12 -3
  1551. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts.map +1 -1
  1552. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.js +85 -48
  1553. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts +7 -0
  1554. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts.map +1 -1
  1555. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js +152 -130
  1556. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +1 -1
  1557. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +5 -0
  1558. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +7 -9
  1559. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +1 -1
  1560. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +11 -9
  1561. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts +35 -0
  1562. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +1 -0
  1563. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.js +105 -0
  1564. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +15 -9
  1565. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +1 -1
  1566. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +26 -36
  1567. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts +10 -0
  1568. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts.map +1 -0
  1569. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.js +51 -0
  1570. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +11 -0
  1571. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +1 -1
  1572. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +19 -6
  1573. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +11 -4
  1574. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -1
  1575. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +14 -5
  1576. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +4 -1
  1577. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  1578. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +43 -10
  1579. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts +133 -0
  1580. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts.map +1 -0
  1581. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.js +152 -0
  1582. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.d.ts +9 -0
  1583. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.d.ts.map +1 -0
  1584. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.js +24 -0
  1585. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts +28 -0
  1586. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts.map +1 -0
  1587. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.js +96 -0
  1588. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts +67 -0
  1589. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts.map +1 -0
  1590. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.js +73 -0
  1591. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_carried.d.ts +14 -0
  1592. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_carried.d.ts.map +1 -0
  1593. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_carried.js +76 -0
  1594. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_scrolled.d.ts +14 -0
  1595. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_scrolled.d.ts.map +1 -0
  1596. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_scrolled.js +38 -0
  1597. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_tap.d.ts +21 -0
  1598. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_tap.d.ts.map +1 -0
  1599. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise_tap.js +74 -0
  1600. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.d.ts +10 -0
  1601. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.d.ts.map +1 -0
  1602. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.js +121 -0
  1603. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +6 -0
  1604. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -1
  1605. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +11 -2
  1606. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +7 -0
  1607. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  1608. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +14 -4
  1609. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  1610. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +54 -5
  1611. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -1
  1612. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +311 -290
  1613. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.d.ts.map +1 -1
  1614. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.js +33 -49
  1615. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +3 -2
  1616. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  1617. package/src/shade/renderer/water/GPUWaterRenderer.js +27 -30
  1618. package/src/shade/renderer/water/chunk_water_gi.d.ts +10 -2
  1619. package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
  1620. package/src/shade/renderer/water/chunk_water_gi.js +70 -56
  1621. package/src/shade/renderer/water/chunk_water_transport.d.ts +0 -1
  1622. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  1623. package/src/shade/renderer/water/chunk_water_transport.js +0 -17
  1624. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts +2 -2
  1625. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts.map +1 -1
  1626. package/src/shade/renderer/water/optics/chunk_water_inscatter.js +5 -2
  1627. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +1 -2
  1628. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  1629. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +4 -2
  1630. package/src/shade/renderer/water/shader_water.d.ts +9 -10
  1631. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  1632. package/src/shade/renderer/water/shader_water.js +88 -55
  1633. package/src/shade/renderer/water/shader_water_avboit.d.ts +0 -4
  1634. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  1635. package/src/shade/renderer/water/shader_water_avboit.js +0 -63
  1636. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts +4 -1
  1637. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  1638. package/src/shade/renderer/water/surface/GPUWaterSurface.js +9 -3
  1639. package/src/shade/renderer/water/surface/WATER_SURFACE_RESOURCES.d.ts +15 -0
  1640. package/src/shade/renderer/water/surface/WATER_SURFACE_RESOURCES.d.ts.map +1 -0
  1641. package/src/shade/renderer/water/surface/WATER_SURFACE_RESOURCES.js +27 -0
  1642. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +2 -1
  1643. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -1
  1644. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +18 -9
  1645. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +0 -3
  1646. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -1
  1647. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +15 -3
  1648. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +2 -2
  1649. package/src/shade/renderer/water/surface/shader_water_cull.d.ts +9 -3
  1650. package/src/shade/renderer/water/surface/shader_water_cull.d.ts.map +1 -1
  1651. package/src/shade/renderer/water/surface/shader_water_cull.js +46 -22
  1652. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts +26 -1
  1653. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts.map +1 -1
  1654. package/src/shade/renderer/water/surface/shader_water_waves_derive.js +73 -9
  1655. package/src/shade/renderer/wind/GPUSceneWind.d.ts +127 -0
  1656. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -0
  1657. package/src/shade/renderer/wind/GPUSceneWind.js +410 -0
  1658. package/src/shade/renderer/wind/WIND_FIELD.d.ts +53 -0
  1659. package/src/shade/renderer/wind/WIND_FIELD.d.ts.map +1 -0
  1660. package/src/shade/renderer/wind/WIND_FIELD.js +60 -0
  1661. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts +36 -0
  1662. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts.map +1 -0
  1663. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.js +61 -0
  1664. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +17 -0
  1665. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -0
  1666. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +17 -0
  1667. package/src/shade/renderer/wind/chunk_wind_field_sample.d.ts +20 -0
  1668. package/src/shade/renderer/wind/chunk_wind_field_sample.d.ts.map +1 -0
  1669. package/src/shade/renderer/wind/chunk_wind_field_sample.js +26 -0
  1670. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +40 -0
  1671. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -0
  1672. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +92 -0
  1673. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +12 -0
  1674. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -0
  1675. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +22 -0
  1676. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +15 -0
  1677. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -0
  1678. package/src/shade/renderer/wind/wind_field_add_resources.js +22 -0
  1679. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +5 -2
  1680. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
  1681. package/src/shade/wgsl/emulator/CPUBitmapData.js +5 -2
  1682. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +5 -1
  1683. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  1684. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +118 -31
  1685. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  1686. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +90 -22
  1687. package/src/engine/network/transport/Channel.d.ts +0 -85
  1688. package/src/engine/network/transport/Channel.d.ts.map +0 -1
  1689. package/src/engine/network/transport/ReliableCommandPipeline.d.ts +0 -155
  1690. package/src/engine/network/transport/ReliableCommandPipeline.d.ts.map +0 -1
  1691. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts +0 -105
  1692. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts.map +0 -1
  1693. package/src/engine/network/transport/fragments/FragmentRetention.d.ts +0 -103
  1694. package/src/engine/network/transport/fragments/FragmentRetention.d.ts.map +0 -1
  1695. package/src/engine/network/transport/fragments/fragment_send.d.ts +0 -61
  1696. package/src/engine/network/transport/fragments/fragment_send.d.ts.map +0 -1
  1697. package/src/engine/network/transport/fragments/packet_size.d.ts +0 -99
  1698. package/src/engine/network/transport/fragments/packet_size.d.ts.map +0 -1
  1699. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +0 -87
  1700. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +0 -1
  1701. package/src/engine/physics/cloth/wind/ClothAmbientWind.js +0 -185
  1702. package/src/shade/renderer/geometry/sdf/chunk_sdf_slot_index_to_texture_offset.d.ts +0 -7
  1703. package/src/shade/renderer/geometry/sdf/chunk_sdf_slot_index_to_texture_offset.d.ts.map +0 -1
  1704. package/src/shade/renderer/geometry/sdf/chunk_sdf_slot_index_to_texture_offset.js +0 -25
  1705. package/src/shade/renderer/global_illumination/clipmap/GPUClipMap3D.d.ts +0 -43
  1706. package/src/shade/renderer/global_illumination/clipmap/GPUClipMap3D.d.ts.map +0 -1
  1707. package/src/shade/renderer/global_illumination/clipmap/GPUClipMap3D.js +0 -207
  1708. package/src/shade/renderer/global_illumination/clipmap/RadianceField.d.ts +0 -21
  1709. package/src/shade/renderer/global_illumination/clipmap/RadianceField.d.ts.map +0 -1
  1710. package/src/shade/renderer/global_illumination/clipmap/RadianceField.js +0 -40
  1711. package/src/shade/renderer/global_illumination/clipmap/chunk_clip_cascade_wrap_coord.d.ts +0 -13
  1712. package/src/shade/renderer/global_illumination/clipmap/chunk_clip_cascade_wrap_coord.d.ts.map +0 -1
  1713. package/src/shade/renderer/global_illumination/clipmap/chunk_clip_cascade_wrap_coord.js +0 -47
  1714. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts +0 -7
  1715. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts.map +0 -1
  1716. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.js +0 -115
  1717. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.d.ts +0 -7
  1718. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.d.ts.map +0 -1
  1719. package/src/shade/renderer/light/cluster/LIGHT_CLUSTER_LOCAL_LIGHT_LIMIT.js +0 -6
  1720. package/src/shade/renderer/light/cluster/chunk_cluster_keep_smallest.d.ts +0 -21
  1721. package/src/shade/renderer/light/cluster/chunk_cluster_keep_smallest.d.ts.map +0 -1
  1722. package/src/shade/renderer/light/cluster/chunk_cluster_keep_smallest.js +0 -47
  1723. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts +0 -21
  1724. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +0 -1
  1725. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts +0 -2
  1726. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts.map +0 -1
  1727. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.js +0 -24
  1728. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts +0 -2
  1729. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +0 -1
  1730. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +0 -21
  1731. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts +0 -2
  1732. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +0 -1
  1733. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +0 -34
  1734. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts +0 -3
  1735. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +0 -1
  1736. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts +0 -7
  1737. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +0 -1
  1738. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +0 -178
  1739. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts +0 -9
  1740. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +0 -1
  1741. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts +0 -9
  1742. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +0 -1
  1743. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +0 -110
  1744. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.d.ts +0 -9
  1745. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.d.ts.map +0 -1
  1746. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +0 -110
  1747. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Hauber.d.ts +0 -9
  1748. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Hauber.d.ts.map +0 -1
  1749. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Hauber.js +0 -22
  1750. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.d.ts +0 -6
  1751. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.d.ts.map +0 -1
  1752. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.js +0 -16
  1753. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.d.ts +0 -7
  1754. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.d.ts.map +0 -1
  1755. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.js +0 -46
  1756. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.d.ts +0 -10
  1757. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.d.ts.map +0 -1
  1758. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.js +0 -127
  1759. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.d.ts +0 -7
  1760. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.d.ts.map +0 -1
  1761. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.js +0 -39
  1762. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts +0 -10
  1763. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts.map +0 -1
  1764. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.js +0 -55
  1765. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts +0 -10
  1766. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts.map +0 -1
  1767. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.js +0 -47
  1768. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts +0 -10
  1769. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts.map +0 -1
  1770. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.js +0 -63
@@ -0,0 +1,1382 @@
1
+ # GPU fluid with scrolling cascades — proposal, 2026-10-16
2
+
3
+ Status: **revision (e), nothing built.** Written against the tree at `fb0e9497b`. Paths are relative
4
+ to `packages/meep-engine/src/`.
5
+
6
+ - **Revision (a)** proposed the simulation and six forks.
7
+ - **Revision (b)** took Alex's answers and a reuse audit.
8
+ - **Revision (c)** answered two adversarial passes.
9
+ - **Revision (d)** took Alex's review of (c): one infinite fluid with `GlobalFluidEffector` as its far
10
+ field; an acceleration structure; water reading actual velocity; queries on the system; a solver
11
+ that departs from the CPU's algorithms on facts, with subgroups and LDS from the start.
12
+ - **Revision (e)** answers a reference check and a design attack on (d) (§22). Its solver numbers are
13
+ **measured on a CPU model of the §8 solver**, reproduced by me.
14
+
15
+ No fork is open.
16
+
17
+ ## 0. Summary
18
+
19
+ **The model is one infinite fluid.**
20
+ - **Inside the cascades** around a domain's anchor, velocity is what the simulation holds.
21
+ - **Everywhere else** it is the **far field**: what the scene's `GlobalFluidEffector`s make of air
22
+ nothing else touches, `v_far(t)`, computed once per tick on the CPU.
23
+ - **Toward the outer edge of the coarsest cascade**, reads blend toward it.
24
+
25
+ There is one wind, read one way. God of War (2018) shipped one uniform volume, with no cascades and
26
+ no projection. Coupled cascades are new for real time; the coupling comes from atmospheric nested
27
+ grids (WRF).
28
+
29
+ **The shape:**
30
+
31
+ 1. **`GlobalFluidEffector` defines the far field.**
32
+ - `v_far = u(t) + g(t)`: `u` relaxes toward the effector's `wind` at its `drag`, and `g` is
33
+ `ClothAmbientWind`'s gust, moved onto the effector with its meaning unchanged and *not*
34
+ low-passed.
35
+ - The body `force` stays a CPU-field term and is not part of the far field.
36
+ - **Every read of a cascade at any time `t` returns
37
+ `v_far(t) + (v − v_far(t_s))·e^(−(Λ(t) − Λ(t_s)))`**, with `t_s` that cascade's last step and
38
+ `Λ = ∫drag dt`. Uniform air therefore matches the far field at every instant, on every cascade,
39
+ through dropped ticks. Every step applies the atmosphere through the same identity, which is
40
+ exact by linearity (§6).
41
+ - `ClothAmbientWind`, `SceneVolumetrics.wind` and `WaterWaves`' per-body wind are removed.
42
+ 2. **A domain is a `GPUFluidComponent` on an entity with a `Transform64`.**
43
+ - Cascades of `cell_size · 2^i` at one power-of-two resolution, placed by a clipmap module shared
44
+ with the VSM and the CPU fluid.
45
+ - Toroidal per-component `r32float` face textures. **Ghosts are never persistent**: a step writes
46
+ its parent's read once into transient ghosts, which its passes and LDS halos read (§7).
47
+ 3. **The solver keeps the CPU's MAC discretisation and departs from its algorithms on measured
48
+ facts** (§8):
49
+ - **Pressure:** a geometric-multigrid V-cycle with an LDS block red-black smoother and the
50
+ finite-volume coarse boundary weight `2/(1+h/H)`.
51
+ - **Measured on 64×32×64:** 0.30 residual factor per V-cycle, against red-black SOR's 0.27 per
52
+ 16 sweeps (32 passes). **Built at S1:** 10 passes a V-cycle, two a step, ~3× faster than SOR to
53
+ the same residual on the 4090; a whole step costs 115 µs there.
54
+ - **Also measured:** carrying the CPU's open-face rule onto every level stalls the V-cycle at
55
+ 0.75, and a frozen-halo SOR with both colours in one dispatch diverges. Both traps are written
56
+ into the design.
57
+ - **Advection:** MacCormack with manual trilinear in f32. Vulkan core guarantees only 4 bits of
58
+ filter weight, and the limiter needs the corners anyway.
59
+ - **Stencils** on LDS tiles; subgroups for appends and reductions.
60
+ 4. **Effectors and obstacles are `GPUDatabase` rows linked to transform rows.**
61
+ - **Each frame** a GPU LBVH is built (or refit) over their world boxes, clipped to the cascades,
62
+ by the engine's TLAS builder: one for each resolution a stepping cascade needs, over the
63
+ effectors and the obstacles at least half its cell wide, which is the resolution cull (§10).
64
+ - **Each brick** of each stepping cascade queries its tree cooperatively in LDS. Survivors are
65
+ chosen deterministically by row index, obstacles first (§10).
66
+ 5. **Consumers read one field** through `chunk_wind_field_sample`: a generalised `GPUTileAtlas3D`, a
67
+ per-cascade read record, and `v_far`.
68
+ - Water samples it per body, low-passed to sea-state timescales.
69
+ - Volumetrics folds the far field into its noise phases on the host, per row, and samples the
70
+ departure from it where the noise is evaluated, as a flow map.
71
+ - Particles get one VM primitive (§11, §13).
72
+ 6. **CPU readers ask `GPUFluidSystem`:** `far_field(out)` synchronously and deterministically, and
73
+ `request(...)` for an async lattice through `GPUDatabaseReadback`. Cloth's default source is an
74
+ adapter over it (§12).
75
+
76
+ ## 1. What the tree has
77
+
78
+ Facts, from the sources, the audits and the verification passes.
79
+
80
+ **The CPU solver** (MAC grid; `quality.spec.js`, `REVIEW_02_PLAN.md`) measures:
81
+ - wall penetration exactly 0;
82
+ - `D∘G ≡ L`;
83
+ - sealed-vortex KE 0.80 after 1 s;
84
+ - warm post-divergence 2.96e-2 with red-black SOR against 2.8e-4 with MIC-PCG;
85
+ - 2.74 ms at 32×8×32 and 10.4 ms at 32³ a step.
86
+
87
+ How it is built:
88
+ - **Pressure is a projection potential in grid units:** `u −= p_R − p_L` with no dt and h = 1
89
+ (`v3_mac_subtract_pressure_gradient.js`).
90
+ - **Open faces read ghost pressure 0 with weight 1** in the diagonal (`v3_grid_solve_pressure.js`).
91
+ - **Sweeps:** `max(8, ceil(0.25 · max_res))` at `sor_optimal_omega`.
92
+ - **Fixed step:** 0.025 s.
93
+
94
+ **Effectors.**
95
+ - `GlobalFluidEffector` integrates `force + drag·(wind − v)` exactly. **With `force` and no `drag`
96
+ the velocity grows without bound** (its docstring); terminal velocity needs drag. `FluidSystem`
97
+ applies several globals one after another.
98
+ - Impulse and Wake triplicate their face loops and inline `(1 − t)²` four times. Wake allocates a
99
+ closure per `apply`.
100
+ - `syncFromTransform` copies translation only. Both fluid systems call the shared helper
101
+ `fluid_sync_effectors_from_transform`, one line each.
102
+ - A manual `Wake.apply` writes `previous_position` under a declared `Read`.
103
+
104
+ **Obstacles.**
105
+ - `FluidObstacleSystem` voxelizes through `PosedShape3D.signed_distance_at_point`, exact for every
106
+ shape.
107
+ - `FluidObstacle.hash()` covers only `inflation`; shape lives on `Collider` and motion on
108
+ `RigidBody`.
109
+ - ω×r is not modelled.
110
+
111
+ **Cloth** reads the CPU field. `AbstractClothWind.sample` must be pure in (time, point). Its clock
112
+ was the cloth's own age (MEASUREMENTS §57); under G2 the gust takes the scene clock and the gate is
113
+ restated (§12).
114
+
115
+ **The four winds:**
116
+ - `SceneVolumetrics.wind`: read only by `ParticipatingMediaSystem`.
117
+ - `ClothAmbientWind`: `gust` is a scalar peak in m/s and an exact bound, since the amplitudes 4/7,
118
+ 2/7 and 1/7 sum to one. Per axis it is three sinusoids at rates 1, 2.41 and 5.83 of `2π/period`,
119
+ with phase offsets φ, 2φ and 3φ, where φ is the axis's third of a turn. Period 4 s.
120
+ - `WaterWaves` per-body speed and direction:
121
+ - the cull pass sets a CPU `windy` gate from them, which gates the spectrum pass and envelope
122
+ seeding;
123
+ - `wind.w` packs the shore reflection;
124
+ - fetch depends on the direction;
125
+ - the derive pass starts a 4 s turn when the direction moves more than ~0.26°, and a later change
126
+ waits for that turn to finish.
127
+ - `GlobalFluidEffector.wind`.
128
+
129
+ **Cascade-like code all rolls its own.**
130
+ - The VSM is the only live toroidal clipmap.
131
+ - One hysteretic snap is copied twice.
132
+ - Toroidal wraps sit at ~10–13 sites.
133
+ - `GPUClipMap3D` is broken and is retired under G1.
134
+
135
+ **The engine already builds BVHs on the GPU.**
136
+ - `graph_bvh_build_lbvh` is **19 dispatches**: Morton, four digits of histogram + CSDLDF prepare +
137
+ scan + scatter, emission, refit (`GPU_BVH_BUILD_PLAN.md`: "~0.15 ms … across all 19 dispatches",
138
+ measured outside a frame).
139
+ - `GPUInstancesAccelerationStructure` drives it, and rebuilds only when its version moves:
140
+ - the host seeds ±inf with `encoder.writeBuffer`;
141
+ - the extraction pass (`shader_bvh_extract_instance_leaves`) writes leaf boxes and reduces their
142
+ union with subgroup min/max plus one atomic. Any bound on every centroid is valid.
143
+ - Leaves come from a CPU-compacted row list (`#refresh_rows`), because Karras breaks Morton ties by
144
+ leaf index.
145
+ - The build is deterministic for an ordered set of finite leaves: the radix sort is stable.
146
+ - The plan's motivations include that "the CPU cannot see GPU-authority transforms". The GPU tree
147
+ beat the CPU one on every axis at 20k instances, and was 1.9× worse in SAH at ~100.
148
+ - Traversal is the stack loop in `chunk_sdf_query_distance` / `chunk_ray_query_*`
149
+ (`BVH_TRAVERSAL_STACK_SIZE` 32, no visit cap). No AABB-overlap query exists.
150
+
151
+ **Subgroup-aggregated appends and reductions exist.**
152
+ - `chunk_vsm_append_mover` does exclusive add, `subgroupAdd`, elect, one `atomicAdd`, broadcast, and
153
+ counts past capacity.
154
+ - Min/max reductions: `shader_bvh_extract_instance_leaves`, `shader_meshlet_bounds_reduce`,
155
+ `shader_depth_reduce` and `shader_csm_caster_range`. The last records a measurement: a subgroup
156
+ reduction plus one atomic sufficed, and a workgroup step through shared memory measured the same.
157
+ - f32 sums: `sh_exp_workgroup_sum` (one vec4, valid in invocation 0, callable once a kernel because
158
+ its counter is never reset), the SH projection and the multiscatter LUT.
159
+ - **Three engine shaders state that local invocation indices need not map to subgroups in contiguous
160
+ blocks**, while three others assume they do.
161
+
162
+ **ECS-driven GPU work.**
163
+ - The `WaterSystem` / `GPUWaterSurface` shape.
164
+ - `GPUDatabase` tables, with the particle database's cross-database `node` link.
165
+ `GPUParticleEmitterSystem.apply_particle_effect` **compares each field while assigning it**: no
166
+ change signal and no hash. A generic accessor measured 228 B of boxing a call.
167
+ - `water_waves` mixes CPU-authored and GPU-derived fields ("the CPU writes what is authored … the GPU
168
+ writes what it derives").
169
+ - Transforms rows hold `global` and `prev_global`. Node globals are current at `FrameStart`:
170
+ `scene.tick` is encoded before the extensions.
171
+ - `TRANSFORM64_EVENT_PLACED` signals a teleport.
172
+ - `GPUSceneVolumetrics` clears and refills the whole volume table on every version change, inverting
173
+ a matrix and allocating a `Float32Array(16)` per repack. A non-zero noise velocity bumps the
174
+ version every frame. *Resolved in S3 (§6, D14): a scroll moves `SceneVolumetrics.noise_version`
175
+ alone and writes each moved row's six phase words; the repack keeps its scratch.*
176
+
177
+ **Constraints.**
178
+ - A tiny compute pass costs 5–8 µs. *(S1 measured back-to-back small dispatches at 1–2 µs on the
179
+ 4090; §14.)*
180
+ - No read-write storage textures are in use.
181
+ - `r32float` is core write-only storage and not filterable.
182
+ - Default limits: 16 KiB of workgroup memory, 256 invocations, 4 storage textures a stage, a floor of
183
+ 10 storage buffers.
184
+ - `shader_water_cull` already binds 10 storage buffers.
185
+ - Subgroups are optional in the floor and required in practice.
186
+ - Barrier kernels cannot run whole under the emulator.
187
+ - I-4: GPU readback never reaches gameplay.
188
+ - `getAnyComponent` allocates per call.
189
+
190
+ ## 2. What the field ships
191
+
192
+ Each source is tagged:
193
+ - **VERIFIED**: the primary text was read.
194
+ - **SECONDARY**: only an abstract, documentation or a write-up was read.
195
+ - **MEASURED**: our own CPU model.
196
+
197
+ **God of War (2018), Renard, GDC 2019 (VERIFIED).**
198
+ - One 32×16×32 volume at ~1 m, shifted with the player.
199
+ - Three-tier sampling: a static global vector, plus the volume, minus the object's own velocity.
200
+ - No projection.
201
+ - Motors: directional, omni, vortex, moving cone, cylinder.
202
+ - CPU audio and cloth read the previous frame.
203
+ - ~0.1 ms on PS4.
204
+
205
+ **NVIDIA Flow (VERIFIED, source).** One cold-started geometric-multigrid V-cycle a step (one Jacobi
206
+ smooth per level, four on the coarsest). The fallback is 40 Jacobi iterations.
207
+
208
+ **Cohen, Tariq & Green, I3D 2010 (SECONDARY).** A full multigrid cycle plus two V-cycles bought ~5
209
+ orders of magnitude. A warm start with flux prescribed on every face grew noise (the Neumann null
210
+ space). Uncoupled grids, blended near their edges.
211
+
212
+ **WRF (VERIFIED).** Nests specified from the parent; two-way face-mean feedback; Davies relaxation
213
+ `F1 = (1/10Δt)·(6 − n)/4`, n = 2..5; a moving nest's leading edge filled from the parent.
214
+
215
+ **Harris & Durran (SECONDARY).** Two-way nesting plus relaxation leaves negligible reflections.
216
+
217
+ **Filter precision (VERIFIED, Vulkan).** `subTexelPrecisionBits` must be at least **4 in core**, 8
218
+ under Roadmap 2022 / Vulkan 1.4 (docs.vulkan.org). D3D11 requires 8 (SECONDARY). WebGPU exposes
219
+ neither.
220
+
221
+ **Multigrid on this operator (MEASURED).**
222
+ - **Setup:** a CPU model of §8 (`mg2.mjs`, `sor.mjs` in the session scratchpad; random RHS, zero
223
+ guess, asymptotic factors): 64×32×64 coarsened to 4×2×4, 8-child-mean restriction, trilinear
224
+ prolongation, red-black Gauss–Seidel with ν = 2 + 2.
225
+ - **Residual factor per V-cycle:**
226
+
227
+ | | Global smoother | 8×8×4 frozen-halo block smoother |
228
+ |---|---|---|
229
+ | The CPU's open-face rule on every level | 0.661 | 0.750 |
230
+ | Finite-volume weight `2/(1+h/H)` | 0.103 | 0.296 |
231
+
232
+ The CPU rule puts the coarse Dirichlet point H/2 too far out, so the coarse correction overshoots
233
+ about 2×.
234
+ - **Depth and coarse-solve budget don't matter here.** With the block smoother and the finite-volume
235
+ weight, stopping at 8×4×8 (4 levels) gives the same 0.296 as stopping at 4×2×4 (5 levels). That
236
+ holds with 32, 64 or 400 sweeps on the coarsest level. The fine-level block smoother sets the
237
+ factor.
238
+ - **Red-black SOR at `sor_optimal_omega` (ω = 1.9065):** global, 0.267 after 16 sweeps and 2.2e-3
239
+ after 64. Run as a frozen-halo block with both colours per dispatch, it grows 2.2e2 after 16 and
240
+ 9.9e12 after 64.
241
+ - **The model-problem bound** `ρ = ω − 1 ≈ 0.9065` at that ω predicts 0.21 after 16 sweeps.
242
+
243
+ **Others (SECONDARY):**
244
+ - McAdams 2010 MGPCG: robust with irregular boundaries; needs a symmetric V-cycle.
245
+ - Compact Poisson Filters (Jacobi-bounded); covector fluids (conditionally stable).
246
+ - Lattice Boltzmann (dt tied to cell size).
247
+ - VXGI, Insomniac and RTXGI clipmap scrolling.
248
+ - The vgeo wavefront traversal precedent in this tree.
249
+
250
+ ## 3. Requirements
251
+
252
+ - **Real time in a browser, on modest GPUs.** No async compute; pass count and bandwidth both count;
253
+ dispatches follow live counts.
254
+ - **Every per-thread loop has a small fixed budget**, and the product of nested budgets is stated.
255
+ - **Subgroups and LDS from the start.**
256
+ - Stencil passes are LDS tile passes.
257
+ - Appends and reductions are subgroup-aggregated.
258
+ - No subgroup layout is assumed: partials take a subgroup reduction plus one atomic, which is what
259
+ CSM measured as enough.
260
+ - Barrier kernels keep their per-cell maths in pure functions for the emulator (§15).
261
+ - **One identity, two complete worlds.** Headless runs; gameplay never reads the GPU. CPU work is
262
+ O(changes + effectors + obstacles + queries).
263
+ - **Keep the effector framework.** The kernel skips an inexpressible effector explicitly, and it is
264
+ asserted in dev.
265
+ - **One fluid, read one way. No static/dynamic distinction.**
266
+ - Membership changes and drop counts are runtime facts, never authored categories.
267
+ - **Reuse first, generalise rather than copy** (§4, §19).
268
+ - **Binding budget:** the floor is 10 storage buffers. The water cull is already at 10, so the field
269
+ adds none there. Fluid passes stay ≤ 8 by choice, to leave headroom.
270
+
271
+ ## 4. The reuse map
272
+
273
+ The verdicts used below:
274
+ - **REUSE**: as is.
275
+ - **GENERALISE**: grows a parameter or variant, and its clients move onto it.
276
+ - **EXTRACT**: becomes shared, and its system migrates.
277
+ - **COMPOSE**: built from existing pieces.
278
+ - **NEW**: written generic, with a JS↔WGSL parity spec when it has both forms. Specs follow
279
+ `chunk_v3_apply_quat.spec.js`: top-level, no hooks.
280
+
281
+ ### 4.1 CPU side
282
+
283
+ | Need | Engine machinery | Verdict |
284
+ |---|---|---|
285
+ | Hysteretic snap; window origins; exposed regions | `fluid_reanchor_field.js:70-73`, `VirtualShadowMap.js:223-227`; `VSMPageManager` | **EXTRACT** `quantize_hysteretic`, `ClipmapWindowSet`, `window_scroll_regions`; the VSM and the CPU fluid migrate |
286
+ | Per-tick effector life and the far field | `fluid_sync_effectors_from_transform`, called by both fluid systems | **EXTRACT** `FluidEffectorsSystem`: once a tick it syncs transforms, calls a new `advance(dt)` on every effector (gust phases), folds the globals and integrates `v_far` and `Λ` (§6) |
287
+ | Far-field relaxation | `GlobalFluidEffector`'s exact ODE | **REUSE** for `u(t)` |
288
+ | Gust | `ClothAmbientWind` | **EXTRACT** into `GlobalFluidEffector`, meaning unchanged; `ClothAmbientWind` retired |
289
+ | Shape parameters as a record | cloth `ClothColliderKind`, `ClothColliderRecord` `PARAM_0..3`, `cloth_collider_pack` | **EXTRACT** the shape half into core; cloth composes it. Extended: rigid `Transformed`, `Union` runs, hull planes (zero planes skipped, capped at 16). |
290
+ | CPU obstacle SDF | `PosedShape3D.signed_distance_at_point` | **REUSE**: the CPU stays exact and is the oracle |
291
+ | Segment distance, AABB tests | `line3_compute_segment_point_distance*`, `aabb3_intersects_aabb3`, `aabb3_expand_array` | **REUSE**; inline copies migrate |
292
+ | Falloff, cone clamp, swirl, rigid velocity | inline / `v3_slerp` + `v3_angle_between` / none / inline at ≥ 10 physics sites | **NEW** `falloff_quadratic`; **COMPOSE** `v3_clamp_to_cone`; **NEW** `vortex_swirl`; **NEW** `rigid_velocity_at_point` (physics sites only under a flat allocation budget and bench) |
293
+ | Change detection | `apply_particle_effect`: compare each field while assigning | **REUSE as pattern**: rows are written only when a record field differs. Pose is excluded, since it comes from the node row. Obstacles compare their encoded shape parameters, inflation, v and ω. |
294
+ | Teleport | `TRANSFORM64_EVENT_PLACED` | **REUSE**: `GPUSceneRows` seeds `prev_global = global` on it |
295
+ | CPU lattice sampling | `scs3d_sample_linear3_array` (planar) | **GENERALISE**: a strided variant |
296
+ | Row holds, record writer, singleton | `RowChains`, `generate_record_writer`, `getAnyComponent` | **REUSE**; **GENERALISE** a non-allocating singleton accessor |
297
+
298
+ ### 4.2 WGSL
299
+
300
+ | Need | Engine chunk | Verdict |
301
+ |---|---|---|
302
+ | Toroidal coordinate; finest containing cascade | `chunk_mod_v3i`; CSM blended-cascade shape | **REUSE** in `chunk_clipmap_storage_coord`; **NEW, concrete** `chunk_clipmap_select_finest` |
303
+ | Flat ↔ 3-D index | `chunk_grid3d_to_index`, `chunk_index_to_grid3d`, `chunk_folded_workgroup_index` | **REUSE** |
304
+ | 3-D tile + halo | none: 31 LDS shaders, mostly 1-D, none a 3-D tile | **NEW** `chunk_grid_tile_halo_f32` / `_vec4`: window-local indexing, toroidal wrap by conditional subtract, a caller-supplied out-of-window fetch, one barrier |
305
+ | Trilinear corners; 3-D texel helpers | inside `chunk_sdf_texture_region_sample_linear_uv`; 2-D helpers | **EXTRACT** `chunk_texture3d_trilinear_corners`; **GENERALISE** 3-D siblings |
306
+ | Primitive SDFs | box inside `chunk_aabb3_signed_distance_to_point`; plane `chunk_point_distance_above_plane` (`+w`); max of planes `chunk_frustum_sdf` | **EXTRACT** box; **REUSE** plane (`w = −offset`) and max of planes; **NEW** sphere, capsule, cylinder |
307
+ | Segment distance; cone clamp; AABB overlap | `chunk_point_distance_to_line` (unguarded); `chunk_v3_angle_between`, `chunk_quat_from_unit_vectors`, `chunk_quat_rotate_v3`; none | **GENERALISE** (guard + spec); **COMPOSE**; **NEW** `chunk_aabb3_intersects_aabb3` |
308
+ | BVH build | `graph_bvh_build_lbvh` (19 dispatches), refit via its returned Morton order | **GENERALISE**: a small-scene path. At ≤ 1,024 leaves (one sort tile), one 256-thread workgroup builds the whole tree in one dispatch, with Morton, a (key, index) bitonic sort in workgroup memory, emission and refit, reusing the builder's chunks. Above 1,024 the multi-pass path is unchanged. The TLAS gains the same path for small scenes. **Landed** on master `b523718db` (2026-10-16), with `chunk_sort_bitonic_comparator`, which the cooperative query also sorts with. |
309
+ | Leaf extraction + centroid bound | `shader_bvh_extract_instance_leaves` (subgroup min/max + one atomic, host-seeded ±inf) | **REUSE as template** |
310
+ | BVH query | traversal loops (ray, point, distance; no visit cap) | **NEW** `chunk_bvh_query_aabb_cooperative`: one workgroup per query box, a level-synchronous frontier in LDS (the vgeo wavefront precedent), so per-thread work is bounded by tree depth |
311
+ | Append | `chunk_vsm_append_mover` | **GENERALISE** into a `COLLECTION_U32` append; the VSM migrates; the fluid's lists use it |
312
+ | Reductions | `chunk_atomic_{min,max,add}_f32_storage`; the CSM measurement | **REUSE**: subgroup reduction + one atomic, no workgroup step, no layout assumption |
313
+ | Node pose; indirect command | `scene_read_node`; `build_indirect_compute_dispatch_command` | **REUSE** |
314
+ | MAC maths | CPU `v3_mac_*`, `v3_grid_limit8_at_indices`, `v3_mac_clip_trace` | **NEW** `chunk_v3_mac_*`: per-cell pure functions over a tile accessor (§15) |
315
+
316
+ ### 4.3 Host and GPU infrastructure
317
+
318
+ | Need | Engine machinery | Verdict |
319
+ |---|---|---|
320
+ | Records | `GPUDatabase`; the particle precedent (own database, cross-database `node` link) | **REUSE**: `FLUID_DATABASE_SPEC` |
321
+ | Readback | `GPUDatabaseReadback` (consecutive rows coalesce); `GPUEntityBoundsReadback` | **REUSE** + **GENERALISE** `request_run` (one handle and status per query, a smaller upload) |
322
+ | Published atlas | `GPUTileAtlas3D` | **GENERALISE**: per-axis content + `chunk_tile_atlas_slot_origin` on `chunk_index_to_grid3d`; the noise tap and the SDF slot maths migrate |
323
+ | Volume phase writes | `GPUSceneVolumetrics` (full repack on version) | **GENERALISE**: phase fields written per row with `set_fields`, so no repack and no per-repack allocation for a moving phase (§6) |
324
+ | Textures, transients, passes, profiling | `GPUTextureContext`, 3-D `TextureResourceDescriptor`, `ComputeShader`, `setImmediate`, upload helpers, `push_scope`, `GPUProfileSession`, `graph_record_stat` | **REUSE** |
325
+ | Producer lifecycle; pass shape | `GPUWaterSurface`; the volumetric TAA pass | **REUSE as pattern** |
326
+ | 3-D debug view | `draw_texture_as_rgba` | **GENERALISE**: a 3-D slice mode; `shader_debug_clipmap` rewritten as the cascade overlay (G1) |
327
+
328
+ ## 5. Architecture
329
+
330
+ ```
331
+ ECS (engine/physics/fluid/ecs/) Graphics (engine/graphics3/, shade/renderer/fluid/)
332
+ ────────────────────────────────────────────── ──────────────────────────────────────────────────
333
+ FluidEffectorsSystem (once a tick): GPUFluidSystem(graphics, scene)
334
+ syncFromTransform; advance(dt); CPU, headless-safe: far_field(out), request()/status
335
+ fold globals → v_far(t), Λ(t) ─────────────────► (from FluidEffectorsSystem; far field when no device)
336
+ FluidSystem / WorkerFluidSystem (CPU fields) GPU, FrameStart: rows → LBVH (build/refit, once a frame)
337
+ apply the folded atmosphere once per step → per pending tick: brick queries → forcing → cascade
338
+ GPUFluidComponent + Transform64 ─────────────────► steps → publish → GPUSceneContext.wind
339
+ FluidEffectorsComponent / FluidObstacle tuple ───► GPU consumers: particles VM, water cull, query gather
340
+ CPU consumers ask GPUFluidSystem: cloth adapter, → chunk_wind_field_sample(p)
341
+ volumetrics, audio
342
+ ```
343
+
344
+ **`FluidEffectorsSystem`** (extracted; its name matches `FluidEffectorsComponent`). Once per tick,
345
+ before every fluid system (declared `Write` on `FluidEffectorsComponent`; the fluid systems declare
346
+ `Read`):
347
+ - `syncFromTransform` for entities with a `Transform64`;
348
+ - `advance(dt)` for every effector;
349
+ - the fold and the far-field integration (§6).
350
+
351
+ It is the single owner of `v_far` and `Λ`, so no trail, phase or far field is advanced twice. The
352
+ fluid systems drop their own sync line. The census runs before and after.
353
+
354
+ **`GPUFluidComponent`.** Data only, adapter v0:
355
+ - `resolution`: per axis, a power of two in [32, 256];
356
+ - `cell_size`;
357
+ - `cascade_count` (1..8);
358
+ - `vorticity_confinement`;
359
+ - `enabled`.
360
+
361
+ There is no `velocity_damping`, because relaxing toward zero fights the far field.
362
+
363
+ **`GPUFluidSystem`** (`engine/graphics3/`, registered wherever `WaterSystem` is):
364
+ - **CPU half, headless-safe:** `far_field(out)` and `request(...)`.
365
+ - **GPU half (`FrameStart`):**
366
+ - records pending ticks (`fixedStepTick` minus the last recorded, capped at 2; the excess is
367
+ counted);
368
+ - keeps the fluid database, the LBVH, the cascades and the published field;
369
+ - rebuilds on restart;
370
+ - holds rows with `RowChains`.
371
+ - **`GPUSceneContext` always constructs a `GPUSceneWind`** (zero cascades, `v_far` = 0), so consumers
372
+ can bind it unconditionally with no fluid system present. `GPUFluidSystem` fills it.
373
+
374
+ *S4, built (2026-10-16): `GPUFluidComponent` (adapter v0, 24 bytes) and `GPUFluidSystem`, registered beside
375
+ `WaterSystem` in `EngineHarness`.*
376
+ - **Ticks.** At `FrameStart`, the ticks `fixedStepTick` advanced since the last recording frame, at most two
377
+ (the latest), the rest counted (`dropped_tick_count`); each steps at `fixedUpdateStepSize` against the far
378
+ field at the end of the frame's last tick. Then `record_publish`, and the field's table is uploaded at once,
379
+ since the scene context uploads it before `FrameStart`.
380
+ - **Node motion** is taken over `1/(frame_dt·fixedStepTimeScale)`, `frame_dt` the wall time the system's
381
+ `update` saw since the last `FrameStart`: the hierarchy pass copies `global` into `prev_global` once a
382
+ rendered frame.
383
+ - **Rows** are kept in `update`, so a chain held this frame is in the scene's rows before the frame reads it.
384
+ Effector membership is by identity; an obstacle is packed again when its collider is handed another shape.
385
+ - **No domain:** nothing is recorded or held on the device, and the wind field is `v_far` alone.
386
+ - **One domain** (F2, R1): the enabled component on the lowest entity id. Any other is dormant and holds
387
+ nothing on the device until it takes over (§18).
388
+ - `vorticity_confinement` reaches every step of every tick (S4d, §8): `record_tick`'s
389
+ `vorticity_confinement`, read from the component each frame, the cascades kept.
390
+
391
+ ## 6. The far field, and what reads the fluid
392
+
393
+ **`GlobalFluidEffector`** keeps `force`, `wind` and `drag`, and gains:
394
+
395
+ ```js
396
+ gust = 0 // m/s, scalar peak — ClothAmbientWind's meaning: a bound, |g| ≤ gust per axis
397
+ gust_period = 4 // s
398
+ // state, advanced by advance(dt): phase_k ← frac(phase_k + dt·rate_k/period), rates 1, 2.41, 5.83
399
+ ```
400
+
401
+ `g_axis(t) = gust · Σ_k a_k · sin(2π·phase_k + (k+1)·φ_axis)`, with amplitudes 4/7, 2/7 and 1/7 and
402
+ φ the axis's third of a turn. That is `ClothAmbientWind` term for term. The phases are integrated, so
403
+ editing the period never jumps.
404
+
405
+ **The fold and the far-field state** (`FluidEffectorsSystem`, f64, once per tick):
406
+ - **Fold:** `D = Σd`, `W = Σd·w / D` (the globals' steady winds), `g = Σ gusts`.
407
+ - **Steady part:** `u ← W + (u − W)·e^(−D·dt)`, exact. It is seeded at `W` only on
408
+ `FluidEffectorsSystem`'s first fold, so a scene that starts with a global starts in steady state;
409
+ a global that arrives later relaxes `u` from where it is; `u` holds when `D = 0`.
410
+ - **State:** `v_far = u + g`. `Λ += D·dt`.
411
+ - **The gust is added, not filtered.** Filtering it through `drag` kept only 16% / 61% / 84% of the
412
+ authored gust at the drags in the tree's specs (0.35 / 2 / 5), shrinking cloth gusts 2–6×.
413
+ - **`force` is not part of the far field.** A world-wide body force would be an unbounded downdraft
414
+ at `D = 0`, and a world downdraft read by water and cloth at `D > 0`. It stays a CPU-field term, as
415
+ today. The GPU path drops it, with a dev assert, and buoyancy is its successor with scalars (§20).
416
+ - A scene that never had a global is still air; after the last global goes, the far field holds —
417
+ calm is authored as a global with wind 0 and a drag.
418
+ - **The far field's state is warmed up, never saved** (Alex, 2026-10-16: "warm up instead of saving
419
+ the state … like particle simulation state - it's inherently transient"). `u`, `Λ` and the
420
+ cascades live on the systems; a load or a restart seeds `u` at the globals' `W` on its first fold
421
+ and the cascades at `v_far`, and a rollback re-simulates nothing of them. Only the effectors'
422
+ authored fields and gust phases are saved.
423
+
424
+ **The atmosphere identity.**
425
+ - At every step (both executors): `v ← v_far(t₁) + (v − v_far(t₀))·e^(−(Λ(t₁) − Λ(t₀)))` per face.
426
+ - At every read of cascade *c*: `v_read = v_far(t) + (v_c − v_far(t_s,c))·e^(−(Λ(t) − Λ(t_s,c)))`.
427
+ `t_s,c` is the cascade's last step, recorded with `v_far(t_s,c)` and `Λ(t_s,c)`.
428
+ - **Why it is exact:**
429
+ - Air that only the atmosphere acts on relaxes toward `v_far` at `D` while carrying `v_far`'s own
430
+ acceleration. Its deviation `e = v − v_far` obeys `de/dt = −D·e` for any `v_far(t)`, so the
431
+ update is exact whatever the gust does and however `D` varies (`Λ` integrates it).
432
+ - A cell equal to the far field reads as the far field at every instant, on every cascade, between
433
+ steps and across dropped ticks.
434
+ - **What it replaces in revision (d):**
435
+ - the far-field ring, and its off-by-one;
436
+ - the published tile frozen against the live far field between a coarse cascade's steps;
437
+ - the parent reads that saw a stale uniform part.
438
+ - **CPU consumers of the identity:**
439
+ - The GPU gets per cascade one uniform pair, `v_far(t_s,c)` and `k_c = e^(−(Λ(t) − Λ(t_s,c)))`,
440
+ computed on the CPU each frame: one FMA a read, and no large numbers on the device.
441
+ - **The CPU fluid applies the same folded atmosphere once per step** through the same identity, so
442
+ the executors agree exactly. Several globals no longer split order-dependently, and `force`
443
+ still adds `F·dt` inside CPU fields.
444
+
445
+ **The read, everywhere:**
446
+ - the finest cascade containing the point, through its identity;
447
+ - in a cascade's edge band, blended with its parent's identity read, and in the coarsest cascade's
448
+ band, blended with `v_far`;
449
+ - outside every cascade, `v_far`.
450
+
451
+ **What reads it:**
452
+
453
+ | Consumer | How |
454
+ |---|---|
455
+ | Particles | `SAMPLE_WIND` → `chunk_wind_field_sample` |
456
+ | Water | **Built (S3).** The cull pass samples `wind_field_sample` 10 m above each body's origin (U10), binding the field's uniform, texture and sampler: its storage buffers stay the ten it had, at the floor. **One** per-body low-pass of the sample, `wind ← s + (wind − s)·e^(−dt/20 s)` over the frames that step, in a GPU-written wave-row field (`wind` + `wind_seeded`) and seeded from the first sample whether the frame steps or not, feeds fetch, the derivation and the turn, taken in the body's metric local xz. A derivation fires only when the low-passed wind leaves a deadband about what it was derived for (5% of speed, 3° of direction; `derived_for` is now speed, fetch and direction) or the fetch along that direction changes; a turn only when the direction leaves 3° of the one the waves turned to; a change during a turn waits for it, as before. Every body's wind is kept, hidden ones too, since their weights bound them. `windSpeed`/`windDirection` left `WaterWaves` (adapter v2, `WaterWavesSerializationUpgrader_1_2` drops them). The record's re-layout keeps the shore reflection, as `shore_reflection`. **The CPU `windy` gate** is "any enabled `GPUFluidComponent`, or `far_field` non-zero", without allocating (`getAnyComponentInstance`; the others are walked only when the lowest holder is disabled). **Measured** (RTX 4090): an impulse at the lake's U10 point, inside a domain's cascades, moved the lake's wind 0.75 m/s off a body outside them in 20 s; the culling dispatch 49 → 54–56 µs on four bodies; the frame unchanged within its run-to-run spread. A seed carries the gust of its instant (up to `gust` per axis), which the low-pass forgets over ~20 s. |
457
+ | Volumetrics | **Built (S3), reworked on Alex's correction (§22).** **The far field is the host's:** `ParticipatingMediaSystem` folds `GPUFluidSystem.far_field` (the effectors' fold: synchronous, deterministic, nothing read back) × `noise_wind_factor` + `noise_velocity` into each noisy volume's phases; no `GPUFluidSystem` is still air. **The departure is the GPU's, wherever the noise is evaluated:** the froxel build samples `wind_field_sample` once a froxel at its jittered noise point, the tracer and the bakes at each density point (`participating_media_volume_density_at`), and `chunk_participating_media_noise` carries the noise by `d = (w(p) − v_far(t)) × noise_wind_factor` as a flow map: two phases half a period apart, `φ₀ = fract(s)`, `φ₁ = fract(s + ½)`, each moving the lookup by `−d·φₖ·P` (tile units), triangle-weighted so each resets at zero weight, the warp tap shared; `s = t/P` is a per-row word the host folds (`noise_flow_phase`, beside `noise_wind_factor` in the row's padding: still 240 B). Below a reach of `1/(2·255·35.3)` = 5.6e-5 tile units a period one tap, the uniform-air path (the tile's steepest gradient, read back, is 35.3 a tile unit, so the neglect is under half an `r8unorm` step); the reach ramps in to twice that, so the branch is continuous. **P = 2.5 s:** the pulse (rms of the crossfade term over the transport term, a function of `λ = |d|·P/noise_scale` alone: ~1 to λ ≈ 0.08, 0.47 at 0.32) and the stretch (`σ_max(I − φ·P·∇d) − 1`) medians cross at 2.48 s where |d| ≥ 1 m/s at the default 32 m scale (2.06 s at 16 m, 2.4–2.9 s over |d| ≥ 0.5 m/s), measured on the 4090 over a wake circling at 10 m/s beside a vortex. Every reader binds the field (uniform, texture, sampler; no storage buffer). **The phases go up per row with `set_fields`**: a scroll or the flow clock moves `SceneVolumetrics.noise_version` (`invalidate_noise()`) and not the version, and `GPUSceneVolumetrics` writes the seven phase words of each row whose f32 phases changed; anything else still repacks. The system compares while assigning and reads the transform's lanes; `set_fields` asserts with constant messages. `SceneVolumetrics.wind` is removed. **Measured:** the froxel build on the 4090 at 1280×720, the camera inside the fog, A/B against the old shader by frame blocks in one capture: uniform air 16.4 → 18.3 µs, with a domain, a wake and a vortex 15.4 → 19.4 µs; the uniform-air 1.9 µs is the flow map's code being there (without it 0.1–0.2 µs off the old; skipped by an exact compare, still 1.8). In calm air with a domain, the frame-to-frame change of the picture gathers around the vortex and the wake's path; without one the fog stands. *The S3 per-row write, in node with 64 noisy volumes: `GPUSceneVolumetrics.update` 41.5–46.5 µs and 72.3 KB a frame → 2.6–2.7 µs and nothing a volume.* |
458
+ | Cloth | `ClothGPUFluidWind`, an adapter over the system (§12). `ClothAmbientWind` is retired. `ClothFluidWind` stays for CPU fields with `ambient = far_field`. |
459
+ | Audio, presentation | `request` or `far_field` |
460
+ | Gameplay | `far_field` only. It is deterministic given the effectors' serialized phases (§16); the fluid is presentation (I-4). |
461
+
462
+ **Playground cost.** The water-surface playground's four per-body winds (cup 2, puddle 4, lake 6, ocean
463
+ 10 m/s) became one fluid: a `GlobalFluidEffector` far field (8 m/s by default, a gust slider) and a
464
+ `GPUFluidComponent` on the stop's body. Sea states differ by fetch and by the field around each body: at
465
+ 8 m/s the ocean is a little lower than at its old 10, the others higher; all four stay recognisable
466
+ (screenshot tour against the previous tree). On the 4090 at the ocean stop a frame that ticks spends 339–367 µs
467
+ in fluid passes with a coarse step and 189–195 µs without (p10 of per-frame timestamps), the bonfire's tick less
468
+ its forcing (§14). *S3 first read 1.09–1.13 ms a frame from 2.5 s captures in which every water pass also ran
469
+ ~3× its time (coherent optics 1.77–2.19 ms against 0.64–0.70): the GPU was slow then, not the fluid (§14).*
470
+
471
+ ## 7. The shared clipmap module, and the cascades on it
472
+
473
+ **The module** (`core/geom/clipmap/`):
474
+ - `quantize_hysteretic`;
475
+ - `ClipmapWindowSet` (integer corners, placed flag, version, `place`, `contains`, `storage_cell`,
476
+ `decode`);
477
+ - `window_scroll_regions` (disjoint k-D boxes);
478
+ - WGSL: `chunk_clipmap_storage_coord`, `chunk_clipmap_contains`, `chunk_clipmap_select_finest`.
479
+
480
+ **Migrations:**
481
+ - the VSM's window bookkeeping and strip eviction (scroll specs re-pointed, masks unchanged);
482
+ - the VSM depth snap and `fluid_reanchor_field` onto `quantize_hysteretic`;
483
+ - the CPU fluid's patch edges stay: corner order is load-bearing, and they were judged not worth
484
+ unifying.
485
+
486
+ **Cascades.**
487
+ - `N = resolution` per axis, all active. Cell `h_c = cell_size · 2^c`.
488
+ - Corners are multiples of 4: even for exact restriction, and in 4s for brick alignment of
489
+ cell-centred data.
490
+ - **Re-placement:** when the anchor is more than 2.1 cells from the window centre, on the cascade's
491
+ own step tick, coarsest first.
492
+ - **Nesting:** the child's corner is clamped into its parent's interior. *S2:* the interior is the
493
+ parent's window less the published read's edge band, 5 parent cells (`FLUID_CASCADE_NEST_MARGIN`),
494
+ so a read never needs a third tap; on the 4-cell corner lattice the margin kept is 6, so cascades
495
+ nest from 32 cells an axis. A parent placing on its own tick is held the same way by its unmoved
496
+ child. Measured cost (20,000 ticks of a random walk at 64×32×64): nothing held off its own placement
497
+ at 10 m/s; at 40 m/s with vertical motion, 0.4–0.8% of ticks, the anchor at most 7.1 of cascade 0's
498
+ cells from its centre on the 32-cell axis.
499
+ - **Jumps:** a jump that would leave a child outside its parent re-places the whole stack.
500
+ - **Exposed regions** refill from the parent's identity read, or from `v_far` with pressure 0.
501
+ - **The far field is a parent with no window**, which reads `v_far` and pressure 0 (*S2*).
502
+
503
+ **Storage.**
504
+ - `u`, `v`, `w` are `r32float` 3-D textures of (N+1)×N×N, N×(N+1)×N and N×N×(N+1), each toroidal
505
+ with period N+1 along its own axis and N on the others. Every face of the window is stored, and a
506
+ scroll by Δ exposes and vacates Δ slots on every axis.
507
+ - **Pressure:** `array<f32>` of N³, period N, **physical kinematic pressure (m²/s²)**, so
508
+ `u −= (dt_c/h_c)·(p_R − p_L)`.
509
+ - **Units across cascades:** parent and child pressures share units, so Dirichlet halos and fill warm
510
+ starts need no rescaling. The CPU's projection potential (grid units, no dt) is the same field
511
+ scaled by `dt/h²`, and parity specs apply that scale.
512
+ - **Ghosts are never persistent.** A step's first pass (`shader_fluid_cascade_ghosts`) evaluates
513
+ the parent's read once into the step's transients: its identity read at every face of a shell
514
+ `FLUID_CASCADE_GHOST_DEPTH` = 6 faces deep around each face lattice, and its pressure at the
515
+ centre of every cell one past the window. A tile at the window edge takes its halo from them
516
+ (pressure, Dirichlet; tangential velocity, through the identity), and an advection corner outside
517
+ the window reads one texel of them where the parent read takes eight. The depth holds every read
518
+ of a step whose far field crosses at most a cell (a carrier one face out, a trace of
519
+ `|v_far|·dt/h + 4` cells under the deviation clamp, its tap one more); a read past the shell takes
520
+ the parent itself, so the depth sets the cost, never the answer.
521
+ - **Tiles are window-local**, 8×8×4: `N/8 × N/8 × N/4` tiles. Storage indices come from a
522
+ conditional subtract, because the face period N+1 is odd. The +boundary face plane, index N, is
523
+ owned by the last tile along its axis in every pass that writes faces (advect correct, gradient,
524
+ fill).
525
+
526
+ **Scroll fill.** `window_scroll_regions` gives bricks, and one dispatch writes faces and pressure.
527
+ *S2:* 4×4×4 bricks tile the boxes exactly; the dispatch is the live brick count, folded past 65,535.
528
+ Fills, steps and seams read a parent as of the reading cascade's own record, so a newer parent's
529
+ deviation is read back by `e^(+ΔΛ)`, its exponent held at 64.
530
+
531
+ ## 8. The solver step
532
+
533
+ **Kept from the CPU, all measured in its gate and GPU-neutral:** the MAC discretisation (wall
534
+ penetration exactly 0, `D∘G ≡ L`), MacCormack with Selle's limiter and solid-clipped traces,
535
+ semi-Lagrangian scalars, open boundaries and warm starting.
536
+
537
+ **Departs, on measurement:**
538
+
539
+ **(1) Pressure: a geometric-multigrid V-cycle.**
540
+ - **Cell-centred**, coarsening N → N/2 down to the first level that fits one workgroup at one cell
541
+ per thread: 64×32×64 → 8×4×8 = 256 cells, three coarsenings. Going on to 4×2×4 measured no better
542
+ (§2) and costs four more passes. Restriction is the 8-child mean, prolongation trilinear.
543
+ - **Coarse operator:** each level's operator is the 7-point Laplacian over `H²` (physical units). An
544
+ open face has the **finite-volume weight `2/(1+h/H)`**, which keeps the Dirichlet point at the fine
545
+ ghost centre on every level.
546
+ - The CPU's weight-1 open-face rule on every level was measured to stall the V-cycle at 0.661
547
+ (global smoother) and 0.750 (block smoother, 4×2×4 coarsest); with the 8×4×8 coarsest at 8
548
+ sweeps, 0.554.
549
+ - A Galerkin coarse operator is the alternative, if obstacles demand it. *S1:* obstacles measured
550
+ 0.43 a cycle, so they do not.
551
+ - **Solids:** a coarse cell is solid iff all eight children are; a coarse face's weight is the open
552
+ fraction of its child faces.
553
+ - **Smoother:** the CPU's red-black kernel, **with a colour mask**, on LDS tiles. One dispatch loads
554
+ an 8×8×4 tile plus a 1-cell halo (2.4 KB), runs ν colour-alternating sweeps against the frozen
555
+ halo, and writes the interior. ν = 2 + 2.
556
+ - **ω = 1 whenever both colours share a dispatch, asserted.** The CPU's ω = 1.9065 in that
557
+ configuration diverged (×9.9e12 in 64 sweeps).
558
+ - **Coarsest level:** one 256-thread workgroup in LDS (1 KB), **8 sweeps**, one dispatch. *S1,
559
+ measured:* 32 sweeps were a third of a V-cycle on the 4090 (21.5 of 62 µs). On the CPU model, 8
560
+ sweeps (even 2) leave the factor unchanged to three digits on every window of three or more levels,
561
+ open and with obstacles. The two-level 16×8×16 window sets the count: 0.178 at 8 sweeps, 0.174 at
562
+ 32, 0.345 at 4.
563
+ - **Measured** (64×32×64, ν = 2 + 2; the CPU model `shade/renderer/fluid/pressure/__fixtures__/fluid_mg_model.js`,
564
+ matched on the 4090):
565
+ - 0.103 per V-cycle with a global smoother;
566
+ - **≈ 0.30 per V-cycle with the block smoother**: 0.296 by cycle 6, 0.298 at 16, 0.302 at 60, so the
567
+ asymptote sits just above 0.30. **0.43 with obstacles** (a sphere plus 5% scattered solids). The
568
+ weight-1 rule stalls at 0.554;
569
+ - **10 dispatches a V-cycle, 3L − 2**: 3 × (smooth, residual + restriction) down, the coarsest, 3
570
+ smooths up. Prolongation is pointwise, so it is folded into the next smoother's tile fetch, bit for
571
+ bit. A solve adds **L weight dispatches** (4 here), because the solid flags may change every step;
572
+ - red-black SOR (32 passes for 16 sweeps) reaches 0.267.
573
+ - **Smoothers never run in place.** A tile writing its interior races a neighbour that is loading it as
574
+ halo, so every smoother writes another buffer: one N-cell scratch on the finest level, and two error
575
+ buffers per coarse level.
576
+ - **Weights:** one u32 a cell, six faces of 5 bits, open area in sixteenths; a coarse face is the mean
577
+ of its four children, rounded up.
578
+ - **The SOR arm** is the same kernel with the coarse correction off, **one colour per dispatch**, at
579
+ `sor_optimal_omega`: 2K passes. *S1, measured on the 4090 from a cold start at 64×32×64:* the
580
+ V-cycle reaches 0.1 of the start in 59 µs (1 cycle) against SOR's 173 µs (26 sweeps), and 0.01 in
581
+ 110 µs (2 cycles) against 327 µs (49 sweeps); 162 µs (3 cycles) with obstacles. **V-cycles are the
582
+ default.**
583
+ - **Two V-cycles a step** (`GPU_FLUID_CASCADE_V_CYCLES`). One fails the projection quality gate: max
584
+ |div| 1.62× the CPU's after one step and 4.96× after ten. The second costs 38 µs at 64×32×64 and
585
+ 72 µs at 128×32×128.
586
+ - **Escalation for obstacle-dense scenes:** MGPCG. It needs a symmetric V-cycle (restriction ∝
587
+ prolongationᵀ, post-smoothing in reversed colour order). Its two dot products are subgroup
588
+ reductions plus one atomic each. It is valid because every system is non-singular (§9).
589
+ - **Warm start:** the previous step's pressure, safe under Dirichlet boundaries.
590
+
591
+ **(2) Advection: manual trilinear, f32.**
592
+ - Vulkan core guarantees 4 bits of filter weight (1/16 cell), enough to swamp MacCormack's
593
+ second-order correction. The limiter needs the 8 corners anyway.
594
+ - So `chunk_texture3d_trilinear_corners` loads 8 corners per component per trace end from the
595
+ component's toroidal texture (from the parent outside the window), with exact f32 weights, and
596
+ feeds the limiter its min and max.
597
+ - Velocity is `r32float` for that reason.
598
+ - **Traces** are bisection-clipped against solids (`v3_mac_clip_trace`), with a fixed budget,
599
+ through the brick gate (§10).
600
+ - **Advection reads textures**: traces are data-dependent, and the texture cache serves them. An
601
+ LDS-tiled *predict* pass with a 2-cell halo fits:
602
+ `13×12×8 + 12×13×8 + 12×12×9` f32 = 14.8 KiB of 16. The *correct* pass needs φⁿ and φ̂ (29.6 KiB)
603
+ and does not fit. That makes predict an S1 lever.
604
+ - *S1, measured on the 4090:* manual trilinear costs 1.09× hardware's in predict at 64×32×64 and 1.19×
605
+ at 128×32×128 (11.3 against 10.2 µs, 33.8 against 27.7 µs). Advection is 22–30% of a step, so the
606
+ LDS predict pass was not built.
607
+
608
+ **(3) LDS and subgroups.**
609
+ - **Stencil passes** on 8×8×4 LDS tiles (`chunk_grid_tile_halo_*`): curl, the smoother (with the
610
+ prolongation folded into its fetch), residual + restriction, gradient + publish. *S1, measured:* the
611
+ divergence reads its faces straight from the textures, 2× faster than its tile on the 4090 (4.1 →
612
+ 2.0 µs at 64×32×64, 9.2 → 5.1 µs at 128×32×128). Direct reads in the gradient measured level at
613
+ 64×32×64 and 0.92× at 128×32×128, so the gradient keeps its tile.
614
+ - **Gradient + publish share one pass.** The final velocity is in LDS for the collocated average,
615
+ and the pass writes four storage textures: u, v, w and the atlas tile.
616
+ - **Subgroups:**
617
+ - appends through the generalised `COLLECTION_U32` append;
618
+ - reductions through a subgroup op plus one atomic;
619
+ - no `subgroupShuffle` stencils, and no layout assumptions.
620
+ - **Hot loops** follow the measured local-memory rule: no runtime vector-component indexing, no
621
+ function-local tables, integer counters.
622
+
623
+ **Order** (one projection a step; the end-of-step field is the next step's divergence-free carrier):
624
+
625
+ | # | Pass | Grid |
626
+ |---|---|---|
627
+ | 0 | scroll fill (after a placement) | exposed bricks |
628
+ | 1 | curl (confinement on) | tiles |
629
+ | 2 | advect predict | full |
630
+ | 3 | advect correct + limiter + atmosphere (identity, §6) + confinement + relaxation band (WRF rows 2..5 toward the parent's identity read) + **deviation clamp** `\|v − v_far\| ≤ 4·h_c/dt_c` (the teleport backstop, which never clamps the wind itself) | full |
631
+ | 4 | divergence of `velocity_mid + forcing`, pinned faces at wall velocity | cells, direct reads |
632
+ | 5 | the solve's weights (L passes), then two V-cycles (10 passes each); non-finite pressure and RHS zeroed on read, and the counter records them | tiles |
633
+ | 6 | gradient + publish; records `t_s, v_far(t_s), Λ(t_s)` for this cascade | tiles |
634
+ | 7 | restrict into the parent (before the parent steps) | parent ∩ child interior |
635
+
636
+ *S4d, built and measured (2026-10-16): pass 1 and the confinement in pass 3.*
637
+ - **Pass 1, curl** (`shader_fluid_mac_curl`), recorded only for a step whose `vorticity_confinement`
638
+ is above 0, after the ghosts and before predict. An LDS tile pass, 8×8×4 cells and two barriers: the
639
+ centre velocity of the tile and two cells around it (12×12×8, 3 × 4,608 B), then `|ω|` of the tile
640
+ and one cell around it (2,400 B), 16,224 of the 16,384 bytes a workgroup may have. It writes each
641
+ cell's `½·ε·dt·(N × ω)` into a transient of 3·N floats: the CPU kernel's three passes
642
+ (`chunk_v3_mac_vorticity_confinement`), its edge ring, solids and 1e-10 floor kept. The differences
643
+ are per cell on velocity in m/s, so the force is Fedkiw's `ε·h_c·(N × ω)·dt_c`, each cascade with
644
+ its own `h_c` and `dt_c`, as the CPU scales `ε·dt`.
645
+ - **Pass 3** adds a face's two cells' halves (the CPU's scatter, gathered) after the atmosphere
646
+ identity and before the band and the clamp, on every face that is not pinned. Off, the step's
647
+ `confinement_dt` is 0, a uniform branch skips the term, and no curl is recorded.
648
+ - **Against the CPU:** the CPU adds its force before advection and the GPU after, so one step at ε = 12
649
+ gives the GPU 1.05× the CPU's increment, cos 0.992. A sealed vortex at ε = 3 keeps 1.18 of its peak
650
+ vorticity on the GPU over 60 steps against 1.09 on the CPU (0.50 without, both); at ε = 12 with no
651
+ damping both grow, the GPU's more (1.77 against 1.22). Emulator parity at 16³ with solids and a
652
+ moving wall: every face is the CPU's increment to 16 ulps of the largest push and an ulp of the face.
653
+ - *RTX 4090, ε = 4:* the curl 8.2 µs a step at 64×32×64 and the correct pass +1.0 µs; a tick of cascade
654
+ 0 alone +8.2 µs (144.4 → 152.6), a tick with a coarse step +16.4 µs (291.8 → 308.2). Off, against the
655
+ step before confinement existed: 143.4 → 144.4 and 295.9 → 292.9 µs, nothing a tick shows.
656
+
657
+ **Sub-cycling (Berger–Oliger, ruler).**
658
+ - Cascade *c* ≥ 1 steps on ticks with `t mod 2^c = 2^(c−1)`, `dt_c = dt·2^c`.
659
+ - Every tick steps cascade 0 plus at most one other, all at one Courant number.
660
+ - The identity makes the time between steps consistent for uniform air.
661
+
662
+ ## 9. Coupling between cascades
663
+
664
+ **The CPU's open boundary, given a parent.**
665
+ - A nested cascade's edge halo takes the parent's pressure (Dirichlet, same units) and tangential
666
+ velocity, through the identity.
667
+ - The coarsest cascade's parent is the far field: `v_far`, pressure 0.
668
+ - Dirichlet keeps every system non-singular, so warm starting and MGPCG are safe. Sealed pockets stay
669
+ local Neumann cases, as on the CPU.
670
+
671
+ **Relaxation band.** WRF rows 2..5, `F1 = (1/10Δt)·(6 − n)/4`. *S2:* `F1·Δt = (6 − n)/40` toward the
672
+ parent's read at the step's start, carried to its end by the step's identity; a face's row counts
673
+ faces along its axis and cells across.
674
+
675
+ **Feedback.** Pass 7 overwrites the parent inside the child's interior with face means of four child
676
+ faces. On a ratio-2 MAC lattice, a divergence-free child restricts to a divergence-free parent,
677
+ exactly. The parent's projection removes the interface divergence.
678
+
679
+ *S2:* the restricted parent cells are those whose children lie 6 or more child cells inside the
680
+ child's window (`FLUID_CASCADE_FEEDBACK_MARGIN`): the band is not fed back. Pinned at 32³ with an
681
+ integer curl field: all 1,000 restricted cells exactly divergence-free.
682
+
683
+ **The fallback** without pass 7 and parent halos is uncoupled grids with the same data and sampler.
684
+ It is the reversal if the S2 seam probes say so.
685
+
686
+ ## 10. Effectors and obstacles: rows, an LBVH, cooperative brick queries
687
+
688
+ **`FLUID_DATABASE_SPEC`**, with a cross-database `node` link:
689
+
690
+ | Table | Rows | Lifecycle |
691
+ |---|---|---|
692
+ | `fluid_effectors` | one per local effector (globals are folded on the CPU) | stable; written only when a record field differs, compared while assigning (the particle pattern); pose excluded |
693
+ | `fluid_obstacles` | one per shape (a `Union` is a run) | stable; shape parameters, inflation, v and ω compared the same way, so a sleeping body writes nothing |
694
+ | `fluid_obstacle_planes` | hull planes | a schema range, `add_run` |
695
+ | `fluid_query`, `fluid_query_sample` | §12; *built at S5 as a database of their own, `FLUID_QUERY_DATABASE_SPEC`* | freed after delivery or drop |
696
+
697
+ **Poses.** `node = row_of_entity(entity)` (`RowChains`), read by `scene_read_node`; node 0 (the world
698
+ root) for transform-less effectors.
699
+
700
+ **The acceleration structure, once per frame.**
701
+
702
+ | # | Pass | Notes |
703
+ |---|---|---|
704
+ | L1 | extract | one thread per leaf, from a **CPU-compacted leaf → row list** (deterministic order, like the TLAS `#refresh_rows`); world AABB from the node pose and the record. **Every box is clipped to the union of the coarsest windows** (CPU-known), so planes, km-scale heightmap boxes and far rows stay finite; a leaf outside collapses to a point. Wake boxes are swept by `v·dt_max` of this frame's stepping cascades. Obstacles are dilated one cell on the + sides. Centroid bound by subgroup min/max + one atomic over a host-seeded buffer (the TLAS template). |
705
+ | L2 | `graph_bvh_build_lbvh`. **≤ 1,024 leaves:** the small-scene path, one dispatch, **rebuilt every frame** (a fresh tree, no cadence). **More:** the multi-pass build (19 dispatches) on a frame whose leaf count changed or every 16th frame, otherwise **refit only** (`shader_bvh_refit` through the stored Morton order). | The engine scales, so both paths are first-class. Most scenes are expected to sit under the threshold, which is why it gets the fast path. The cadence above it is keyed on runtime facts (membership, age), with no static/dynamic category, and measured at S4. |
706
+
707
+ **Per pending tick, for its stepping cascades:**
708
+
709
+ | # | Pass | Notes |
710
+ |---|---|---|
711
+ | Q1 | cooperative brick query | **one workgroup per brick** of each stepping cascade, one dispatch. `chunk_bvh_query_aabb_cooperative`: a level-synchronous frontier in LDS, so per-thread work is bounded by tree depth. Brick box grown by the kernel floor (2·h_c). **Resolution cull:** obstacles narrower than `h_c/2` are not in this cascade's tree (S4d, below). Candidates gather into LDS (≤ 128); survivors are chosen **by row index**, which is stable under motion: ≤ 24 obstacles, then ≤ 16 effectors; overflow is counted. Non-empty bricks append (generalised append). |
712
+ | Q2 | indirect command | 1 thread |
713
+ | Q3 | forcing | one workgroup per touched brick. Per cell: **solid test** = any obstacle SDF at the centre ≤ inflation (≤ 24 obstacles × ≤ 16 hull planes = 384 plane tests worst case, one SDF for analytic shapes), recording the solid's obstacle. Pinned faces from neighbour flags, as on the CPU, with wall velocity from that obstacle. Effector deposits (≤ 16). Output: dense transient forcing + flags; readers gate on the touched bit. |
714
+
715
+ **Effector kinds** (`write_gpu_record(record)` → `generate_record_writer`):
716
+
717
+ | Kind | Class | Deposit over `dt_c` (shared core: segment, radius, `falloff_quadratic`) |
718
+ |---|---|---|
719
+ | `SPHERE_PUSH` | `ImpulseFluidEffector` + `spread` | `\|f\|·dt_c·w·v3_clamp_to_cone(r̂, f̂, spread)`: 0 is today, π is omni, `r = 0` → `f̂` |
720
+ | `SWEPT_CAPSULE` | `WakeFluidEffector` | `v·strength·w` over `[p − v·dt_c, p]`; momentum per second `\|v\|²·strength·πR²` on every cascade (spec) |
721
+ | `SWIRL` | `VortexFluidEffector` (`position`, `axis`, `length`, `radius`, `strength`) | `strength·dt_c·(27/4)·(â × r⊥)/R·(1 − d/R)²`: finite everywhere |
722
+
723
+ - **Wake velocity:** `(global − prev_global)·offset / (frame_dt·fixedStepTimeScale)`.
724
+ `TRANSFORM64_EVENT_PLACED` makes teleports clean, and the deviation clamp is the backstop.
725
+ - **Kernel floor:** `R_eff = max(R, 2·h_c)`, momentum-conserving, with a spec bounding sub-cell
726
+ pulsing.
727
+ - **One record, two executors:** `fluid_record_apply` is the CPU applier, with parity on node-0
728
+ records.
729
+ - **Obstacles on the GPU:** analytic shapes, rigid `Transformed`, `Union` runs, hulls as capped
730
+ planes; scaled shapes, meshes and heightmaps as their clipped oriented box until the SDF stage.
731
+ Wall velocity per face is `rigid_velocity_at_point(v, ω, node translation, x)`.
732
+ - **The CPU obstacle path is untouched.**
733
+
734
+ *S4, built and measured (2026-10-16): `GPUFluidForcing` (`shade/renderer/fluid/forcing/`).*
735
+ - **The database** is the table above, less S5's query tables. The planes are runs through `add_run`
736
+ but not a schema range: a hull names its run in core's f32 shape parameters, and the 80-byte record
737
+ has no u32 pair to declare one over, so the caller frees the run with its records.
738
+ - **The step's input.** The correct pass adds the forcing after its epilogue on every face that is not
739
+ pinned, so the divergence is of `velocity_mid + forcing` with no change to the divergence, the solve
740
+ or the gradient. The forcing is dense over the three face lattices and written only on forced bricks;
741
+ bit 1 of a cell's solid flags (`FLUID_FORCED_FLAG`) says its faces were written, so nothing is cleared
742
+ and every other pass keeps testing bit 0 alone. The flags are the cascade's own buffer; a word a
743
+ brick (`solid_bricks`) says which bricks the forcing last wrote, so a brick nothing meets any more is
744
+ listed once more and cleared.
745
+ - **Pinned faces.** Q3 writes the wall's velocity (`rigid_velocity_at_point` of the solid cell's
746
+ obstacle, the + side's when both are) into the cascade's persistent faces at every face it pins,
747
+ before the step and after the restriction. Every pass already carries a pinned face's persistent
748
+ value through, so a face that just became pinned carries the wall, never the fluid value it held.
749
+ - **Q3 is a dispatch per stepping cascade**, from its own command: it writes the cascade's three
750
+ persistent face textures, and two cascades' would be six of the four storage textures a stage may
751
+ bind. A coarse tick is Q1, Q2 and two Q3s. Bindings: extract 6 storage buffers, query 7, commands 3,
752
+ forcing 7 and 3 storage textures, the correct pass 2.
753
+ - **On the RTX 4090** (every kernel compiled through Tint at the default limits): Q1–Q3 against the CPU
754
+ twins over two 32³ cascades, three frames with rows moved and removed: every cell's solid bit exact,
755
+ every forced face's forcing within 5.6e-10 of the summed peak, every pinned face exactly the wall's
756
+ velocity, every unforced cell fluid with no deposit. At 4,000 rows a refit and a rebuild at the same
757
+ pose list the same 2,494 bricks with the same survivors.
758
+ - **A forest** of 3,000 spheres of 0.12–0.35 m on 48 × 4 × 48 m: survivors equal the lowest 24 rows
759
+ among the culled overlaps in every brick of every cascade, through a 0.05 m-a-frame drift (so a
760
+ changed list is a changed overlap, 275–317 of 1,024 fine bricks a frame). The cull leaves cascade 1
761
+ 282 overflowing bricks against 352 without it, and cascades 2 and 3 no obstacle. But a coarse brick's
762
+ box meets so many of the small leaves that the query's frontier (256) overflows before the cull,
763
+ which runs at leaves: 692 nodes dropped a tick at cascade 2, ~5,500 at cascade 3, every leaf under
764
+ them small enough to be culled here.
765
+ - **A mixed forest loses obstacles** (S4, 2026-10-16, RTX 4090): the same 3,000 small spheres with 60 of
766
+ 1–4 m among them, their rows last, first or interleaved, survivors compared brick by brick with the CPU
767
+ reference (the lowest 24 rows among the culled overlaps). Cascades 0 and 1: exact. Cascade 2: 112 nodes
768
+ dropped a tick, 0–2 kept obstacles lost in at most one brick. **Cascade 3: 4,360–4,484 nodes dropped a
769
+ tick, and 134–148 of the 658 obstacles the reference keeps lost, in 23–24 of the 70 bricks that keep
770
+ any** — every one of them large; the brick then keeps higher rows in their place (14–20). A CPU model of
771
+ the query over a Karras LBVH of the same scene reproduces it (136 lost in 24 bricks, 4,470 nodes
772
+ dropped) and measures the remedies: a node-level cull, the leaf cull applied to internal boxes, still
773
+ loses 106; a frontier of 512 loses 35; 1,024 loses none; **a tree per coarse cascade over only the
774
+ obstacles it resolves loses none and drops nothing** at every cascade. Decided and built at S4d.
775
+
776
+ *S4d, built and measured (2026-10-16): a tree per resolution.*
777
+ - **The cull is the tree.** Each obstacle row keeps its extent, `fluid_obstacle_record_extent`:
778
+ `2·(max local half extent + inflation)`, ∞ for a plane. It is the record's own, so a turned box keeps
779
+ its longest edge; at the identity pose it is S4's widest world edge less the dilation. Cascade c
780
+ resolves the obstacles at least `h_c/2` wide and every effector; its bricks search a tree of exactly
781
+ those, obstacle rows ascending, then effector rows, and the query filters nothing. The sets are
782
+ nested, and a cascade resolving what the finer one does shares its tree.
783
+ - **The CPU decides membership** because the build takes its leaf count from the host, and a tree of
784
+ the cascade's own leaves is what puts a coarse tree on the one-dispatch path. The extent is known when
785
+ a record is written, so membership costs O(delta).
786
+ - **Only the trees the ticks need are built.** The first tick of a frame that steps a cascade of a level
787
+ records that level's tree, L1 and L2, right before its queries; a later tick of the frame reuses it.
788
+ Each tree keeps its own cadence (list version, count, age). A level resolving nothing binds an empty
789
+ tree.
790
+ - **Bindings.** The query binds slot 0's and slot 1's trees (one buffer twice when shared): 8 storage
791
+ buffers, the per-stage limit. The forcing pass reads each slot's survivors through its own tree's leaf
792
+ rows.
793
+ - **Measured.** The mixed forest on the RTX 4090 (S4's scene, rows last, first and interleaved, ticks
794
+ stepping cascades 1, 2 and 3): every survivor list of every brick equals the CPU reference at every
795
+ cascade, 0 nodes dropped, with trees of 3,026, 1,396, 100 and 100 leaves (cascades 2 and 3 share).
796
+ The CPU model and a tier-2/3 spec (`GPUFluidForcing.forest.spec.js`: the cooperative query in
797
+ lockstep over the CPU oracle's LBVH of each tree) lose nothing at any cascade; one tree culled at its
798
+ leaves loses 120 obstacles and 152 effectors at cascade 3 in the same spec.
799
+
800
+ ## 11. The published wind field
801
+
802
+ **`GPUSceneWind`** (always on `GPUSceneContext`):
803
+ - a `GPUTileAtlas3D` (per-axis content, `rgba16float`, border 1), one tile per cascade;
804
+ - a uniform `WIND_CASCADE_STRUCT` table (≤ 16, finest first: slot, corner, cell size,
805
+ `v_far(t_s,c)`, `k_c`);
806
+ - `v_far(t)`.
807
+
808
+ **Pass 6** writes its own tile only: velocity collocated at cell centres, with the edge halo as the
809
+ skirt. It never samples the atlas it writes.
810
+
811
+ **`chunk_wind_field_sample(p)`:**
812
+ - `chunk_clipmap_select_finest` picks the cascade and a band weight.
813
+ - The read is the identity (`v_far(t) + (tap − v_far(t_s,c))·k_c`). Inside a band it takes two
814
+ identity reads (the cascade and its parent, or `v_far` for the coarsest); otherwise one; outside,
815
+ `v_far`.
816
+ - **The blend is live at sample time.**
817
+ - Bindings: one `texture_3d<f32>`, the clamp sampler, one uniform, no storage buffer.
818
+ - **Hardware trilinear here is presentation-grade**, and 4-bit weights are acceptable for it.
819
+
820
+ ## 12. The CPU read API, and cloth
821
+
822
+ **On `GPUFluidSystem`:**
823
+
824
+ ```js
825
+ system.far_field(out) // m/s, synchronous, deterministic
826
+ const h = system.request(min_x, min_y, min_z, max_x, max_y, max_z, nx, ny, nz, target, target_offset);
827
+ system.status[h] // GPUReadbackStatus, for one frame
828
+ ```
829
+
830
+ **With a device:**
831
+ - requests become `add_run` rows;
832
+ - a gather evaluates `chunk_wind_field_sample` into them;
833
+ - `request_run` reads them back, with `readback.encode` right after the gather in the fluid's own
834
+ pass;
835
+ - delivery is in order, `max_in_flight` is 4 batches, drops come with a status, and latency is
836
+ typically 2–3 frames.
837
+
838
+ **Headless:** answered from `far_field` at the next update.
839
+
840
+ **Cloth: `ClothGPUFluidWind`, the default source.**
841
+ - **`begin`** swaps in lattices delivered since the last tick.
842
+ - **`varies`** answers whether a delivered lattice covers the box, and requests the padded box.
843
+ - **`sample`** interpolates with the strided `scs3d_sample_linear3`, or answers `far_field`.
844
+ - **G2:** the gust runs on the scene clock. The parity gate is restated: worker and inline agree for
845
+ cloths registered on the same tick, and under a time-invariant wind. The specs use those plus
846
+ injected lattices. Run-to-run repeatability under GPU wind is lost and accepted (F4).
847
+
848
+ *S5, built and measured (2026-10-16).*
849
+ - **The API.** `request(min_x, min_y, min_z, max_x, max_y, max_z, nx, ny, nz, target, target_offset)` → a
850
+ handle; `target` is a `Float32Array` and the lattice lands from `target_offset` as four floats a point,
851
+ `(x, y, z, 0)` m/s, x fastest, point `(i, j, k)` at `mix(min, max, (i, j, k) / (n − 1))` (an axis of one
852
+ point at `min`). `status[h]` is `Pending` until the apply point that answers it, then `Delivered` or
853
+ `Dropped` until the next, then `None`. **The apply point is the system's `update`**, once a frame.
854
+ - **On the device** (`GPUFluidQueries`, `shade/renderer/fluid/query/`): the tables are a database of their
855
+ own, not `FLUID_DATABASE_SPEC`'s, because a request is answered with no domain (the field is then the far
856
+ field alone) and the forcing exists only while a domain does. At `FrameStart`, after the publish, a
857
+ frame's requests become a `fluid_query` row and a `fluid_query_sample` run each (`add_run_filled`) and one
858
+ pass: the upload, the gather (one invocation a sample; its request found by halving the frame's list; two
859
+ storage buffers), and `readback.encode` right after it. A frame's lattices share one pooled staging
860
+ array, so the readback delivers a frame as one run. A device restart or shutdown drops what is in flight.
861
+ - **Latency, measured on the RTX 4090** (Chrome headless, ~240 frames a second, three ribbons and a probe
862
+ line asking every frame they could): from the frame a request is made in to the update that delivers it,
863
+ **median 2 frames, 95th percentile 3, worst 5** over 2,171 lattices, 8.5 ms median wall time, none
864
+ dropped or stalled; cloth reads a lattice at its next fixed step after that.
865
+ - **The wake, through the read API:** a 32-point probe line across the ribbons' fronts deviated from the
866
+ far field by a median 2.77 m/s (worst 5.77) with a 6 m/s box wake crossing in front of them, against
867
+ 0.026 (worst 0.51) with no wake.
868
+ - **Cloth: `ClothGPUFluidWind`** (`engine/physics/cloth/wind/`): lattices over each cloth's box padded by
869
+ 0.5 m, points every 0.5 m at most (16 along an axis at most), one request in flight per cloth. `begin`
870
+ lets go of a lattice no cloth read in the last tick and asks again over the box of one only a wake test
871
+ read, so a sleeping cloth notices a gust. A status is readable for one frame and `begin` runs once a
872
+ tick (four frames a tick at 240 Hz), so a lattice counts as delivered by its own data (a 0 the delivery
873
+ writes where a NaN was) and as dropped when its handle settled without that.
874
+ - **Cloth reads it by default** (decided after S5's first report, F4): with nothing assigned,
875
+ `ClothWorld#wind` is a `ClothGPUFluidWind` while the scene has a domain, else a `ClothFluidWind` while
876
+ the far field is not exactly zero, else `null` — decided at every tick from those facts, so a scene
877
+ without wind gains no drag; an assigned source, `null` included, wins. Cloth finds the system by
878
+ `GPUFluidSystem.prototype.isGPUFluidSystem`, since importing it needs WebGPU's globals. The resolution
879
+ allocates 0.04–0.10 bytes a tick (sampling noise); the ribbons scene with no wind assigned came up on the
880
+ GPU wind on the 4090 with the same latency (median 2 frames, 95th percentile 3, worst 5).
881
+ - **G2:** `ClothAmbientWind` is retired; `ClothFluidWind(effectors)` answers `FluidEffectorsSystem`'s far
882
+ field outside the CPU fields; `GlobalFluidEffector#apply` is removed and `FluidSimulator#step` refuses a
883
+ global. The restated gate measured (cloth `MEASUREMENTS.md` §69): the staggered spawn under a 3 m/s
884
+ gust differs at the second cloth's step 1, byte 0; registered on the same tick, none in 180 steps.
885
+ - **Allocation per request at steady state:** headless 0.8 bytes; on the software device the read API's
886
+ own path ≤ 5 bytes, after two fixes in `GPUTypedTable` it exposed (`set_record`'s byte views, 278.8 →
887
+ 0 bytes a row; `#find_run`'s interpolated assert message, 132 bytes a run → 0). Open, measured:
888
+ `GPUDatabase#update` walks each table's pages with entry destructuring and frees empty pages, ~59
889
+ bytes a request at 17 lattices of 64 points a frame.
890
+
891
+ ## 13. Integration
892
+
893
+ **Water.** In this work (§6).
894
+
895
+ **Particles: `SAMPLE_WIND`** (position → m/s).
896
+ - A primitive: it reads a bound resource.
897
+ - It touches the ISA, the interpreter (host function, far-field stub), the JS reference VM,
898
+ optimizer semantics, DAG lift/lower/pack, the node library, and every VM host: emit, simulate, the
899
+ wide variants, warm-up, the editor's `ParticleReferenceSimulation`, and the optimizer's equivalence
900
+ and fuzz harnesses.
901
+ - No storage buffer.
902
+
903
+ **Volumetrics.**
904
+ - **Now:** the far field folded into the phases on the host, per-row phase writes, and the departure
905
+ from the far field sampled on the GPU wherever the noise is evaluated, carried as a flow map (§6).
906
+ Built in S3, reworked on Alex's correction (§22).
907
+ - **Later:** fluid scalars (§20).
908
+
909
+ **Audio.** A 1-point request.
910
+
911
+ ## 14. Budget
912
+
913
+ **Memory at the defaults** (64×32×64, 4 cascades):
914
+
915
+ | Resource | Size |
916
+ |---|---|
917
+ | velocity (persistent) | 6.4 MiB |
918
+ | pressure (persistent) | 2 MiB |
919
+ | atlas (persistent) | 4 MiB |
920
+ | per-step transients | ~5 MiB, + 3.5 MiB the step's ghosts |
921
+ | forcing + flags (two stepping cascades) | 5.2 MiB; *S4: 3.2 MiB of forcing and 0.66 MiB of survivors, the flags the cascades' own* |
922
+ | LBVH | `(2n−1)·32 B` + sort transients for n leaves; *S4d:* one per resolution a stepping cascade needs, n its leaves |
923
+ | confinement force (with confinement) | 3·N floats a step, transient: 1.5 MiB at 64×32×64 |
924
+ | **peak** | **~28 MiB** |
925
+
926
+ **Dispatches**, from the pass tables in §8 and §10. The cascade step is counted by S1
927
+ (`GPUFluidCascade`, tier 3); the rest is an estimate until S2/S4 count it.
928
+
929
+ | Unit | Item | Dispatches |
930
+ |---|---|---|
931
+ | **Cascade step** | the step's ghosts | 1 |
932
+ | | advect predict, advect correct, divergence, gradient + publish | 4 |
933
+ | | the solve's weights: level 0 from the solid flags, then each coarser level | 4 |
934
+ | | two V-cycles to 8×4×8, each 3 levels × (smooth + residual/restrict), the coarsest, 3 levels × (prolongation folded into the smooth) | 2 × 10 |
935
+ | | *baseline per step* | **29** (19 at one V-cycle) |
936
+ | | scroll fill (only on a step that re-placed the cascade); curl (only with confinement) | +0..2 |
937
+ | **Tick** | Q1 brick query, Q2 command, Q3 forcing | 3; *S4: 4 on a tick with a coarse step, a Q3 per cascade (§10)* |
938
+ | | cascade 0 + one coarse cascade (7 ticks in 8 at four cascades; the 8th steps cascade 0 alone) | 2 × 29 |
939
+ | | restriction of the child into the coarse cascade before it steps | 1 |
940
+ | | *baseline per tick* | **62** (32 on the tick with no coarse step) |
941
+ | **Frame** (any frame that records a tick) | L1 extract + L2: ≤ 1,024 leaves, the one-dispatch build every frame; more leaves, refit or rebuild (19). *S4d:* for each tree a tick of the frame needs, one when every level resolves the same obstacles | 2; or 2 / 20; each |
942
+ | **Frame** (every frame) | fluid database uploads when rows changed (`GPUDatabase.update`'s upload shaders); the query gather + `GPUDatabaseReadback`'s gather (≥ 48 rows) when requests exist | ~2–4 |
943
+
944
+ Per frame, then:
945
+ - **No tick** (e.g. 2.6 of every 3.6 frames at 144 Hz against 40 Hz ticks): ~2–4.
946
+ - **One tick, ≤ 1,024 leaves, or a refit above that:** 2 + 62 + 2–4 ≈ **66–68**, or ~72 with fills
947
+ and curl on both steps.
948
+ - **One tick, rebuild above 1,024 leaves:** 20 + 62 + 2–4 ≈ **84–86**, or ~90.
949
+ - **Two ticks** (the cap, under load, e.g. a third of frames at 30 fps): 2 + 2 × 62 + 2–4 ≈
950
+ **128–130**; ~148 on a rebuild frame.
951
+
952
+ Two pressure solves are 48 of the 62 dispatches in a tick. The V-cycle is where the count lives.
953
+
954
+ **Cost, measured at S1** (RTX 4090, D3D12, headless Chrome; the engine's recorded step replayed with
955
+ timestamps, arms paired and interleaved, p10 of 100–200 samples):
956
+ - **A cascade step:** 114.7 µs at 64×32×64 and 244.7 µs at 128×32×128 with two V-cycles (76.8 and
957
+ 173.1 µs at one). At 64×32×64: V-cycles 77 µs, advection 25.6, weights 8.2, gradient 4.1,
958
+ divergence 2.0. The solve is 65–73% of a step. Obstacles change nothing.
959
+ - **Small dispatches cost 1–2 µs back to back**, not the 5–8 µs a separate pass was estimated at.
960
+ Recording a step's 28 dispatches in one compute pass or in separate passes costs the same.
961
+ - **One tick at the defaults** (cascade 0 plus one coarse cascade, both 64×32×64) is ~230 µs of
962
+ cascade steps plus forcing, and **a two-tick frame ~0.46 ms plus forcing**: at the 0.5 ms target on
963
+ the 4090. S2 and S4 measure a whole tick.
964
+ - **A whole tick, measured at S2** (four cascades at 64×32×64, h₀ = 0.5 m; RTX 4090, the recorded tick
965
+ replayed with timestamps, its uniforms copied at capture, arms interleaved, p10 of 200): **214 µs**
966
+ on a tick that steps cascade 0 alone (28 dispatches), **432 µs** on one that steps cascade 1 too
967
+ (57), 349 µs with cascade 3. A lone S1-shaped cascade beside the far field reads 132 µs in the
968
+ same run. Against the revised 115 and ~230 µs above, a coupled step is ~1.6× S1's (per-dispatch
969
+ medians 221 against 138 µs): the parent seams' fetches (8 parent texels a beyond-window read, made
970
+ by the ~67% of a 64×32×64 window's tiles that lie on a window face) take predict from 14 to 42 µs
971
+ and correct from 24 to 59, and the solve's parent ghosts ~14 µs more. The band costs nothing a tick shows (213 against 213 µs),
972
+ 3% of correct. Forcing (S4) is not in these.
973
+ - **With the step's ghosts (§7, D3), measured at S2:** two stacks, one reading the parent per seam
974
+ tap and one from the ghosts, driven alike and their recorded ticks replayed paired and
975
+ interleaved (p10 of 200; after 32 ticks the four cascades' state bit for bit the same): **144.4 µs**
976
+ on a tick that steps cascade 0 alone (29 dispatches) against 246.8, **291.8 µs** with a coarse
977
+ step (59) against 489.5. Of cascade 0's step, predict 45 → 16 µs, correct 89 → 27, the smoother
978
+ 63 → 53, residual + restriction 22 → 18 and the gradient 6 → 4, for the ghosts' 9. The per-tap
979
+ seams read 214 and 432 µs in the run above and 247 and 490 in this one: the level moves from run to
980
+ run, the paired difference does not.
981
+ - **Levers, in order of where S1 measured the time:**
982
+ 1. the solve. At 128×32×128 the finest up-leg smoother, with its folded prolongation, costs 19.5 µs
983
+ against 13.3 µs down: stage the coarse block in LDS (144 loads a tile instead of 4,800). Build the
984
+ coarse weights in one dispatch, or level 0's in the forcing pass (the weights are 7% of a step);
985
+ 2. fusing divergence into the first smoother;
986
+ 3. the LDS predict pass (advection is 22–30%);
987
+ 4. a lower rebuild cadence above 1,024 leaves.
988
+ - **The small-scene build, measured** (landed `b523718db`, RTX 4090, `GPU_BVH_BUILD_PLAN.md` §4.7):
989
+ one dispatch costs 7.3 µs at 16 leaves, 13.2 µs at 128 and 53.2 µs at 1,024, against ~73–84 µs for
990
+ the 19-dispatch build at those counts. Near the 1,024 threshold a rebuild is a single dispatch, but
991
+ it costs far more than a small dispatch's 1–2 µs.
992
+
993
+ - **A whole tick with forcing, measured at S4** (the defaults, four cascades at 64×32×64, h₀ = 0.5 m;
994
+ RTX 4090, each tick recorded by the engine and replayed with timestamps, its uniforms, copies and
995
+ clears kept, arms interleaved, p10 of 200), against the same tick without forcing:
996
+
997
+ | Scene | Tick of cascade 0 alone | Tick with a coarse step |
998
+ |---|---|---|
999
+ | none (S2's tick) | 143.4 µs | 289.8 µs |
1000
+ | 6 effectors and 6 obstacles about the anchor | 166.9 (+23.5) | 326.7 (+36.9) |
1001
+ | the same and a ground plane, which forces every brick | 173.1 (+29.7) | 345.1 (+55.3) |
1002
+ | 3,000 small spheres, 400 fine bricks past 24 obstacles | 201.7 (+58.3) | 379.9 (+90.1) |
1003
+
1004
+ By pass (medians, each in its own timed pass): Q1 13.8–15.4 µs over 2,048 bricks and 18–28 over 4,096,
1005
+ 40 and 59 in the forest; Q2 1 µs; Q3 8–16 µs for a cascade, 17–30 for two; the correct pass the
1006
+ same with the forcing as without (26.6 and 53.2 µs). The frame's L1 and one-dispatch build at 13
1007
+ leaves: 11.3 µs; at 3,000 (the 19-dispatch build): 86 µs.
1008
+ - **4,000 rows, rebuild against refit** (2,000 obstacles and 2,000 effectors over 200 × 40 × 200 m; costs
1009
+ as the difference from a plain tick replayed before them, p10): L1 and the rebuild +87.7 µs, L1 and
1010
+ the refit +17.0 µs; Q1 over both stepping cascades +70.3 µs. On the forest, Q1 over cascade 0 and 1
1011
+ +54.3 µs, over 0 and 3 +50.2 µs.
1012
+
1013
+ - **A scene from entities, measured at S4** (the bonfire playground, RTX 4090, every pass timestamped,
1014
+ medians of 90 frames at 60 fps against 40 Hz ticks): a `GPUFluidComponent` at the defaults, a gusting
1015
+ global, two impulses, a vortex, a wake on a moving entity and a moving box. The frame's passes sum to
1016
+ 1.60 ms on a frame with no tick and 2.00 ms on a frame with one; the fluid's share of a one-tick frame is
1017
+ 396 µs with a coarse step and 220 µs without (the frame's L1 and build 12 µs, Q1–Q3 20 µs, the publish
1018
+ 10 µs). No tick was dropped and the forcing dropped nothing. The published tile deviates from `v_far` by
1019
+ up to 4.67 m/s beside the vortex, +0.48 m/s upward over the fire, and 0.001 m/s 17 m away.
1020
+ - **The water playground against the bonfire** (the ocean stop at the defaults, no effector or obstacle rows,
1021
+ against the scene above; RTX 4090, every pass timestamped per frame, 240-frame captures at 60 fps by
1022
+ `create_frame_loop`, runs alternated W B B W W B): pass for pass the two agree within 1 µs, but for the
1023
+ bonfire's forcing (the brick query, the apply, the leaves and its one-dispatch tree: 45 µs with a coarse step,
1024
+ 34 alone) and its smoother (+7). A frame that ticks, p10 per capture: water 339–367 µs with a coarse step and
1025
+ 189–195 alone, the bonfire 391–419 and 221–234. S3's tree (`d2bd51b90`), alternated with this one, reads the
1026
+ same (343–357 and 190–194); either tree drifts to 390–600 µs in a capture whose whole frame drifts with it.
1027
+ The water frames tick at most once (a two-tick frame about once in 240), drop nothing, fill nothing at rest,
1028
+ dispatch no forcing, and publish one or two cascades only on a frame that ticks. **A capture's mean of the
1029
+ fluid's spans a frame is not its cost**: while other processes held the 4090 at 36–99%, single passes took
1030
+ +270 µs steps, and that mean read 248–500 µs for water and 396–1,399 µs for the bonfire. S3's 1.09–1.13 ms
1031
+ (§6) was that statistic, in captures where every water pass ran ~3× its time here. Judge the fluid by a
1032
+ tick class's p10 or by per-pass medians.
1033
+
1034
+ - **A tree per resolution, measured at S4d** (RTX 4090, whole frames, the trees and one tick, before
1035
+ and after paired and interleaved, p10 of 200). 6 effectors and 6 obstacles build one tree as before,
1036
+ every tick shape the same (181.2 → 181.2 µs alone, 545.8 → 545.5 with cascade 1, a 16-tick cycle
1037
+ 5,180.4 → 5,180.4); with S4b's protocol (the tick alone) 167.9 and 327.7 µs against S4b's 166.9 and
1038
+ 326.7 (no forcing: 144.4 and 291.8 against 143.4 and 289.8). The mixed forest: +12.3 µs with cascade
1039
+ 1 (its 1,396-leaf tree refit), +3.1 with cascade 2 and +9.3 with cascade 3 (a 100-leaf one-dispatch
1040
+ build), +0 alone; a 16-tick cycle +2.9% (6,224.9 → 6,408.2 µs). 3,000 small spheres alone: +13.3 with
1041
+ cascade 1, −11.3 and −6.1 with cascades 2 and 3 (their trees are empty), a cycle +2.1%.
1042
+ - **Vorticity confinement, measured at S4d** (§8): the curl 8.2 µs a step, the correct pass +1.0 µs; a
1043
+ tick +8.2 µs alone and +16.4 with a coarse step. Off, nothing a tick shows.
1044
+
1045
+ **Bandwidth** on a ~50 GB/s integrated GPU: ~1.5 ms a tick.
1046
+
1047
+ ## 15. Verification
1048
+
1049
+ **Tier 1: WGSL validity.** ≤ 8 storage buffers (fluid passes), ≤ 4 storage textures, ≤ 16 KiB of
1050
+ workgroup memory, `enable subgroups;`.
1051
+
1052
+ **Tier 2: the emulator, and CPU models.**
1053
+ - **Parity specs:**
1054
+ - `sdf3_*`;
1055
+ - `aabb3_intersects_aabb3`;
1056
+ - segment distance;
1057
+ - falloff;
1058
+ - cone clamp (`r = 0`, antipodal);
1059
+ - swirl (axis);
1060
+ - rigid velocity;
1061
+ - the clipmap coordinate;
1062
+ - `fluid_record_apply` ↔ forcing (node-0);
1063
+ - the atmosphere identity: a uniform cell matches `v_far` at dt_c = dt…8·dt with gusts on and `D`
1064
+ changing mid-interval, and a dropped tick leaves no offset.
1065
+ - **Barrier kernels:** per-cell maths in `chunk_v3_mac_*` behind a two-function seam (`tile_read_*`
1066
+ from LDS in production, from a buffer in specs — the particle VM's register-backing pattern).
1067
+ Parity against `v3_mac_*` at 16³, with the pressure scale `dt/h²` applied.
1068
+ - **A CPU multigrid model as a spec** (the `mg2.mjs` shape):
1069
+ - **≤ 0.30 per V-cycle at 64×32×64** with the block smoother and the finite-volume boundary;
1070
+ - red the moment the CPU's open-face rule is put back (0.75);
1071
+ - the both-colours / ω > 1 assert fires.
1072
+ - **The quality scenarios** at 16³ through the buffer-backed hosts (`.slow.spec.js`).
1073
+ - **Physics specs:**
1074
+ - wake momentum equal across cascades;
1075
+ - kernel-floor pulsing bounded;
1076
+ - the far field keeps the authored gust exactly (no drag filtering);
1077
+ - `force` with `D = 0` stays out of the GPU far field.
1078
+ - **LBVH inputs:** planes and heightmaps produce finite clipped leaves (no NaN centroid), and the
1079
+ leaf order is the CPU list.
1080
+
1081
+ **Tier 3: `SoftwareGPUDevice`.**
1082
+ - The ruler schedule.
1083
+ - Placement, nesting clamp, jump re-placement.
1084
+ - Fills.
1085
+ - L1/L2 build-versus-refit by membership and age.
1086
+ - Q1–Q3 sizes, and nothing with no rows.
1087
+ - Upload order.
1088
+ - `request_run`.
1089
+ - Teardown under a pending mapping.
1090
+ - Restart.
1091
+ - The default `GPUSceneWind` with no fluid system.
1092
+
1093
+ **Migrations.** VSM, CPU fluid (sync extraction, folded atmosphere), cloth, volumetrics, water,
1094
+ physics and the singleton users stay green at each commit. The census runs before and after.
1095
+
1096
+ **Tier 4: one-off device checks, short runs:**
1097
+ - the SOR and V-cycle arms;
1098
+ - manual against hardware trilinear;
1099
+ - the LDS predict pass;
1100
+ - in-pass dispatch cost;
1101
+ - seam probes;
1102
+ - a long warm start;
1103
+ - a fast camera;
1104
+ - a teleport;
1105
+ - an obstacle-dense scene (V-cycle against MGPCG);
1106
+ - 4,000 rows (rebuild against refit);
1107
+ - a forest on a coarse cascade (resolution cull, survivor stability under motion).
1108
+
1109
+ ## 16. Stages
1110
+
1111
+ One-concern commits, each green alone.
1112
+
1113
+ | Stage | Contents | Gate |
1114
+ |---|---|---|
1115
+ | **S0: shared foundations** | clipmap module + VSM and CPU-fluid migrations; `FluidEffectorsSystem` extraction; core shape record + cloth; SDF chunks; shared kernels; `chunk_aabb3_intersects_aabb3`; `chunk_bvh_query_aabb_cooperative`; the small-scene path in `graph_bvh_build_lbvh` (landed on master in its own session); `chunk_grid_tile_halo_*`; generalised append (the VSM migrates); `GPUTileAtlas3D` per-axis + slot origin; trilinear-corners extraction; 3-D texel helpers; `request_run`; strided `scs3d`; non-allocating singleton accessor; `GPUSceneRows` on `TRANSFORM64_EVENT_PLACED`; 3-D slice view; G1 retirement | parity specs; existing specs green; census |
1116
+ | **S1: solver core** | one cascade: MAC chunks, LDS hosts, V-cycle with the finite-volume boundary and colour-masked smoother, manual-trilinear MacCormack, far-field boundary, physical pressure | multigrid CPU-model spec; kernel parity; quality slow-spec; **device A/Bs**; dispatch cost; defaults confirmed or cut |
1117
+ | **S2: cascades** | toroidal face textures, window-local tiles, placement, fills, coupling, ruler, read records | seam probes, long run, teleport |
1118
+ | **S3: the far field and its readers** | `GlobalFluidEffector` gust + `advance` + effector serialization (`FluidEffectorsComponent` adapter, so phases persist); the fold, `v_far` and `Λ`; the folded CPU atmosphere; the read API; volumetrics with per-row phases; water (`WaterWaves` v2, GPU low-pass, `windy` gate); `ClothAmbientWind` retired | consumer specs; Breaking CHANGELOG lines |
1119
+ | **S4: ECS fluid** | `GPUFluidComponent` + adapter, `GPUFluidSystem`, fluid database with field-wise change detection, the LBVH (build/refit), cooperative queries, forcing, `fluid_record_apply`, Impulse `spread`, `VortexFluidEffector`, the `FluidObstacle` adapter | tier-3 specs; CPU quality gate re-run |
1120
+ | **S5: queries + cloth** | gather, `ClothGPUFluidWind`, restated parity gate | readback contract; cloth specs |
1121
+ | **S6: particles** | `SAMPLE_WIND`; the bonfire in a gust | VM meta-tests; device look |
1122
+
1123
+ ## 17. Decisions
1124
+
1125
+ ### Resolved by Alex
1126
+
1127
+ - **F1. Two-way coupled cascades:** yes.
1128
+ - **F2. One scene wind.** As refined by R1: it is the fluid, with `GlobalFluidEffector` as its far
1129
+ field.
1130
+ - **F3. The CPU fluid:** kept, deprecated later.
1131
+ - **F4. Cloth reads the GPU fluid.**
1132
+ - **F5. Obstacles are `FluidObstacle`s;** SDFs later.
1133
+ - **F6. More kinds:** Impulse gets `spread`, and a vortex effector is added.
1134
+ - **G1.** Retire `GPUClipMap3D`, its update shader, its wrap chunk and `GPURadianceField`; rewrite the
1135
+ debug overlay.
1136
+ - **G2.** The gust runs on the scene clock, and cloth's parity gate is restated.
1137
+ - **R1.** One infinite fluid.
1138
+ - **R2.** An acceleration structure.
1139
+ - **R3.** Water reads actual velocity.
1140
+ - **R4.** Queries on the system; cloth left to my call.
1141
+ - **R5.** Depart from the CPU on facts; subgroups and LDS from the start.
1142
+
1143
+ ### Decided here
1144
+
1145
+ Each line gives the decision, then *what would reverse it*.
1146
+
1147
+ - **D1.** A domain follows its entity.
1148
+ - **D2.** Ratio 2, power-of-two resolution, corners in 4s.
1149
+ - **D3.** Toroidal per-component face textures (period N+1) and window-local tiles. The persistent
1150
+ textures hold no ghost: a per-step transient ghost shell, written once a step from the parent
1151
+ (velocity faces `FLUID_CASCADE_GHOST_DEPTH` = 6 deep, pressure one cell), holds the parent read the
1152
+ step's passes and LDS halos take; past the shell they read the parent itself. *Confirmed by the S2
1153
+ A/B: a tick 247 → 144 µs alone and 490 → 292 µs with a coarse step, bit for bit the same state
1154
+ (§14). Reversal: a measured tick where the ghosts' pass costs more than the reads it saves.*
1155
+ - **D4.** The MAC discretisation and MacCormack are kept; the CPU kernels are the maths oracle, with
1156
+ pressure scaled `dt/h²`.
1157
+ - **D5.** A V-cycle with the finite-volume coarse boundary and a colour-masked LDS block smoother at
1158
+ ω = 1, two a step. *Confirmed by the S1 A/B: ~3× faster than SOR to the same residual on the
1159
+ 4090. Reversal: MGPCG for obstacle-dense scenes.*
1160
+ - **D6.** Manual trilinear in f32; `r32float` velocity. *S1: 1.09–1.19× hardware's cost in predict.*
1161
+ - **D7.** One projection a step. *Confirmed at S1: without its pre-advection projection the CPU reads
1162
+ 0.99–1.02 of its default on every quality scenario. Reversal: a quality scenario regressing beyond
1163
+ tolerance.*
1164
+ - **D8.** Two-way nesting, Dirichlet halos in shared physical units, a WRF band, face-mean
1165
+ restriction. *Reversal: seam probes, falling back to uncoupled grids.* *Confirmed by the S2 seam
1166
+ probe* (a column vortex carried out of cascade 0 into cascade 1 and back, against one fine window
1167
+ over cascade 1's region): after the round trip the vortex is 15.0% of its peak off the fine window
1168
+ coupled, 16.0% with the band alone, 17.8% with feedback alone and 18.8% uncoupled; cascade 0's
1169
+ interior 4.0% against 6.2%.
1170
+ - **D9.** Ruler sub-cycling with per-cascade read records instead of a ring.
1171
+ - **D10.** The atmosphere identity at every step and every read; `v_far = u + g` with an unfiltered
1172
+ gust; `force` kept out of the far field.
1173
+ - **D11.** An LBVH once per frame. At ≤ 1,024 leaves it is the one-dispatch small-scene build, fresh
1174
+ every frame. Above that it is rebuilt on membership change or every 16th frame, and refit otherwise,
1175
+ queried cooperatively per brick, with survivors by row index and a resolution cull. *S4d:* the cull
1176
+ is a tree per resolution, each with its own cadence.
1177
+ - **D12.** One record, two executors; field-wise change detection; a momentum-conserving floor at
1178
+ 2 cells.
1179
+ - **D13.** Water: one low-passed sample feeds fetch, derivation and turn; deadband triggers; the
1180
+ `windy` gate from domains and `v_far`.
1181
+ - **D14.** Volumetrics phases written per row. *Built in S3 (§6): `SceneVolumetrics.noise_version`, seven
1182
+ words a moved row (the two scrolls and the flow clock). The phases carry the far field only; the
1183
+ departure from it is sampled on the GPU per evaluated point, never read back (§22).*
1184
+ - **D15.** Physics' inline ω×r copies migrate only under a flat budget.
1185
+ - **D16.** Projection stays on.
1186
+
1187
+ ## 18. Forks left
1188
+
1189
+ The measured reversals are D5, D7, D8 and D11's cadence. S4 left two forks; the brick query's frontier
1190
+ on coarse cascades was decided (a tree per resolution) and built at S4d (§10). One is left, with a
1191
+ recommendation:
1192
+
1193
+ - **Several `GPUFluidComponent`s.** *Built:* the lowest enabled entity is the domain, the others dormant.
1194
+ The alternative, every domain stepping and one publishing, costs a whole stack's tick (~144–292 µs) for
1195
+ nothing a consumer reads until S5's queries could ask a second domain; overlapping domains coupling to
1196
+ each other is out of the proposal (§20).
1197
+
1198
+ ## 19. Duplication ledger
1199
+
1200
+ **Removed by this work:**
1201
+ - The hysteretic snap (2 → 1); VSM window bookkeeping.
1202
+ - `GPUClipMap3D` and its wraps (G1).
1203
+ - Per-tick effector bookkeeping and several globals' order-dependent application →
1204
+ `FluidEffectorsSystem` and one folded atmosphere.
1205
+ - Cloth's shape-parameter encoding → core.
1206
+ - The box SDF inside the AABB chunk; the trilinear corners inside the SDF chunk; two slot-maths
1207
+ copies.
1208
+ - `chunk_vsm_append_mover` → the generalised append.
1209
+ - Impulse's and Wake's triplicated loops, four inline falloffs, Wake's closure and segment distance.
1210
+ - `ClothFluidWind`'s inline AABB tests.
1211
+ - `ClothAmbientWind`, `SceneVolumetrics.wind` and `WaterWaves`' wind.
1212
+ - `wind_main.js`'s hand copy.
1213
+ - `GPUSceneVolumetrics`' full repack and per-repack allocation for moving phases.
1214
+ - `getAnyComponent`'s per-call allocation.
1215
+
1216
+ **Noted, separate work:**
1217
+ - The f32 workgroup-sum pattern repeated in the SH projection and the multiscatter LUT. A shared
1218
+ chunk needs a reset and barrier, per-type variants and a layout-free slot claim.
1219
+ `sh_exp_workgroup_sum` is callable once per kernel, and since `48926a7ec` its 64 partial slots
1220
+ contradict its own one-slot-per-invocation comment.
1221
+ - The engine's split on subgroup contiguity (three shaders assume it, three warn against it).
1222
+ - `FluidObstacleSystem`'s triple traversal, duplicated clamp, `setVelocityAt` copy and stale
1223
+ "mesh-ish shapes throw" note.
1224
+ - The undeclared write of a manual `Wake.apply` to `previous_position`.
1225
+ - The CPU fluid's patch-edge variants and `fluid_gather_visible_effectors`' O(fields × effectors).
1226
+ - Hand-rolled row holding in Water, the particle emitter system, `GPULightCollection` and
1227
+ `prefab_place`.
1228
+ - Light and decal cluster tails; Brick4's index helpers.
1229
+ - ≥ 10 inline rigid-velocity sites.
1230
+ - `shape_to_type` throwing on `BoxShape3D`.
1231
+ - The CSM blended chunk as a `select_finest` client.
1232
+ - The existing BVH traversal loops have no visit budget.
1233
+
1234
+ ## 20. Not in this proposal, and open
1235
+
1236
+ **Not in this proposal:**
1237
+ - Scalars, sources, buoyancy (the successor to `force`), temperature.
1238
+ - Interpolated presentation of sub-cycled cascades beyond the identity's uniform part.
1239
+ - Overlapping domains coupling to each other: the finest answers.
1240
+ - Mesh, heightmap and scaled-shape obstacles on the GPU from SDFs. That needs
1241
+ `GPUGeometryManager.sdf`, a physics-shape source, and `shader_build_sdf`'s `NEGATIVE_WRAP_DISTANCE`
1242
+ hack removed, because it reads thick meshes as hollow beyond ~5.6 voxels.
1243
+
1244
+ **Open until measured:**
1245
+ - The V-cycle factor with obstacles, and Galerkin against the open-fraction operator.
1246
+ - In-pass dispatch cost.
1247
+ - The rebuild cadence above 1,024 leaves.
1248
+ - The staggering cost of sub-cycled coupling for non-uniform air.
1249
+ - Sealed pockets under a warm start.
1250
+
1251
+ ## 21. Sources
1252
+
1253
+ - Renard, "Wind Simulation in God of War", GDC 2019 (speaker notes, quotes checked).
1254
+ - NVIDIA Flow, `NVIDIA-Omniverse/PhysX` `flow/source/nvflow/Pressure.cpp`.
1255
+ - Cohen, Tariq, Green, I3D 2010.
1256
+ - WRF v4 technical note; Harris & Durran.
1257
+ - Vulkan Required Limits (docs.vulkan.org); realtimerendering.com "Direct 3D Details Part V".
1258
+ - McAdams, Sifakis, Teran 2010; Trottenberg, Oosterlee, Schüller, *Multigrid*.
1259
+ - English et al. 2013.
1260
+ - Selle et al. 2008; Zehnder et al. 2018; Nabizadeh et al. 2022; Qu et al. 2019; Rabbani et al. 2022.
1261
+ - GPU Gems 1 ch. 38, GPU Gems 3 ch. 30; Stam 2003.
1262
+ - Panteleev 2014; Rockenbeck 2021; HOME-LBM 2023.
1263
+ - Karras 2012, as implemented in `gpu_primitive/bvh/`.
1264
+ - `mg2.mjs`, `sor.mjs` (CPU models of §8, session scratchpad, reproduced 2026-10-16).
1265
+
1266
+ ## 22. Review record
1267
+
1268
+ **b → c.** Two adversarial passes. The blockers were the gust clock and NaN paths; about twenty
1269
+ majors followed. All were answered in (c); (d) superseded several answers.
1270
+
1271
+ **c → d.** Alex's review: R1–R5, G1, G2.
1272
+
1273
+ **d → e.** A reference check and a design attack.
1274
+
1275
+ - **Blocker, measured and reproduced:**
1276
+ - The CPU's open-face rule on every multigrid level stalls the V-cycle (0.66/0.75) → the
1277
+ finite-volume coarse boundary (0.10/0.30).
1278
+ - A frozen-halo SOR with both colours diverges → a colour mask, ω = 1 asserted for both colours,
1279
+ and the SOR arm at one colour per dispatch.
1280
+ - **Majors:**
1281
+ - Uniform air seamed between coarse steps; dropped ticks broke the ring → the read-time identity
1282
+ with per-cascade records (§6).
1283
+ - The gust was low-passed by drag (16–84% kept) → `v_far = u + g`.
1284
+ - `force` at `D = 0` was unbounded and became a world downdraft → kept out of the far field.
1285
+ - The speed clamp capped the wind at fine cells → it clamps the deviation.
1286
+ - Parent pressure carried no unit scaling → physical pressure.
1287
+ - Unbounded leaves (planes) put NaN into the LBVH → boxes clipped to the coarsest windows.
1288
+ - Per-brick caps overflowed on coarse cascades, with flicker under Morton order and per-thread
1289
+ visit budgets of 128 → cooperative queries, separate caps, row-index survivors, resolution cull.
1290
+ - The LBVH is 19 dispatches and was rebuilt every tick → once per frame, refit unless membership
1291
+ changed or every 16th frame, and the budget recounted (§14: at or over target until in-pass cost
1292
+ is measured).
1293
+ - Hash change detection was not the particle pattern and failed both row kinds → field-wise
1294
+ compare.
1295
+ - "Four inline workgroup sums" were four different computations, with an indexing rule the engine
1296
+ itself warns against → subgroup op + one atomic, the ledger corrected.
1297
+ - A subgroup append existed (`chunk_vsm_append_mover`) → generalised.
1298
+ - Water's `windy` gate, shore reflection and fetch direction → §6.
1299
+ - A live velocity would repack every volume every frame → per-row phase writes.
1300
+ - **Recount, at Alex's question.** "55–73 a frame" overstated a cascade step (~25 against 21
1301
+ counted) and left out the fluid database uploads and the query gather (2–4 a frame). It also never
1302
+ stated two-tick frames. Re-running the CPU model then showed that stopping the V-cycle at 8×4×8
1303
+ matches 4×2×4 (0.296) at 32, 64 or 400 coarsest sweeps. The V-cycle is now 13 passes, a tick 38
1304
+ dispatches, a one-tick frame 42–62, and a two-tick frame 80–100 (§14).
1305
+ - **The BVH, at Alex's question.**
1306
+ - The rebuild's 19 dispatches are Morton (1), a 4-digit radix sort at 4 dispatches a digit
1307
+ (histogram, scan prepare, indirect scan, scatter: 16), emission (1) and refit (1). All of them
1308
+ are near-empty at fluid scale.
1309
+ - Alex approved a small-scene path in `graph_bvh_build_lbvh`, and it was started as its own task.
1310
+ He also corrected a question of mine: "this is an engine, there is no such thing as a 'typical',
1311
+ the engine is build to scale … most cases will have very small number of elements, so having a
1312
+ fast path for that is a big win."
1313
+ - **Minors:** window-local tiles for odd face periods; the LDS-advection sizes (predict only); MGPCG's
1314
+ symmetry; the leaf order; the TLAS bound wording; the default `GPUSceneWind`; the water low-pass
1315
+ seed; nested loop budgets stated; BVH-quote provenance; the sync helper being one line; LDS shaders
1316
+ mostly 1-D; the binding-budget premise.
1317
+ - **S1, built and measured (2026-10-16).** The solver core exists as `GPUFluidCascade`
1318
+ (`shade/renderer/fluid/`): `GPUFluidPressureSolve` (V-cycles or SOR) and `FluidMacPasses`
1319
+ (predict, correct, divergence, gradient), every kernel a WGSL twin of its CPU model or kernel, and
1320
+ all nine compiled through Tint on the 4090. Measurements moved four things here:
1321
+ - the V-cycle is 10 passes, not 13 (prolongation folded into the smoother, bit for bit), plus 4
1322
+ weight passes a solve that §14 had left out; a step is 28 dispatches at two V-cycles;
1323
+ - the coarsest level sweeps 8 times, not 32 (a third of a V-cycle on the device, no change in the
1324
+ factor on three or more levels);
1325
+ - the divergence reads its faces directly (2× faster than its LDS tile);
1326
+ - small dispatches cost 1–2 µs back to back, so the §14 cost model of 5–8 µs a pass was replaced by
1327
+ the measured step (115 µs at 64×32×64, 245 µs at 128×32×128).
1328
+ The quality slow-spec holds the GPU step to the CPU on every scenario (D7 confirmed), and the CPU far
1329
+ field (S3's fold, gust and identity) was built alongside it.
1330
+ - **S2, built and measured (2026-10-16).** `GPUFluidCascadeStack` (`shade/renderer/fluid/`): placement
1331
+ through `ClipmapWindowSet` (`FluidCascadePlacement`, with `clamp_corner`), the ruler
1332
+ (`fluid_cascade_ruler`), fills, two-way feedback, parent seams and Dirichlet ghosts, the correct
1333
+ pass's epilogue (identity, band, clamp) and per-cascade read records. Every kernel compiles through
1334
+ Tint at the default limits; the most storage bindings are the smoother's and the residual's 7. A
1335
+ uniform wind is exact everywhere, bit for bit, across three cascades through gusts, a changing drag,
1336
+ dropped ticks and refills (the stack's recorded ticks run under the emulator). On the device: the
1337
+ seam probe confirms D8 (above); 4,000 ticks at the defaults with a moving anchor stay finite with the
1338
+ non-finite counter at 0, in calm air no deviation ever exceeding its seeded 1.72 m/s; a 1 km teleport
1339
+ re-places and refills all four cascades to the far field exactly. A tick cost 214 µs alone and
1340
+ 432 µs with a coarse step (§14), the parent seams most of the excess; the step's ghosts (D3), one
1341
+ dispatch that evaluates the parent's read once, take it to 144 µs alone and 292 µs with a coarse
1342
+ step against 247 and 490 in the same paired run, the state bit for bit the same. The stack's
1343
+ `record_publish` sets `GPUSceneWind` and publishes each cascade that changed, its skirt the
1344
+ parent's read; uniform air reads back `v_far` exactly through `wind_field_sample`.
1345
+ - **S4, the ECS half, built and measured (2026-10-16).** `GPUFluidComponent` and `GPUFluidSystem` (§5): a
1346
+ scene gets the GPU wind by adding a component. The CPU effectors moved onto `fluid_record_apply` (D12):
1347
+ impulse and wake deposit through their records, so the CPU and GPU fluids deposit the same momentum; a
1348
+ sub-cell push that carried 13–77× the continuum's momentum now carries 0.98–1.08 of it, a wake 0.22–0.32 of
1349
+ its swept momentum now 1.00–1.07. From two cells up the push is within 1.43e-5 of its peak of the old one,
1350
+ not bit for bit (the old apply rounded its grid-space centre to f32). The census found no system reordered
1351
+ by the new system. The mixed forest's frontier loss and the several-domains rule are §18's forks.
1352
+ - **S4d, built and measured (2026-10-16).** Two gaps S4 measured. *The frontier* (§10): the resolution
1353
+ cull became the tree's structure, a tree per resolution a stepping cascade needs, over the effectors
1354
+ and the obstacles at least half its cell wide by the record's own extent, shared where the sets are
1355
+ equal, built only by the ticks that need it, each with its own cadence. On the RTX 4090 the mixed
1356
+ forest keeps every obstacle the reference keeps at every cascade, nothing dropped (S4: 134–148 of 658
1357
+ lost at cascade 3); 6 + 6 rows cost the same as before, the mixed forest +2.9% over a 16-tick cycle.
1358
+ *Vorticity confinement* (§8): pass 1 and its term in pass 3, the twin of the CPU kernel, `ε·dt_c` and
1359
+ `h_c` per cascade, from `GPUFluidComponent.vorticity_confinement`; 8.2 µs a step on, nothing off.
1360
+ - **S5, built and measured (2026-10-16).** The read API (§12): `GPUFluidSystem#request` and `#status` over
1361
+ `GPUFluidQueries`, headless answered from the far field; `ClothGPUFluidWind`; `ClothAmbientWind` and
1362
+ `GlobalFluidEffector#apply` removed; cloth's parity gate restated. One departure from §10: the query tables
1363
+ are a database of their own, since a request is answered with no domain and the forcing's database lives
1364
+ only while one does. Measured on the 4090: a lattice lands a median 2 frames after it is asked for (95th
1365
+ percentile 3), and a wake crossing in front of three ribbons reads 2.77 m/s off the far field through it.
1366
+ - **S3's volumetrics, corrected (2026-10-16).** S3 kept one `GPUFluidSystem.request()` per volume centre and
1367
+ folded that one read-back wind into the volume's phases. Alex rejected it: "it breaks the GPU-driven design.
1368
+ We already have all of the data on the GPU, and yet we bring CPU into the equation. We should just sample on
1369
+ the GPU, and we might as well sample per-froxel instead of one tap at the origin. The volume is continuous,
1370
+ so the result will be continuous too." The method he chose, *far phase + flow map*: the far field stays the
1371
+ host's exact scroll (`far_field`, deterministic, no readback); per evaluated point the GPU samples the
1372
+ published field and carries the noise by the departure as a flow map, two phases half a period apart on a
1373
+ host-folded clock, because a froxel has no history to integrate a phase in and `t·w(p)` would jump by
1374
+ `t·Δw`. Built as §6 says, with P and the threshold measured there. The per-volume requests and everything
1375
+ that existed for them (handles, landing buffers, the status walk) are gone. Two defects surfaced on the way:
1376
+ the host scroll carried the noise upwind (the lookup is `position/scale + offset` and the offset grew with
1377
+ the velocity), and the accumulating path tracer's pass threw on every frame since the noise landed
1378
+ (`this.#graphics` read inside a plain `execute`); both fixed and pinned. Measured and left open: the
1379
+ uniform-air cost of the flow map's code (§6), and the flow map's reach: with the departures the fluid
1380
+ produced here (median 0.33 m/s, at most 2.9 m/s, past 0.1 m/s) on the default 8 m features, the balance
1381
+ point leaves the pulse and the stretch both near 0.9, so the departure reads mostly as an in-place
1382
+ rebuild; a smaller `noise_scale` moves the balance toward motion.