@woosh/meep-engine 3.60.4 → 3.60.5

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 (379) hide show
  1. package/CHANGELOG.md +2602 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  63. package/src/shade/renderer/Renderer.js +7 -5
  64. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  67. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  68. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  69. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  70. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  71. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  72. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
  74. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
  75. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
  77. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  78. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  80. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  81. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  82. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  83. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  85. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  86. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  87. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
  88. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  89. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
  90. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  91. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  92. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  93. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  94. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  96. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  98. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  99. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  100. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  101. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  102. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  103. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  104. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  105. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  106. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  107. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  108. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  109. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  110. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  111. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  112. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  113. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  114. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  115. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  116. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  117. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  118. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  119. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  120. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  121. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  122. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  123. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  124. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  126. package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
  127. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  128. package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
  129. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  130. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  131. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  132. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  133. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  134. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  135. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  136. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  137. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  138. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  139. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  140. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  141. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  142. package/src/shade/renderer/water/shader_water.js +22 -13
  143. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  144. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  145. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  146. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  147. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  148. package/editor/REWORK_PLAN_2026_08.md +0 -692
  149. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  150. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  151. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  152. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  153. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  154. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  155. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  156. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  157. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  158. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  159. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  160. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  161. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  162. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  163. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  164. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  165. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  166. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  167. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  168. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  169. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  170. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  171. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  172. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  173. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  174. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  175. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  176. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  177. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  178. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  179. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  180. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  181. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  182. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  183. package/src/REVIEW_2026_08_06/generation.md +0 -176
  184. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  185. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  186. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  187. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  188. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  189. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  190. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  191. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  192. package/src/REVIEW_2026_08_06/view.md +0 -667
  193. package/src/REVIEW_2026_08_06.md +0 -610
  194. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  195. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  196. package/src/core/bvh8/NOTES.md +0 -63
  197. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  198. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  199. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  200. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  201. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  202. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  203. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  204. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  205. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  206. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  207. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  208. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  209. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  210. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  211. package/src/engine/REVIEW_2026_07_03.md +0 -211
  212. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  213. package/src/engine/control/first-person/DESIGN.md +0 -658
  214. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  215. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  216. package/src/engine/control/first-person/TODO.md +0 -160
  217. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  218. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  219. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  220. package/src/engine/ecs/ik/PLAN.md +0 -179
  221. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  222. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  223. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  224. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  225. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  226. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  227. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  228. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  229. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  230. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  231. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  232. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  233. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  234. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  235. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  236. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  237. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  238. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  239. package/src/engine/physics/cloth/PLAN.md +0 -3056
  240. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  241. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  242. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  243. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  244. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  245. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  246. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  247. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  248. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  249. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  250. package/src/format/image/avif/DECISIONS.md +0 -545
  251. package/src/format/image/jpeg/NOTES.md +0 -3
  252. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  253. package/src/generation/COORDINATES.md +0 -54
  254. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  255. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  256. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  257. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  258. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  259. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  260. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  261. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  262. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  263. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  264. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  265. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  266. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  267. package/src/shade/RENDERER_CONTRACT.md +0 -697
  268. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  269. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  270. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  271. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  272. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  273. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  274. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  275. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  276. package/src/shade/renderer/NOTES.md +0 -78
  277. package/src/shade/renderer/PLAN.md +0 -8
  278. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  279. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  280. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  281. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  282. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  283. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  284. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  285. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  286. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  287. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  288. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  289. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  290. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  291. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  292. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  293. package/src/shade/renderer/camera/orbital/README.md +0 -81
  294. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  295. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  296. package/src/shade/renderer/camera/orbital/index.js +0 -9
  297. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  298. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  299. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  300. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  301. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  302. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  303. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  304. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  305. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  306. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  307. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  308. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  309. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  310. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  311. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  312. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  313. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  314. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  315. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  316. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  317. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  318. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  319. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  320. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  321. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  322. package/src/shade/renderer/hiz/NOTES.md +0 -3
  323. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  324. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  325. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  326. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  327. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  328. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  329. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  330. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  331. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  332. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  333. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  334. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  335. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  336. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  337. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  338. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  339. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  340. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  341. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  342. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  343. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  344. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  345. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  346. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  347. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  348. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  349. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  350. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  351. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  352. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  353. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  354. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  355. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  356. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  357. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  358. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  359. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  360. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  361. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  362. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  363. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  364. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  365. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  366. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  367. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  368. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  369. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  370. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  371. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  372. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  373. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  374. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  375. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  376. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  377. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  378. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  379. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,336 +0,0 @@
