@woosh/meep-engine 3.60.4 → 3.60.6

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 (419) hide show
  1. package/CHANGELOG.md +2621 -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 +11 -0
  63. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  64. package/src/shade/renderer/Renderer.js +50 -6
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  67. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  68. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  69. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  70. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  71. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  72. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
  74. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  75. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
  77. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  78. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
  80. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
  82. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  83. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  85. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
  86. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
  88. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  89. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  91. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  92. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  93. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
  94. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
  95. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  111. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  112. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  113. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  114. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  115. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  116. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  117. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  118. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  119. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  120. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  121. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  122. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  123. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  124. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  125. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  126. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  127. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  128. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  129. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  130. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  131. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  136. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  137. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  138. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  139. package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
  140. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  141. package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
  142. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  143. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  144. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  145. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
  146. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  147. package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
  149. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  150. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
  151. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  152. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
  153. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  154. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
  155. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
  156. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
  158. package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
  159. package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
  160. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  161. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  162. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  163. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  164. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  165. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  166. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  168. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  169. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  170. package/src/shade/renderer/water/shader_water.js +22 -13
  171. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  172. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  173. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  174. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  175. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  176. package/editor/REWORK_PLAN_2026_08.md +0 -692
  177. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  178. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  179. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  180. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  181. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  182. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  183. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  184. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  185. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  186. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  187. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  188. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  189. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  190. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  191. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  192. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  193. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  194. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  195. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  196. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  197. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  198. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  199. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  200. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  201. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  202. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  203. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  204. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  205. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  206. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  207. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  208. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  209. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  210. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  211. package/src/REVIEW_2026_08_06/generation.md +0 -176
  212. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  213. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  214. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  215. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  216. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  217. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  218. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  219. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  220. package/src/REVIEW_2026_08_06/view.md +0 -667
  221. package/src/REVIEW_2026_08_06.md +0 -610
  222. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  223. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  224. package/src/core/bvh8/NOTES.md +0 -63
  225. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  226. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  227. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  228. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  229. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  230. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  231. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  232. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  233. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  234. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  235. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  236. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  237. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  238. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  239. package/src/engine/REVIEW_2026_07_03.md +0 -211
  240. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  241. package/src/engine/control/first-person/DESIGN.md +0 -658
  242. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  243. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  244. package/src/engine/control/first-person/TODO.md +0 -160
  245. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  246. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  247. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  248. package/src/engine/ecs/ik/PLAN.md +0 -179
  249. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  250. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  251. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  252. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  253. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  254. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  255. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  256. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  257. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  258. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  259. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  260. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  261. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  262. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  263. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  264. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  265. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  266. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  267. package/src/engine/physics/cloth/PLAN.md +0 -3056
  268. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  269. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  270. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  271. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  272. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  273. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  274. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  275. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  276. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  277. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  278. package/src/format/image/avif/DECISIONS.md +0 -545
  279. package/src/format/image/jpeg/NOTES.md +0 -3
  280. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  281. package/src/generation/COORDINATES.md +0 -54
  282. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  283. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  284. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  285. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  286. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  287. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  288. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  289. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  290. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  291. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  292. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  293. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  294. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  295. package/src/shade/RENDERER_CONTRACT.md +0 -697
  296. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  297. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  298. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  299. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  300. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  301. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  302. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  303. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  304. package/src/shade/renderer/NOTES.md +0 -78
  305. package/src/shade/renderer/PLAN.md +0 -8
  306. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  307. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  308. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  309. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  310. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  311. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  312. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  313. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  314. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  315. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  316. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  317. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  318. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  319. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  320. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  321. package/src/shade/renderer/camera/orbital/README.md +0 -81
  322. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  323. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  324. package/src/shade/renderer/camera/orbital/index.js +0 -9
  325. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  326. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  327. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  328. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  329. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  330. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  331. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  332. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  333. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  334. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  335. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  336. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  337. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  338. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  339. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  340. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  341. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  342. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  343. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
  344. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
  345. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
  346. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
  347. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
  348. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
  349. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
  350. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
  351. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
  352. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
  353. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
  354. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
  355. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  356. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  357. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  358. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  359. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  360. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  361. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  362. package/src/shade/renderer/hiz/NOTES.md +0 -3
  363. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  364. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  365. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  366. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  367. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  368. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  369. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  370. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  371. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  372. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  373. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  374. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  375. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  376. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  377. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  378. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  379. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  380. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  381. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  382. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  383. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  384. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  385. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  386. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  387. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  388. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  389. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  390. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  391. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  392. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  393. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  394. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  395. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  396. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  397. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  398. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  399. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  400. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  401. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  402. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  403. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  404. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  405. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  406. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  407. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  408. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  409. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  410. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  411. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  412. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  413. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  414. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  415. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  416. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  417. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  418. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  419. 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