1
- # Noise for participating-media volumes — design brief, 2026-10-15
2
-
3
- Status: **revision (c), built.** Written against the tree at 59861de99; the implementation is what
4
- the tree beside this file holds, and `NOTES.md` (2026-10-15) has the device numbers. Revisions (a)
5
- and (b) proposed a procedural field and then a texture with a stack of phases; Alex's answers
6
- (§6) settled on one static texture per slot in a general 3-D tile atlas, evolution by scrolling and
7
- a domain warp, no stacks, no clock. §4 and §5 describe what was built; §7 is what was left open.
8
-
9
- The ask: noise-modulated density on `ParticipatingMedia` volumes with a simple API and a cost that
10
- stays flat. The starting concept was a fixed number of octaves of 4-D noise, sampled in world
11
- space, with a per-volume scale and temporal rate, a per-volume lerp between uniform and noisy so one
12
- shader path serves both, and a global wind vector.
13
-
14
- ## 1. What the tree had
15
-
16
- Facts, read from the sources, each of which shaped the design.
17
-
18
- **The volume model is a unit box posed by a matrix, carrying `density`, a particle spec, and an
19
- edge fade.** `PARTICIPATING_MEDIA_VOLUME_STRUCT` was `particle_spec`, `transform`,
20
- `transform_inverse`, `fade_distance`, `density` — a row in the scene database, rows packed from 0
21
- and rewritten whole whenever `SceneVolumetrics.version` moves. The renderer-side
22
- `ParticipatingMediaVolume` carried six dead stub fields (`noise_scale/amplitude/offset/velocity/
23
- evolution_speed`, `time`) from an older version of this very concept; nothing read them. Deleted.
24
-
25
- **The froxel density pass had no sample point.** `shader_volumetrics_build_participating_media`
26
- runs a 16×16 workgroup per z-slice over `ceil(w/16) × ceil(h/16) × 64` froxels — 120×68×64 =
27
- 522,240 at 1080p, 2,073,600 at 2160p. Per froxel it builds the slab's world frustum (the z edges
28
- carry the per-column jitter), then for every volume row: reject on `aabb3_intersects_frustum`,
29
- estimate `frustum_unit_box_coverage` (8 three-plane intersections), evaluate the edge fade at the
30
- midpoint of the centre ray's intersection with the box, and accumulate `density × coverage × fade`.
31
- The density was a slab average, never a value at a point. Adding noise meant choosing a point, and
32
- the rule from 2026-10-09 applies — a froxel's value is evaluated at a per-frame jittered point,
33
- never a fixed lattice, or a large particle reading the volume shows the lattice as seams.
34
-
35
- **The lighting pass reads the density textures at a jittered point and the TAA integrates it.**
36
- STBN at the `(37, 71)` decorrelation offset, the 3-D TAA at 0.95, about 39 effective frames,
37
- reprojected by camera motion only. A density field that moves in world space is averaged over the
38
- window, not reprojected.
39
-
40
- **Nothing downstream re-evaluates the volumes.** The sun's optical-depth cascades and the
41
- local-light march both read `tParticipatingMedia1`, the froxel extinction texture. Noise costs once,
42
- in the density pass, never per shadow step.
43
-
44
- **The path tracer evaluates the volumes analytically and needs a majorant.**
45
- `participating_media_volume_density_at(volume, p)` is bounded above by `density`, and
46
- `chunk_medium_volumes`'s piece majorant is `Σ density × extinction`. The noise had to be a factor
47
- in [0, 1], applied inside that one function, or the null-collision estimator goes biased.
48
-
49
- **psrdnoise was in the tree with a GPU consumer already.** `chunk_psrdnoise3(x, period, alpha)`
50
- tiles at any integer period up to 289 on each axis. That property is what makes the bake exact:
51
- each octave gets an integer period across the tile, so each tiles on its own.
52
-
53
- **There was a 3-D slot atlas, a slot allocator, and a texture that resizes with its contents.**
54
- `GPUGeometrySDFManager` packs 50³ SDF slots into one 3-D texture and grows; `PageSlotAllocator` is
55
- an O(1) free list; `GPUTextureContext.resize(…, true)` copies the old extent across. None was a
56
- general tile atlas. The 2-D terrain atlas is a rect packer for arbitrary patches, a different thing.
57
- Brixelizer carries its own 8³ brick SDF atlas (the FFX port) and was left alone, as asked.
58
-
59
- **WebGPU has no bindless and no compressed 3-D textures.** A per-volume texture is an atlas or
60
- nothing, and the atlas is `r8unorm`: BC4 is 2-D only there. And no `r8unorm` storage texture in
61
- core WebGPU, which is why the bake writes a byte block into a storage buffer and copies it in.
62
-
63
- **Froxels are long in z.** On the 64-slice log curve a slab is ≈16% of its depth (≈8 m at 50 m,
64
- ≈79 m at 500 m); a 16-px tile at 1080p is ≈1.4% of depth across. Features finer than the slab are
65
- averaged by the jitter and the TAA into a lower-contrast mean, so distant fog goes uniform on its own.
66
-
67
- ## 2. What the field ships
68
-
69
- Tagged **VERIFIED** where the slides or source were read, **SECONDARY** where only documentation
70
- or a search summary was, **NOT RE-READ** where the material exists but was not opened.
71
-
72
- **Smolder — IO Interactive, 007 First Light, SIGGRAPH 2026 Advances (VERIFIED, slides + notes).**
73
- Not a noise system: a per-pixel raymarcher over baked animated density (OpenVDB frames in a custom
74
- sparse brick format, 4³ bricks stored 5³, 4 bits a voxel), 4-moment volumetric shadows on async
75
- compute, segment-based overlap culling (4 volumes), an adaptive lighting rate. No temporal
76
- filtering inside, blue noise per pixel, FSR's reactive mask. The density lookup "was only a small
77
- fraction" of the per-sample cost; and the one thing they refused was a fallback that makes artists
78
- "author content twice". 450 volumes shipped. Slides:
79
- `advances.realtimerendering.com/s2026/content/AlexanderMueller_Smolder_Siggraph26.pdf`.
80
-
81
- **Enshrouded — Keen Games, GPC 2025 "The fog is lifting" (VERIFIED, slides).** A froxel volume
82
- (160×90×64, to 10 km, temporally accumulated on the populate pass only) for atmosphere, weather and
83
- VFX-injected box volumes — `densityTexture, uvOffset, uvScale, density, falloff, …` — and a
84
- half-resolution ray march for the dense shroud over a world voxel volume (16³ tiles with a
85
- "half voxel border on each side for seamless trilinear filtering"). **Detail noise is baked**:
86
- Nubis-Cubed "Curly-Alligator" and "Alligator" types, "tileable, 128x128x128 four channels
87
- uncompressed", eroding density at ray-march samples. Slides on
88
- `static.graphicsprogrammingconference.com/public/2025/talks/the-fog-is-lifting-volumetric-rendering-enshrouded/`.
89
- The GPC 2024 talk (Lukas Feller, linked at the top of `NOTES.md`) is video only.
90
-
91
- **Assassin's Creed 4 — Wronski, SIGGRAPH 2014 (VERIFIED).** "Just one octave of Perlin noise that
92
- is animated by wind. We tried using multiple octaves, but in the end difference was rather subtle
93
- for added cost." Density and lighting 0.43 ms on PS4 at 160×90×64.
94
-
95
- **Bevy `scrolling_fog` (VERIFIED, source).** A repeating 3-D noise texture, a
96
- `density_texture_offset` the app advances on the CPU by `velocity × dt`, jitter under TAA.
97
-
98
- **Godot 4 FogMaterial (SECONDARY).** A static 3-D `density_texture` in clamped local box space,
99
- height falloff, edge fade; animation needs a custom shader. **Unity HDRP (SECONDARY):** 3-D mask
100
- texture, scroll speed and tiling per axis. **Unreal 5.4 (VERIFIED):** local fog
101
- volumes are analytic (radial + exponential height, no noise); froxel fog density comes from
102
- Volume-domain materials evaluated per froxel at a jittered slice depth. **Frostbite 2015, RDR2
103
- 2019, Nubis Cubed 2023 (NOT RE-READ):** PPTX only, or cited through Enshrouded.
104
-
105
- **The pattern.** Froxel fog ships one or two octaves of 3-D noise scrolled by wind, or a baked
106
- tileable 3-D texture eroding a density; hero effects are baked animated voxels. The 3-D texture is
107
- the universal artist hook, and 128³ is the size the two most recent references use.
108
-
109
- ## 3. What it costs
110
-
111
- Per (froxel, volume) the noise is two trilinear `r8unorm` taps into an atlas of a few MiB (one tap
112
- when `noise_warp == 0`) plus ~25 scalar ops of coordinate arithmetic, against the ~300 ops the
113
- coverage estimator already spends per volume in the same loop. Paid only inside `aabb_intersects`;
114
- a froxel with no volume pays nothing, and a volume at `noise_strength == 0` branches around it
115
- uniformly, so a scene with no noisy volume costs what it did before. The device numbers, taken by
116
- the paired protocol in `volumetrics_froxel/measure.js` at 2160p, are in `NOTES.md` (2026-10-15).
117
-
118
- ## 4. The concept, item by item, as built
119
-
120
- **Fixed number of octaves — 3, baked into the default tile.** Lacunarity 2, gain 0.5, three
121
- octaves of `psrdnoise3` at integer periods 4, 8 and 16 lattice units across the content, each
122
- offset by a constant times its index so the doubled lattices do not sit on the base one's corners.
123
- The finest octave is 8 texels a wavelength in a 128³ tile. At runtime the octave count is not a
124
- parameter: it is whatever the texture holds, and a user tile may hold one or ten at the same cost.
125
-
126
- **4-D noise — dropped (F1), on Alex's call.** "3-D preserves mass/volume better perceptually; 4-D
127
- is great for variation but with discrete samples not worth it, blurrier borders for little benefit
128
- and 2x taps." No phase stack either, for memory. The evolution is **scroll plus a domain warp**: a
129
- second tap of the same tile at half frequency and its own, slower scroll displaces the base lookup
130
- along a fixed oblique direction by `noise_warp` tile units times how far the warp value sits from
131
- its mean. As the two scrolls slide against each other (ratio 0.37) the base field changes shape in
132
- place. `noise_warp == 0` is one tap and a field that only slides.
133
-
134
- **Time tick / supplied time — no clock at all.** The scroll is a **phase on the volume**, two
135
- `[0, 1)³` offsets (`noise_offset`, `noise_warp_offset`) advanced once a frame by
136
- `participating_media_volume_advance_noise(volume, velocity, dt)` in f64 and wrapped there — a
137
- running sum, so a change of wind never jumps the field and a session running for days never grows
138
- a number. `ParticipatingMediaSystem.update(dt)` is the caller for an ECS scene; a playground calls
139
- it from its loop. Not called, the field stands still, which is what an accumulating reference
140
- wants. The GPU never multiplies a velocity by a time.
141
-
142
- **Temporal scale per volume — became `noise_warp`.** A rate had no meaning without a 4th
143
- dimension; the warp amount is the knob that sets how much the field changes shape as it moves.
144
-
145
- **World-space sampling — kept, with repeat.** The tile repeats every `noise_scale` metres along
146
- each world axis; `fract` folds the world position onto the tile. Neighbouring volumes with the same
147
- settings share one continuous field, and a volume carried by a moving entity has the world's fog
148
- flow through it. User tiles must tile seamlessly; the engine's does by construction.
149
-
150
- **Noise scale per volume — one scalar, metres per tile repeat.** `noise_scale`, default 32 m,
151
- which with the default tile's four base features puts them 8 m apart and the finest octave at 2 m.
152
-
153
- **Lerp between noisy and uniform — `noise_strength ∈ [0, 1]`, blending to the texture's [0, 1]
154
- value.** `density(p) = density × fade(p) × mix(1, tile(p), strength)`. Bounded by `density`, so the
155
- tracer's majorant, the ray spans and the froxel coverage arithmetic are untouched. The remap that
156
- shapes the wisps — `smoothstep(−0.6, 0.6, fBm)`, psrdnoise's fBm sits in about ±0.7 — is baked, so
157
- the texture *is* the multiplier and a user tile is one too, with nothing more to say.
158
-
159
- **Uniform path.** `noise_strength == 0` branches around the taps inside the volume loop: a property
160
- of the volume, identical for every thread, so a uniform branch and not a variant.
161
-
162
- **Global wind — `SceneVolumetrics.wind`, felt per medium.** Per Alex's F7: effective velocity
163
- `= wind × noise_wind_factor + noise_velocity`, two explicit fields on the component, folded by the
164
- system into the phase. The row carries phases only. *Superseded 2026-10-16 (GPU fluid S3,
165
- `GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md` §6): `SceneVolumetrics.wind` is removed, and a scroll
166
- writes each row's phase words through `SceneVolumetrics.invalidate_noise()` instead of repacking the
167
- table. The phases fold the scene's far field (`GPUFluidSystem.far_field`, still air without one);
168
- the fluid's departure from it is sampled on the GPU wherever the noise is evaluated and carries the
169
- noise as a flow map, on a flow clock the host folds into the row (`noise_flow_phase`, period 2.5 s),
170
- scaled by `noise_wind_factor`, which the row now carries too. A per-volume read-back of the wind was
171
- built first and withdrawn on Alex's word: the data is on the GPU. The scroll also changed sign: it
172
- had carried the noise upwind.*
173
-
174
- **Where the froxel pass evaluates it.** Once per froxel, before the volume loop, a world point
175
- inside the slab at an STBN jitter with a **third** decorrelation offset `(53, 97)` — the aerial pass
176
- owns zero and the lighting pass `(37, 71)`, and two passes drawing the same number lock their
177
- nuisance variables together, which biases the estimate and no TAA window recovers it. Per volume
178
- inside `aabb_intersects`, the multiplier at that point scales the slab's weight. The slab's z jitter
179
- is already per frame, so the point moves on all three axes.
180
-
181
- **Band limiting — none (F2).** No mips (a one-texel skirt is wrong from level 1 down, and the
182
- tracer samples one level anyway), no octave skipping; the texture is band-limited at its texel and
183
- the jitter plus the TAA average the froxel.
184
-
185
- **What the path tracer gets.** The same `participating_media_volume_density_at`, which now needs
186
- `tParticipatingMediaNoise` and `sParticipatingMediaNoise` bound by every shader that imports it:
187
- the accumulating tracer, `graph_path_trace_scene`, the Brick4 probe bake, both lightmap viz bakes
188
- and the deprecated LPV trace all declare and bind them.
189
-
190
- **The TAA envelope — a stated limit.** At 0.95 the history spans ≈39 frames, 0.65 s at 60 Hz; a
191
- feature scrolls `|v| × 0.65 s` inside that window. Wind at a few m/s on 8 m features is fine; 10 m/s
192
- on 2 m features is mush, and a history reprojected by the scroll is a separate piece of work.
193
-
194
- ## 5. The design, in one place
195
-
196
- ### 5.1 `GPUTileAtlas3D` — general, one instance for the volumetrics
197
-
198
- `shade/renderer/texture/atlas/GPUTileAtlas3D.js`. One 3-D `GPUTextureContext` of one format, cut
199
- into tiles of `content_size + 2·border` texels, slots linear (x fastest, z slowest), handed out by
200
- a free list that reuses the most recently freed slot first.
201
-
202
- - `new GPUTileAtlas3D({ device, format, content_size, border, slots_x, slots_y, capacity, usage, label })`,
203
- every argument required. `slots_x`/`slots_y` are the starting footprint; `capacity` is rounded
204
- up to whole z layers of it. `usage` is how the clients bind the texture (`TEXTURE_BINDING`,
205
- `STORAGE_BINDING`); the atlas adds the `COPY_DST | COPY_SRC` its writes and grows need (added
206
- 2026-10-16 for the SDF manager, whose build stores into its tiles).
207
- - `allocate()` returns a slot and, when none is free, **grows the texture by a layer**, copying the
208
- old extent across (`resize(…, true)`; x and y do not change, so every tile keeps its origin).
209
- **Once z is at `maxTextureDimension3D` it widens instead** (2026-10-16, Alex's design): the
210
- smaller of x and y doubles (x on a tie, capped at the device), the layers halve (+1 for the slot
211
- being allocated), and every tile handed out is copied — in runs along x, a whole old row per
212
- copy when a side doubles — to where its slot sits under the new footprint, through
213
- `GPUTextureContext.replace`. A slot keeps its index and texels; its origin moves. Rare and as
214
- costly as a full copy. The ceiling is `capacity_limit`, the device's limit in tiles cubed; past
215
- it, `allocate` throws with the numbers. `free(slot)`, `is_live(slot)`, `live_count`.
216
- - `write(slot, content)` takes `content_size³` texels and builds the skirt on the host
217
- (`tile_atlas_bordered_block`, pure and exported: the skirt is the content wrapped) in one
218
- `writeTexture`. `copy_from_buffer(encoder, slot, buffer, offset, bytes_per_row)` lands a whole
219
- bordered tile a device producer wrote, rows padded to the copy alignment.
220
- - `slot_origin(slot, out)` is the same arithmetic in JS and WGSL.
221
- - A grow replaces the `GPUTexture` and a widen moves every tile; take a view, the footprint or an
222
- origin after allocating, never across an `allocate`. The frame graph imports the texture per
223
- frame and the noise shader takes the footprint from `textureDimensions`, so the passes are fine
224
- by construction.
225
-
226
- The volumetrics instance (`PARTICIPATING_MEDIA_NOISE.js`): `r8unorm`, content 128, border 1
227
- (tile 130), footprint 2×1, capacity 2 — the engine's tile and one spare, 4.4 MB — growing by 2
228
- slots (4.4 MB) a layer to 30 on a 2048-limit device, then widening. Per scene, on `GPUSceneVolumetrics.noise_atlas`:
229
- a volume names its tile by slot and the volumes are the scene's.
230
-
231
- `GPUGeometrySDFManager` is the second instance (G4, 2026-10-16): `r32float`, content 50, border 0
232
- (every reader loads inside its tile and clamps the far tap to the last texel, and a wrapped skirt
233
- would be wrong for a distance field anyway), starting footprint 4×4 — the 16 slots it started with,
234
- and its smallest growth step — to 40 layers (640 slots, 320 MB) on a 2048-limit device, then
235
- widening to 8×4×21 and on. A slot is its geometry's id, so it claims slots in order and frees none.
236
- Brixelizer's atlas is not migrated.
237
-
238
- ### 5.2 The engine's default tile — slot 0, baked on first update
239
-
240
- `shader_volumetrics_noise_tile_bake` + `bake_volumetrics_noise_tile`: a compute dispatch over the
241
- whole 130³ tile — skirt included, by wrapping the texel index, the same rule the host applies — into
242
- a transient storage buffer of 256-byte rows, four `r8unorm` texels a word, then
243
- `copyBufferToTexture` into the slot, in one command stream. Three octaves at periods 4/8/16,
244
- `features` 4, remap baked. Runs once, from `GPUSceneVolumetrics.update` the first time it is
245
- called (a bake needs a command stream and the constructor has none). Deterministic, so the
246
- emulator bakes small tiles in `shader_volumetrics_noise_tile_bake.spec.js`.
247
-
248
- ### 5.3 The API
249
-
250
- ECS, flat on `ParticipatingMedia`:
251
-
252
- noise_strength = 0 // [0, 1]; 0 = uniform, nothing evaluated
253
- noise_scale = 32 // metres per tile repeat (default tile: 8 m base features)
254
- noise_warp = 0.1 // tile units the warp may displace by; 0 = one tap, slide only
255
- noise_velocity = [0,0,0] // m/s, the medium's own motion, added to the wind
256
- noise_wind_factor = 1 // how much of the scene wind it feels
257
- noise_texture = 0 // atlas slot; 0 = the engine's
258
-
259
- Scene: `SceneVolumetrics.wind` (m/s) — removed 2026-10-16, see above. Tiles: `GPUSceneVolumetrics.noise_atlas` —
260
- `allocate()`, `write(slot, Uint8Array(128³))`, `free(slot)`.
261
-
262
- Renderer-side `ParticipatingMediaVolume`: `noise_strength`, `noise_scale`, `noise_warp`,
263
- `noise_slot`, and the phase state `noise_offset`, `noise_warp_offset`, advanced by
264
- `participating_media_volume_advance_noise(volume, velocity_m_s, dt_s)`, which returns whether
265
- anything moved.
266
-
267
- GPU row, appended to `PARTICIPATING_MEDIA_VOLUME_STRUCT`: `noise_offset: vec3f`,
268
- `noise_warp_offset: vec3f`, `noise_slot: u32`, `noise_strength: f32`, `noise_inverse_scale: f32`,
269
- `noise_warp: f32`. Packed by `GPUSceneVolumetrics` whenever the version moves — which, while any
270
- volume's phase moves, is every frame (tens of rows). *Since 2026-10-16 a scroll moves
271
- `SceneVolumetrics.noise_version` instead, and only the moved rows' phase words go up: seven, with
272
- `noise_flow_phase`; `noise_wind_factor` and `noise_flow_phase` sit in the padding after `density`.*
273
-
274
- Serialization: `ParticipatingMediaSerializationAdapter` version 1 (eighteen doubles),
275
- `ParticipatingMediaSerializationUpgrader_0_1` fills a version-0 save with the defaults.
276
-
277
- ### 5.4 The shader
278
-
279
- `chunk_participating_media_noise`, bound as `tParticipatingMediaNoise` (`texture_3d<f32>`) with
280
- `sParticipatingMediaNoise` (linear, clamped — the wrap is the skirt's and `fract`'s, never the
281
- sampler's, which would wrap the whole atlas):
282
-
283
- tap(slot, u): cell = (slot mod sx, (slot / sx) mod sy, slot / (sx·sy)), sx/sy from textureDimensions
284
- texel = cell·130 + 1 + fract(u)·128; sample at texel / atlas_size
285
- multiplier(volume, p):
286
- base = p · noise_inverse_scale; u = base + noise_offset
287
- if noise_warp > 0: w = tap(slot, base·0.5 + noise_warp_offset)
288
- u += (w − 0.5) · noise_warp · (0.6, 0.48, −0.64)
289
- return mix(1, tap(slot, u), noise_strength)
290
-
291
- `participating_media_volume_density_at` multiplies it in under `if (noise_strength > 0)`.
292
-
293
- ### 5.5 Specs
294
-
295
- `GPUTileAtlas3D.spec.js` (slots, placement, skirt, growth with tiles preserved — read back off the
296
- software device — the limit, formats); `shader_volumetrics_noise_tile_bake.spec.js` (emulator: skirt
297
- = content wrapped, range, periodicity of the field across the content, padding words untouched,
298
- octaves and features, determinism, the octave ceiling, WGSL validity);
299
- `chunk_participating_media_noise.spec.js` (emulator, hand-built atlas: texel centres, wrap, the
300
- skirt blend and never the next slot, strength, scale, scroll, the warp's displacement in closed
301
- form, the density function bounded); `ParticipatingMediaVolume.spec.js` (the advance: units,
302
- wrap, continuity, a week of frames); `GPUSceneVolumetrics.spec.js` and
303
- `GPUViewVolumetrics.passes.spec.js` (unchanged, now encoding the atlas); the ECS `*.noise.spec.js`
304
- trio (component JSON/equality, adapter round trip and the 0→1 upgrade, the system's fold and
305
- per-frame invalidation).
306
-
307
- ## 6. The forks, as answered
308
-
309
- Revision (a): **F1** flow noise — yes in principle, then ditched with the texture pivot (§4).
310
- **F2** octave band-limiting — "with textures insignificant", dropped. **F3** [0, 1] multiplier —
311
- "absolutely". **F4** CPU-side wrapped phase — fine, "a mod on the CPU". **F5** scalar scale — fine.
312
- **F6** delete the stubs — yes. **F7** per-volume velocity additive plus a multiplier on the wind —
313
- yes: `noise_velocity`, `noise_wind_factor`.
314
-
315
- Revision (b): **G1** no stacks — "one static texture, temporal variation via domain warping and
316
- scrolling"; built as scroll + warp. **G2** 128³ — yes. **G3** general atlas from day one — yes.
317
- **G4** migrating the SDF manager — a follow-up; Brixelizer left alone or promoted out of its FFX
318
- naming, not built on. **G5** world-space repeat only — yes. **G6** automatic growth — "house style";
319
- 16 slots was fine, 2 was chosen as the first layer since a layer is 4.4 MB and growth is automatic.
320
- **G7** `r8unorm` — yes.
321
-
322
- ## 7. Open, by measurement or by later ask
323
-
324
- - The repeat distance is `noise_scale`; at 32 m on a wide bank seen from above it may read as a
325
- lattice. The fix, if it shows, is a user tile with more features or a larger scale — no code.
326
- - A per-volume `contrast`, a local clamped sampling mode (a texture that *is* the shape), exponential
327
- height falloff, and history reprojected by the scroll: each a one-field or one-pass addition the
328
- layout leaves room for, none asked for.
329
- - The froxel-versus-tracer parity check for a noisy volume was not run on the device this pass;
330
- both paths read one function and the chunk spec pins the function.
331
-
332
- ## 8. Not verified this pass
333
-
334
- RDR2's and Frostbite's fog-density slides (PPTX only). Nubis Cubed's noise authoring (cited
335
- through Enshrouded). The GPC 2024 Enshrouded talk (video only). The contrast dip of a phase
336
- crossfade, which the no-stacks decision made moot.
@@ -1,23 +0,0 @@
1
- /** A view's water bodies: which the view draws and how, and their meshlets in row order. */
2
- export class GPUWaterBodies {
3
- /**
4
- * Draw culling over the frame's visible list (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §4.3), each drawn
5
- * body's lattice frame at its row, and the drawn bodies' meshlets. The expansion is an ordered prefix scan over the
6
- * rows, which preserves equal-depth ownership, including after holes and reuse.
7
- *
8
- * @returns {{meshlets: number, lod_bodies: number}} resources
9
- */
10
- meshlets({ graph, view, camera, meshlet_capacity, visible_rows, lod, steep }: {
11
- graph: any;
12
- view: any;
13
- camera: any;
14
- meshlet_capacity: any;
15
- visible_rows: any;
16
- lod: any;
17
- steep: any;
18
- }): {
19
- meshlets: number;
20
- lod_bodies: number;
21
- };
22
- }
23
- //# sourceMappingURL=GPUWaterBodies.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GPUWaterBodies.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/medium/GPUWaterBodies.js"],"names":[],"mappings":"AAkBA,4FAA4F;AAC5F;IACI;;;;;;OAMG;IACH;;;;;;;;QAFa;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,CAgDlD;CACJ"}
@@ -1,75 +0,0 @@
1
- import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
2
- import { round_up } from "../../../../core/math/round_up.js";
3
- import {
4
- graph_prefix_scan_csdldf,
5
- prefix_scan_csdldf_output_descriptor
6
- } from "../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
7
- import { graph_create_buffer } from "../../shader/graph/graph_create_buffer.js";
8
- import {
9
- build_indirect_compute_dispatch_command,
10
- INDIRECT_COMPUTE_COMMAND_DESCRIPTOR
11
- } from "../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
12
- import { shader_prefix_sum_to_command } from "../../rasterize/expand/mesh/shader_prefix_sum_to_command.js";
13
- import { shader_increment_count_by_prefix_sum } from "../../rasterize/expand/mesh/shader_increment_count_by_prefix_sum.js";
14
- import { graph_compute_pass } from "../../shader/graph/compute/graph_compute_pass.js";
15
- import { shader_water_meshlets_expand } from "./shader_water_meshlets.js";
16
- import { shader_water_lod_bodies } from "../surface/lod/shader_water_lod.js";
17
- import { WATER_LOD_BODY_STRUCT, WATER_LOD_VIEW_STRUCT } from "../surface/lod/WATER_LOD.js";
18
-
19
- /** A view's water bodies: which the view draws and how, and their meshlets in row order. */
20
- export class GPUWaterBodies {
21
- /**
22
- * Draw culling over the frame's visible list (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §4.3), each drawn
23
- * body's lattice frame at its row, and the drawn bodies' meshlets. The expansion is an ordered prefix scan over the
24
- * rows, which preserves equal-depth ownership, including after holes and reuse.
25
- *
26
- * @returns {{meshlets: number, lod_bodies: number}} resources
27
- */
28
- meshlets({ graph, view, camera, meshlet_capacity, visible_rows, lod, steep }) {
29
- const scene = view.scene, table = scene.scene_database.get('water_bodies');
30
- const capacity = Math.max(table.element_capacity, 1);
31
- const data = {};
32
- const pass = graph.add('Water / lod bodies', data, (d, resources, { encoder }) => {
33
- const command = resources.get(d.command);
34
- build_indirect_compute_dispatch_command(64, encoder, visible_rows, 0, command, 0, true);
35
- shader_water_lod_bodies.dispatchIndirect({ encoder, command, bindings: {
36
- capacity: round_up(capacity, 4), lod: encoder.allocateTransientValueBuffer(WATER_LOD_VIEW_STRUCT, lod),
37
- camera: resources.get(d.camera), scene_database: scene.scene_database_buffer,
38
- geometries: scene.geometries.buffer_metadata, visible_rows, steep,
39
- lod_bodies: resources.get(d.lod_bodies), counts: resources.get(d.counts),
40
- } });
41
- });
42
- data.camera = pass.read(camera);
43
- // The shared scan reads vec4u blocks, including the padded final block.
44
- const bytes = 16 + round_up(capacity, 4) * 4;
45
- data.counts = pass.create('counts', BufferResourceDescriptor.from(bytes, GPUBufferUsage.STORAGE, 0, bytes));
46
- data.command = pass.create('Water lod bodies command', INDIRECT_COMPUTE_COMMAND_DESCRIPTOR);
47
- data.lod_bodies = pass.create('Water lod bodies', BufferResourceDescriptor.from(capacity * WATER_LOD_BODY_STRUCT.size,
48
- GPUBufferUsage.STORAGE));
49
- const sums = graph_prefix_scan_csdldf({ graph, input: data.counts,
50
- output: graph_create_buffer(graph, 'Water lod body meshlet sums', prefix_scan_csdldf_output_descriptor(capacity)),
51
- element_max_count: capacity });
52
- const command_data = {};
53
- const command_pass = graph.add('Water / expand command', command_data, (d, resources, { encoder }) => {
54
- shader_prefix_sum_to_command.dispatch({ encoder, bindings: {
55
- prefix_sums: resources.get(d.sums), command: resources.get(d.command),
56
- } });
57
- });
58
- command_data.sums = command_pass.read(sums);
59
- const command = command_data.command = command_pass.create('command', INDIRECT_COMPUTE_COMMAND_DESCRIPTOR);
60
- const expand_data = {};
61
- const expand = graph.add('Water / expand meshlets', expand_data, (d, resources, { encoder }) => {
62
- shader_water_meshlets_expand.dispatchIndirect({ encoder, command: resources.get(d.command), bindings: {
63
- prefix_sums: resources.get(d.sums), output: resources.get(d.output),
64
- scene_database: scene.scene_database_buffer, geometries: scene.geometries.buffer_metadata,
65
- } });
66
- });
67
- expand_data.command = expand.read(command);
68
- expand_data.sums = expand.read(sums);
69
- expand_data.output = expand.create('meshlets', BufferResourceDescriptor.from(16 + Math.max(meshlet_capacity, 1) * 8,
70
- GPUBufferUsage.STORAGE, 0, 16));
71
- const { output } = graph_compute_pass({ graph, shader: shader_increment_count_by_prefix_sum,
72
- bindings: { prefix_sums: sums, output: expand_data.output } });
73
- return { meshlets: output, lod_bodies: data.lod_bodies };
74
- }
75
- }
@@ -1,4 +0,0 @@
1
- WASM is taken from this
2
- commit : https://github.com/gpuweb/tree-sitter-wgsl/blob/ca727304343930195bcaf36b97d23431d10fc996/tree-sitter-wgsl.wasm
3
-
4
- THE official grammer is tree-sitter, from WebGPU W3C: https://github.com/gpuweb/tree-sitter-wgsl