@woosh/meep-engine 3.60.3 → 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 (514) 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/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +3 -0
  9. package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
  10. package/editor/ecs/component/editors/ecs/Trail3DEditor.js +6 -0
  11. package/package.json +6 -2
  12. package/src/engine/EngineHarness.d.ts +3 -9
  13. package/src/engine/EngineHarness.d.ts.map +1 -1
  14. package/src/engine/EngineHarness.js +6 -8
  15. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  16. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  17. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  18. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  19. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  21. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  22. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  23. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  27. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  28. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  30. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +1 -2
  31. package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts +14 -0
  32. package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts.map +1 -0
  33. package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.js +22 -0
  34. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +19 -3
  35. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
  36. package/src/engine/graphics/ecs/trail3d/Trail3D.js +31 -4
  37. package/src/engine/graphics/ecs/trail3d/advance_trail.js +1 -1
  38. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  39. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  40. package/src/engine/graphics/ecs/water/Water.js +8 -0
  41. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +5 -5
  42. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +1 -1
  43. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +6 -6
  44. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  45. package/src/engine/graphics3/WaterSystem.js +731 -734
  46. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  47. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  48. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  49. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  50. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  51. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  52. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  53. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  54. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  55. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  56. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  57. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  58. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  59. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  60. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  61. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  62. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  63. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  64. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  65. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  66. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  67. package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +10 -0
  68. package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +1 -1
  69. package/src/engine/graphics3/trail/trail_tube_write_geometry.js +13 -1
  70. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  71. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  72. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  73. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  74. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  75. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  76. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +2 -2
  77. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +2 -2
  78. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  79. package/src/shade/playground/probe_clipmap/README.md +1 -0
  80. package/src/shade/playground/probe_clipmap/index.html +5 -0
  81. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  82. package/src/shade/playground/probe_clipmap/main.js +16 -2
  83. package/src/shade/playground/vgeo_scene/README.md +1 -1
  84. package/src/shade/playground/water_refraction/README.md +5 -6
  85. package/src/shade/playground/water_refraction/index.html +1 -1
  86. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  87. package/src/shade/renderer/Renderer.js +7 -5
  88. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +4 -6
  89. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -1
  90. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +34 -36
  91. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +1 -1
  92. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
  93. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +162 -163
  94. package/src/shade/renderer/atmosphere/compute_mie_absorption.d.ts +1 -1
  95. package/src/shade/renderer/atmosphere/compute_mie_absorption.js +1 -1
  96. package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_EARTH.js +1 -1
  97. package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_PARAMETERS_STRUCT.js +1 -1
  98. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +164 -164
  99. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +1 -1
  100. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  101. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  102. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  103. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  104. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  105. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  106. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  107. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  108. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +4 -4
  109. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +4 -4
  110. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
  111. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  112. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
  113. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +2 -2
  114. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.d.ts +1 -1
  115. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.js +1 -1
  116. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts +4 -5
  117. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts.map +1 -1
  118. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.js +6 -7
  119. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  120. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  121. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  122. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  123. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  124. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  125. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  126. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  127. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  128. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +2 -8
  129. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
  130. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  131. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
  132. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +12 -0
  133. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  134. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +22 -0
  135. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +4 -4
  136. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  137. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +50 -13
  138. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +6 -0
  139. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  140. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +7 -0
  141. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts +13 -0
  142. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts.map +1 -0
  143. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.js +13 -0
  144. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -0
  145. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  146. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +20 -0
  147. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts +18 -0
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts.map +1 -0
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.js +42 -0
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +5 -4
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +4 -0
  156. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  157. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +13 -2
  158. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts +52 -0
  159. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts.map +1 -0
  160. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.js +250 -0
  161. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  162. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  163. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  164. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  165. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  166. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  167. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  168. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  169. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  170. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  171. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  172. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  173. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  174. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  175. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  176. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  177. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  178. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  179. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  180. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  181. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  182. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  183. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  184. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  185. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  186. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  187. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  188. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  189. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  190. package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts +39 -0
  191. package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts.map +1 -0
  192. package/src/shade/renderer/light/environment/environment_level_1_blur_plan.js +119 -0
  193. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +15 -7
  194. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  195. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +66 -83
  196. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
  197. package/src/shade/renderer/light/environment/graph_filter_environment_map.js +15 -6
  198. package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts +3 -0
  199. package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts.map +1 -0
  200. package/src/shade/renderer/light/environment/shader_blur_environment_map.js +111 -0
  201. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts +3 -0
  202. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts.map +1 -0
  203. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.js +128 -0
  204. package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
  205. package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +0 -1
  206. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  207. package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
  208. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  209. package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
  210. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  211. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  212. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  213. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -3
  214. package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
  215. package/src/shade/renderer/postprocess/nss/NSS.js +1 -3
  216. package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts +5 -6
  217. package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts.map +1 -1
  218. package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.js +9 -10
  219. package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
  220. package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +48 -49
  221. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
  222. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +12 -16
  223. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +246 -246
  224. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +1 -2
  225. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -1
  226. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +34 -35
  227. package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.d.ts +2 -2
  228. package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.js +2 -2
  229. package/src/shade/renderer/shader/chunk/atmosphere/chunk_compute_extinction.js +1 -1
  230. package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.d.ts +1 -1
  231. package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.js +1 -1
  232. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts +3 -3
  233. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js +3 -3
  234. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts +9 -10
  235. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts.map +1 -1
  236. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.js +9 -10
  237. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts +4 -4
  238. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js +5 -5
  239. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts +1 -2
  240. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts.map +1 -1
  241. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.js +1 -2
  242. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts +14 -1
  243. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts.map +1 -1
  244. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.js +19 -6
  245. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts +10 -1
  246. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts.map +1 -1
  247. package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.js +14 -6
  248. package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.d.ts +1 -1
  249. package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.js +1 -1
  250. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  251. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  252. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts +2 -3
  253. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts.map +1 -1
  254. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.js +7 -8
  255. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.d.ts +1 -1
  256. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.js +12 -12
  257. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +2 -2
  258. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -1
  259. package/src/shade/renderer/shadow/vsm/VSMPageManager.js +3 -4
  260. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  261. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  262. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  263. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  264. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  265. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  266. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  267. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  268. package/src/shade/renderer/water/shader_water.js +22 -13
  269. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  270. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  271. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  272. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  273. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  274. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +0 -19
  275. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
  276. package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +2 -52
  277. package/editor/REWORK_PLAN_2026_08.md +0 -692
  278. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  279. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  280. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  281. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  282. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  283. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  284. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  285. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  286. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  287. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  288. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  289. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  290. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  291. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  292. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  293. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  294. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  295. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  296. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  297. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  298. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  299. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  300. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  301. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  302. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  303. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  304. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  305. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  306. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  307. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  308. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  309. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  310. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  311. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  312. package/src/REVIEW_2026_08_06/generation.md +0 -176
  313. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  314. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  315. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  316. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  317. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  318. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  319. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  320. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  321. package/src/REVIEW_2026_08_06/view.md +0 -667
  322. package/src/REVIEW_2026_08_06.md +0 -610
  323. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  324. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  325. package/src/core/bvh8/NOTES.md +0 -63
  326. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  327. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  328. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  329. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  330. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  331. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  332. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  333. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  334. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  335. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  336. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  337. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  338. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  339. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  340. package/src/engine/REVIEW_2026_07_03.md +0 -211
  341. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  342. package/src/engine/control/first-person/DESIGN.md +0 -658
  343. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  344. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  345. package/src/engine/control/first-person/TODO.md +0 -160
  346. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  347. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  348. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  349. package/src/engine/ecs/ik/PLAN.md +0 -179
  350. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  351. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  352. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  353. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  354. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  355. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  356. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  357. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  358. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  359. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  360. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  361. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  362. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  363. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  364. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  365. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  366. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  367. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  368. package/src/engine/physics/cloth/PLAN.md +0 -3056
  369. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  370. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  371. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  372. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  373. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  374. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  375. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  376. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  377. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  378. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  379. package/src/format/image/avif/DECISIONS.md +0 -545
  380. package/src/format/image/jpeg/NOTES.md +0 -3
  381. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  382. package/src/generation/COORDINATES.md +0 -54
  383. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  384. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  385. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  386. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  387. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  388. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  389. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  390. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  391. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  392. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  393. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  394. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  395. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  396. package/src/shade/RENDERER_CONTRACT.md +0 -697
  397. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  398. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  399. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  400. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  401. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  402. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  403. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  404. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  405. package/src/shade/renderer/NOTES.md +0 -78
  406. package/src/shade/renderer/PLAN.md +0 -8
  407. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  408. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  409. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  410. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  411. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  412. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  413. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  414. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  415. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  416. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  417. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  418. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  419. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  420. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  421. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  422. package/src/shade/renderer/camera/orbital/README.md +0 -81
  423. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  424. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  425. package/src/shade/renderer/camera/orbital/index.js +0 -9
  426. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  427. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  428. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  429. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  430. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  431. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  432. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  433. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  434. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  435. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -483
  436. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  437. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  438. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  439. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  440. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  441. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  442. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  443. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -536
  444. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  445. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4225
  446. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  447. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  448. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  449. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  450. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  451. package/src/shade/renderer/hiz/NOTES.md +0 -3
  452. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  453. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  454. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  455. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  456. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  457. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts +0 -13
  458. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts.map +0 -1
  459. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.js +0 -198
  460. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  461. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  462. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  463. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  464. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -283
  465. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  466. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  467. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  468. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  469. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  470. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -339
  471. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  472. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  473. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  474. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  475. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  476. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  477. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  478. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  479. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  480. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  481. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  482. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  483. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -394
  484. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -160
  485. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  486. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  487. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  488. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  489. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  490. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  491. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  492. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  493. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  494. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -932
  495. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  496. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  497. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  498. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  499. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  500. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  501. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  502. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  503. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  504. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  505. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -4
  506. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  507. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  508. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  509. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  510. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  511. package/src/shade/wgsl/NOTES.md +0 -4
  512. package/src/view/elements/progress/segmented/segment_frame_transform.d.ts +0 -15
  513. package/src/view/elements/progress/segmented/segment_frame_transform.d.ts.map +0 -1
  514. package/src/view/elements/progress/segmented/segment_frame_transform.js +0 -69
@@ -1,432 +0,0 @@
1
- # Acoustic Simulation — Implementation Plan
2
-
3
- > A geometry-driven acoustic **simulation** layer for meep that feeds the **sopra** sound engine.
4
- > Steam-Audio-equivalent in *role* (occlusion, transmission, medium, later reflections / reverb /
5
- > pathing), built ECS-first and almost entirely in JS for **real-time, in-browser** use. The simulation
6
- > computes scalars / IRs against meep geometry; **sopra renders them through WebAudio**. The two never
7
- > blur: this folder produces data, sopra turns data into sound.
8
- >
9
- > Status: **P0–P6 BUILT + GREEN, all render paths wired** (full `engine/sound` suite 360 pass / 0
10
- > regressions). The simulation engine + the occlusion/transmission/medium RENDER seam + the **probe-baked
11
- > reverb RENDER** + the **corner-leakage (pathing) RENDER** are complete and wired into sopra + the ECS
12
- > (`AudioEmitterSystem`). Reverb render uses **option B** — a new acoustic-owned `ProbeReverbRenderer`
13
- > (its own double-buffered ConvolverNode crossfade, IR from the nearest probe's baked decay), leaving
14
- > sopra's static `ReverbEffect` untouched. Pathing render is an **engine-wide `AcousticSimulator.pathing`
15
- > toggle** (off by default, zero cost when off): one single-source Dijkstra from the listener per frame
16
- > (`AcousticPathGraph.computeExitField`) gives every probe its exit point; each occluded source routes a
17
- > second exit-spatialized send (`EventInstance` path branch). No per-source flag — threaded from the
18
- > engine config like `acoustic`. **ECS WIRING HELPER LANDED (2026-06-20):** `configureAcousticSimulation`
19
- > (`simulation/configureAcousticSimulation.js`) — one call from a config builds/reuses the shared
20
- > `AcousticSimulator`, adds `AcousticSimulationSystem` + `AcousticVolumeSystem` (via `addManySystems`),
21
- > and injects the simulator (+ optional `ProbeReverbRenderer`) into the `AudioEmitterSystem`. So the only
22
- > meep-internal integration is done; **Remaining:** the EXTERNAL config call (`makeMirEngineConfig`, in moh
23
- > — out of meep scope) + save/load serialization registration, both gated on the sopra strangler
24
- > migration. Serialization adapters are deliberately NOT built yet — they mirror `AudioEmitter`, which has
25
- > none either (the new sound stack defers binary save integration); the acoustic components carry JSON
26
- > `toJSON`/`fromJSON` + `typeName` for when the migration lands. To wire reverb: connect a sopra bus send →
27
- > `ProbeReverbRenderer.input`, pass `probeReverb` to `configureAcousticSimulation` (or set
28
- > `system.probeReverb`) + `renderer.setProbeField(bakedField)`. To wire pathing: `sim.pathing = true` +
29
- > `sim.setPathGraph(bakeVisibility(probeField, sim.occluderIndex))`.
30
- >
31
- > **What landed per phase:**
32
- > - **P0** — `AcousticMaterial`, `RayHit`, `AcousticOccluderIndex` (per-body local ebvh BLAS, O(1) `setTransform`).
33
- > - **P1** — `OcclusionSolver` (volumetric fibonacci rays + seeded jitter + EMA), `VolumeField`, `AcousticMedium`/`AcousticSolution`/`AcousticSourceState`.
34
- > - **P2** — `AcousticBody` + `AcousticSimulationSystem` (reactive); `AcousticSimulator`; occluder shapes raycast directly via `AbstractShape3D.raycast` (no triangulation).
35
- > - **P3** — `EventInstance.setAcoustic` + node insert (occlusion gain + lowpass + transmission); `AudioEmitter.acoustic`; `AudioEmitterSystem` apply + `LiveEmitterSet` acoustic threading. **First audible occlusion — wired.**
36
- > - **P4** — `AcousticVolume` + `AcousticVolumeSystem` (medium, blended, live-tracked).
37
- > - **P5** — world-AABB broadphase (measurement-driven via `bench/occlusion.bench.spec.js`); temporal amortization proven.
38
- > - **P6** — `AcousticProbe` + `bakeReverb` + `ProbeField` + `bakeProbeField` (geometry-derived reverb, density knob, serialized); `AcousticPathGraph` + `bakeVisibility` + `findAcousticPath` (probe-visibility routing around obstacles).
39
- >
40
- > **Post-P6 cleanup + accel pass (2026-06-20, all committed, `engine/sound` 373 pass):** the occluder
41
- > index now **raycasts shapes directly** via `AbstractShape3D.raycast` (no triangulation;
42
- > `acoustic_geometry_from_shape` deleted) and sits behind a **TLAS** — a dynamic BVH over the bodies'
43
- > world AABBs (P5's deferred TLAS, landed early). `RayHit` carries the world hit **point + normal** (no
44
- > `hit` flag, no `triangleIndex`). Per-source state is **pooled** in a `BinaryElementPool`
45
- > (`Map<EventInstance, id>`, flyweight cursor) instead of a `Map<…, AcousticSourceState>`. The probe
46
- > substrate moved to **`RowFirstTable` + a probe BVH** (nearest via `bvh_query_user_data_nearest_to_point`)
47
- > and **`CSRGraph`** connectivity. `sourceRadius` moved onto `AudioEmitter`/`EventInstance`;
48
- > `pathMaxDistance` was removed (path falloff now derives from the source's authored attenuation curve);
49
- > `AcousticSolution.exit` is a vector. Below, §3.1 / §4 / D5 / P5 describe the v1 triangle-BLAS +
50
- > linear-scan design that this pass superseded — read them as history. The remaining headline work is the
51
- > ray-traced reflection IR (see `REFLECTION_IR_PLAN.md`).
52
- >
53
- > **FOA directional reverb LANDED (2026-06-20):** the first of P6's two premium tiers — the **FOA
54
- > (first-order ambisonic / B-format) directional reverb field**. The bake now captures, per band, the
55
- > energy-weighted **arrival direction** (a 0..1 anisotropy vector) by reciprocity — a ray's reverberant
56
- > energy arrives from its launch direction (`acoustic_trace_energy` accumulates it, `bakeReverbBands`
57
- > normalises it). `ProbeField` widened stride 6→15 to store the three per-band direction vectors (JSON
58
- > round-trips them). Render: a new `render/FoaProbeReverbRenderer` convolves the mono send into a B-format
59
- > set (`foaReverbImpulseResponse` — `W` omni + `X/Y/Z` steered by the baked direction, one-factor W-energy
60
- > normalised) and decodes to stereo by **rotating the decoder, not the soundfield** (two virtual cardioids
61
- > whose look dirs are rotated into world space by the listener orientation — six decode gains/frame, the IR
62
- > re-baked only on probe-cell change). `AudioEmitterSystem` now threads the listener rotation to
63
- > `probeReverb.update()` (the scalar `ProbeReverbRenderer` ignores it). Stereo decode is isolated so a
64
- > binaural/HRTF (SOFA) decoder can replace it later.
65
- >
66
- > **Source directivity LANDED (2026-06-20):** the second of P6's premium tiers. `AcousticDirectivity`
67
- > (`simulation/definition/`) is the Steam-Audio dipole model — `gain = |(1−w) + w·cosθ|^p`
68
- > (`w` = `dipoleWeight` 0=omni/0.5=cardioid/1=dipole, `p` = `dipolePower`), `cosθ` = source forward · the
69
- > source→listener direction. Authored on `AudioEmitter.directivity` (default omni → zero cost; `isOmni`
70
- > short-circuits). The simulator's `apply` computes it per non-omni source (forward = `Vector3.forward`
71
- > rotated by the source's orientation) into `AcousticSolution.directivityGain`, which `EventInstance.setAcoustic`
72
- > multiplies into the direct-path gain. Orientation (shared `Transform.rotation` ref) + the directivity ref
73
- > plumb through `playEvent`/`LiveEmitterSet` exactly like `sourceRadius`/`position`. **P6 premium tiers now
74
- > both done;** the only remaining acoustic work is the external `makeMirEngineConfig` activation + save/load
75
- > serialization (gated on the sopra strangler migration) and the deferred optional refinements (NEE early
76
- > reflections, pathing live-recheck, door variants, binaural/SOFA decode).
77
- >
78
- > **DISTANCE AIR ABSORPTION LANDED (2026-06-20):** "low frequencies travel further." `AcousticMedium.airAbsorption`
79
- > is now **dB/metre**; `VolumeField.integrateAbsorption` line-integrates it over the source→listener path
80
- > (`∫ α ds`; no-region case is closed-form `ambient·distance`, else 8-midpoint march reusing `sample`) into the
81
- > new `AcousticSolution.airLoss[3]` (per-band total dB). The point-sampled `AcousticSolution.medium` was
82
- > REMOVED (superseding §6's `airAbsLP.frequency ← solution.medium.airAbsorption` — air is now path-integrated,
83
- > not point-sampled). Render (`EventInstance.setAcoustic`) anchors the tilt at the LOW band — only
84
- > `airLoss[high] − airLoss[low]` darkens the cutoff (`OPEN·2^(−tilt/6dB-oct)`, floored), so a uniform loss (the
85
- > distance **attenuation curve's** job, a windowed/irradiance falloff — *not* physical) causes no darkening:
86
- > the curve owns loudness, air owns the spectral tilt, and the two compose via separate series nodes. Default
87
- > ambient = a small low-anchored atmosphere (`DEFAULT_AIR_ABSORPTION [0, 0.03, 0.1] dB/m`, tunable). Applied to
88
- > the DIRECT path only (the leak send's longer path is a deferred refinement, like directivity-on-leak).
89
- >
90
- > **CORNER-LEAK REFINEMENTS + DYNAMIC RECHECK + SERIALIZATION LANDED (2026-06-21):** the three corner-leak
91
- > gaps are closed, plus the acoustic binary adapters. (1) **Leak now carries directivity + air.**
92
- > `AcousticSimulator.#applyPath` walks the leaked polyline ONCE (source→…→listener via
93
- > `ProbeFieldPathingSolution.next`) and does three things: integrates air per leg
94
- > (`VolumeField.integrateAbsorption`) into the new `AcousticSolution.pathAirLoss[3]`; folds **directivity toward
95
- > the FIRST hop** (the corner the source radiates into, not the blocked listener — `#directivityGainToward`)
96
- > into `pathGain`; and marks each traversed edge for the recheck. `EventInstance`'s leak branch renders through
97
- > its own 3-band crossover (`#leak3Band`), gained per band by `(1 − transmission[b])` × the `pathAirLoss`
98
- > low-anchored tilt (so a longer routed leak darkens more, and a band-selective wall leaks only its blocked
99
- > bands around the corner — consistent with the direct path's 3-band render).
100
- > (2) **Budgeted dynamic-geometry recheck** (`AcousticSimulator.pathingRecheck` + `recheckBudget`, off by
101
- > default): `ProbeVisibilityRecheck` re-verifies (within budget, FIFO round-robin) the edges leaks traverse
102
- > against live geometry (`probe_edge_visible`, extracted + shared with `bakeVisibility`); a now-blocked edge →
103
- > `EDGE_WEIGHT_BLOCKED` (Float32 max — finite, no topology change, blows the path distance past audibility),
104
- > restored to the inter-probe distance when it re-opens. No structural mutation; the baked graph self-heals.
105
- > (3) **Binary serialization** adapters for `AcousticMaterial`/`AcousticMedium`/`AcousticDirectivity` (value
106
- > types) + `AcousticBody`/`AcousticVolume` (components, delegating; shape omitted like `toJSON`), with
107
- > `populateAcousticSerializationRegistry`. (`AudioEmitter`'s own adapter — needing the full sopra
108
- > `EventDescription` clip-graph chain — is still deferred.) Plus a **two-rooms-and-a-corridor integration
109
- > test** (`two_rooms_corridor.spec.js`) verifying bake (per-band reverb), reachability, leak direction
110
- > (emerges from the corridor, not through the wall), routed-vs-straight attenuation, and a sealed-divider
111
- > disconnection control. **Remaining deferred** (optional/premium): NEE early reflections, binaural/SOFA
112
- > decode, opt-in door variants + re-bake-on-streaming, region-aware air over the leak polyline, the full
113
- > external `makeMirEngineConfig` activation (gated on the sopra strangler migration).
114
-
115
- ---
116
-
117
- ## 0. The one rule: simulation vs. render
118
-
119
- ```
120
- SIMULATION (this folder — engine geometry, JS, no WebAudio) RENDER (sopra — WebAudio)
121
- ─────────────────────────────────────────────────────────── ─────────────────────────
122
- AcousticBody (occluder shapes + material) ─┐
123
- AcousticVolume (medium) ├─► AcousticSolution ─► EventInstance.setAcoustic()
124
- ebvh rays + Ray3 + sphere_fibonacci_point ───┘ (a class) (gain + biquad insert)
125
- ```
126
-
127
- `simulation/core` and `simulation/ecs` import **no WebAudio**. The *only* WebAudio touch is the seam
128
- where `AudioEmitterSystem` hands an `AcousticSolution` to `EventInstance.setAcoustic(...)` (that method
129
- lives in sopra, where the node chain already lives). Consequence: the whole simulation is unit-testable
130
- on real geometry with **zero `MockAudioContext`** — only the one render seam needs it.
131
-
132
- We do **not** put medium on `EventDescription`. An event is a recipe for *a source*; the medium (air,
133
- room) is a property of *the world*. Medium lives on `AcousticVolume` components; a source merely **opts
134
- in** to simulation via one flag (`AudioEmitter.acoustic`). No god-object `AcousticScene` — the occluder
135
- set is just the entities that have an `AcousticBody`, indexed by a system-owned acceleration structure.
136
- This is an ECS engine at the top level; the data model is components.
137
-
138
- ---
139
-
140
- ## 1. Layout
141
-
142
- ```
143
- sound/simulation/
144
- IMPLEMENTATION_PLAN.md
145
- definition/ authored, immutable, serializable (sopra/definition style)
146
- AcousticMaterial.js value class: absorption[3], scattering, transmission[3]
147
- AcousticMaterialSerializationAdapter.js
148
- core/ ECS-agnostic AND WebAudio-agnostic — the testable heart
149
- RayHit.js result class: t / material / bodyHandle / world position + normal
150
- AcousticOccluderIndex.js OccluderBody shapes + world transform behind a TLAS BVH; closestHit / anyHit
151
- AcousticMedium.js value class: airAbsorption (per-band)
152
- AcousticSolution.js result class the render seam consumes: occlusion, transmission[3], medium
153
- AcousticSourceState.js transient per-source accumulation (rolling occlusion, smoothing)
154
- OcclusionSolver.js solve(listener, source, index, rayCount, state, out) — explicit args, out-param
155
- VolumeField.js sample(volumes, x, y, z, out) — out-param, no allocation
156
- sampleDirections.js sphere_fibonacci_point set + per-tick seededRandom rotation
157
- ecs/ thin ECS binding (real-component tested)
158
- AcousticBody.js component: AcousticMaterial + "is occluder"; pairs with Collider + Transform
159
- AcousticBodySerializationAdapter.js
160
- AcousticVolume.js component: AbstractShape3D + AcousticMedium + transition band
161
- AcousticVolumeSerializationAdapter.js
162
- AcousticSimulationSystem.js System: maintain index + volume set (reactive); apply(liveInstances, listener)
163
- probe/ P6 — the baked substrate for reverb + pathing (see D6)
164
- bench/
165
- occlusion.bench.spec.js rays/tick + ms/tick calibration (raycast.bench methodology)
166
- ```
167
-
168
- The render-side additions (`EventInstance.setAcoustic`, the node insert, `AudioEmitter.acoustic`) live in
169
- **sopra**, not here — see §6.
170
-
171
- ---
172
-
173
- ## 2. Reused meep primitives (verified to exist)
174
-
175
- | Primitive | Path | Used for |
176
- |---|---|---|
177
- | `ebvh_geometry_query_nearest_triangle_ray` | `core/bvh2/bvh3/` | closest-hit ray → `[triangleIndex,u,v,t]` |
178
- | `ebvh_build_for_geometry_morton` | `core/bvh2/bvh3/` | build a body's BLAS from its triangle soup |
179
- | `BVH` | `core/bvh2/bvh3/BVH.js` | the per-body tree (`new BVH()`, `release_all`, `allocate_linear`, `root`) |
180
- | `Ray3` (`Float32Array(7)`: o,d,tMax) | `core/geom/3d/ray/Ray3.js` | the ray type; slots into the ebvh query as-is; `applyMatrix4` for local transform |
181
- | `m4_invert` / `m4_inverse_rotation_translation` | `core/geom/3d/mat4/` | per-body world→local inverse |
182
- | `sphere_fibonacci_point` | `core/geom/3d/sphere/` | even source-sphere / hemisphere sampling |
183
- | `v3_orthonormal_matrix_from_normal` + `v3_matrix3_rotate` | `core/geom/vec3/` | hemisphere sampling around a normal (P6) |
184
- | `seededRandom` (Mulberry32) | `core/math/random/` | per-tick ray jitter; **never `Math.random`** |
185
- | `AbstractShape3D.signed_distance_at_point` / `contains_point` | `core/geom/3d/shape/` | `AcousticVolume` boundary blend |
186
- | `AnimationCurve` | `engine/animation/curve/` | distance→cutoff curves (reuse, don't invent) |
187
- | `BinarySerializationRegistry` + adapter pattern | `ecs/storage/binary/` | serialize materials/bodies/volumes |
188
- | SH toolkit (`sh3_rotate_bl`, `sh3_sample_by_direction`, `sh3_add`) | `core/geom/3d/sphere/harmonics/` | ambisonic field (P6) |
189
- | `AssetManager` + `OfflineAudioContext` | `engine/asset/` / browser | baked probe data + offline IR (P6) |
190
-
191
- ---
192
-
193
- ## 3. Encapsulation (the clean core)
194
-
195
- **Two non-negotiables, applied everywhere below:**
196
- - **No opaque config bags.** Tunables (`rayCount`, …) are passed as explicit arguments. Configuration
197
- objects rot — a function that needs a ray count takes a ray count.
198
- - **No magic structs / `@typedef`.** Every result/value shape is a real **class** (`RayHit`,
199
- `AcousticSolution`, `AcousticMedium`, `AcousticSourceState`, `AcousticMaterial`). Hot-path queries are
200
- **allocation-free**: the caller allocates the result and passes it in; the function writes into it.
201
-
202
- ### 3.1 `AcousticOccluderIndex.js` — the (internal) acceleration structure, fully dynamic
203
- Not a public "scene". Owns a list of **bodies**, each a *local-space* triangle BLAS (`BVH` built once via
204
- `ebvh_build_for_geometry_morton`) plus a world transform (and its cached inverse) and one
205
- `AcousticMaterial`. API:
206
-
207
- ```js
208
- addBody(positions, indices, material, matrix?) → handle // BLAS built once from local triangles
209
- setTransform(handle, matrix) // O(1): store matrix + recompute inverse
210
- removeBody(handle)
211
- closestHit(ray /* Ray3 */, out /* RayHit */) → boolean // nearest hit across all bodies, into `out`
212
- anyHit(ray /* Ray3 */) → boolean // early-out
213
- ```
214
-
215
- `closestHit` transforms the world ray into each body's local frame (a module-static `Ray3` scratch +
216
- `applyMatrix4(inverse)`), runs the ebvh query against that body's BLAS bounded by the running best-`t`,
217
- and keeps the nearest; `out` receives `{ t, material, bodyHandle, triangleIndex }`. **Fully dynamic**:
218
- a moving body is just `setTransform` (O(1), no rebuild) — the ECS layer drives it from
219
- `Transform.position.onChanged`. Material is **per body** (a wall has one material); per-triangle
220
- materials are a later refinement, not a v1 need. *Precondition: rigid transforms (no scale), so local
221
- `t` equals world `t`* (documented, not guarded — see house rules). A body-level BVH (TLAS) over the bodies
222
- is the **P5** scaling step; v1 linear-scans the (few) bodies, BLAS does the real work.
223
-
224
- ### 3.2 `OcclusionSolver.js` — the per-source solve (pure, explicit args, out-param)
225
- ```js
226
- solve(listenerPose, sourceX, sourceY, sourceZ, sourceRadius, index, rayCount, state, out) → void
227
- ```
228
- Shoots `rayCount` rays from the listener toward a `sphere_fibonacci_point` set over the source's sphere
229
- (`sourceRadius`), rotated per tick by a `seededRandom` orientation (so accumulation covers the sphere).
230
- Each ray is bounded (`tMax` = listener→sample distance) so far subtrees prune. Blocked-ray fraction →
231
- instantaneous occlusion; blocked rays' materials accumulate the transmission 3-band. Folded into `state`
232
- (`AcousticSourceState`, a rolling window) and smoothed; written into `out` (`AcousticSolution`).
233
- **Pure function of geometry + state**, deterministic for a seed; no ECS, no WebAudio, no allocation.
234
-
235
- ### 3.3 `VolumeField.js` — medium zones (pure, out-param)
236
- ```js
237
- sample(volumes, x, y, z, out /* AcousticMedium */) → void
238
- ```
239
- Each `AcousticVolume` has an `AbstractShape3D` and a `transition` band. Weight =
240
- `smooth(-signed_distance / transition)` clamped to `[0,1]` (1 deep inside, 0 outside, smooth across the
241
- boundary). Normalize weights over overlapping volumes; blend the medium into `out`. A few
242
- `signed_distance_at_point` evals per query — cheap. Queried at the listener every tick; at sources
243
- optionally. **Pure**, allocation-free.
244
-
245
- ### 3.4 result + state classes
246
- `RayHit`, `AcousticSolution`, `AcousticMedium`, `AcousticSourceState`, `AcousticMaterial` are all real
247
- classes with named fields and a `reset()`/`clear()` where they are reused. The system owns a
248
- `Map<EventInstance, AcousticSourceState>`, dropped on `instance.onEnded` — so `EventInstance` stays
249
- ignorant of solver internals.
250
-
251
- ---
252
-
253
- ## 4. The component model (ECS)
254
-
255
- ### `AcousticBody` (occluder) — pairs with `Collider` + `Transform`
256
- Serializable component carrying an `AcousticMaterial` and the "this entity occludes audio" semantic. The
257
- **shape** comes from the entity's existing `Collider`/mesh; `AcousticBody` contributes the acoustic
258
- *properties*. The system triangulates the body's collider shape once into the occluder index (local
259
- space) and drives its transform reactively. Tagging a wall = adding the component; nothing
260
- acoustically-inert occludes unless tagged — that closes the "physics BVH contains everything" problem the
261
- ECS way.
262
-
263
- ### `AcousticVolume` (medium) — pairs with `Transform`
264
- Serializable component: an `AbstractShape3D` (its region), a `transition` distance (boundary blend band),
265
- and an `AcousticMedium` (air-absorption coefficients). Volumes overlap and blend (§3.3). **Medium only —
266
- no reverb here.** (Authored "reverb zones" are the wrong primitive; real reverb is the geometry-traced /
267
- baked output of the probe volume in P6. Until then, sopra's existing reverb stands unchanged.)
268
-
269
- ### `AcousticSimulationSystem` — the binding
270
- `extends System`, `dependencies` covering `AcousticBody`/`AcousticVolume`:
271
- - `link/unlink AcousticBody` → `index.addBody/removeBody` + subscribe `transform.position.onChanged`
272
- (and rotation) → `index.setTransform`. **Reactive, no per-tick refit loop** (mirrors
273
- `SpatialAudioIndex`).
274
- - `link/unlink AcousticVolume` → add/remove from the volume list.
275
- - `apply(liveInstances, listenerPose)` — **called by `AudioEmitterSystem`** between `liveSet.refresh`
276
- and `sopra.update`. Samples the listener medium once, then for each **live 3D** instance opted into
277
- acoustics: `OcclusionSolver.solve(...)` (+ optional per-source `VolumeField.sample`) into a pooled
278
- `AcousticSolution` → `instance.setAcoustic(solution)`. Bounded to ≤ budget (consumes the live set,
279
- never iterates all registered emitters).
280
-
281
- `AudioEmitterSystem` takes an **optional injected** `acousticSim` collaborator (default none → behaviour
282
- identical to today). Feature is off-by-default and testable in isolation.
283
-
284
- ---
285
-
286
- ## 5. Key decisions
287
-
288
- - **D1 — Event carries no medium; one opt-in flag.** `AudioEmitter.acoustic` (default `false`) plumbs to
289
- the instance; `EventInstance` builds the acoustic nodes only when set; `setAcoustic` is a no-op
290
- otherwise. `EventDescription` stays medium-free. (Owner-directed.)
291
- - **D2 — No `AcousticScene`; geometry is `AcousticBody` components, indexed internally.**
292
- - **D3 — `AcousticVolume` is medium-only.** No authored reverb zones. Reverb is the P6 traced/baked
293
- output; sopra's existing reverb stands until then.
294
- - **D4 — `simulation/` imports no WebAudio.** It emits `AcousticSolution`s; sopra renders. The whole
295
- simulation is testable without `MockAudioContext`.
296
- - **D5 — Occluders are fully dynamic.** No static merge. Per-body local BLAS + an O(1) `setTransform`;
297
- the ECS layer refits reactively via `Transform.onChanged` (meep is reactive end-to-end — there is no
298
- static/dynamic flag and no per-tick iteration). A body-level TLAS is the P5 scaling step, not a
299
- correctness requirement.
300
- - **D6 — Using the sim requires a built probe volume; the bake is automatic.** When acoustics is enabled
301
- for a scene, a **probe volume** must be built (it is the substrate for reverb + pathing). The bake is
302
- **fully automatic** save for a few knobs (chiefly **maximum probe density**): it places probes across
303
- the playable space, computes their data (reflection/reverb IR + inter-probe visibility for pathing),
304
- and **serializes** the result. Triggering the bake is the user's responsibility (an explicit call /
305
- editor action — it is not free), but the user authors no probes by hand. Runtime then just loads and
306
- selects/blends baked probe data. (This is why pathing/reverb are P6: they consume the probe volume.)
307
- - **D7 — No opaque config bags; explicit args.** Tunables are parameters, not config objects.
308
- - **D8 — No magic structs; classes + caller-allocated out-params.** Hot-path queries allocate nothing.
309
- - **D9 — Cosmetic-only, so no determinism gate.** Rays use `seededRandom` (reproducible tests, clean
310
- jitter), but there is no lockstep/networking requirement. If acoustics ever become gameplay-affecting
311
- (AI hearing), that is a different project with a different bar.
312
- - **D10 — Bounded, amortized, allocation-free.** Work is capped to the ≤ budget (64) live voices;
313
- `rayCount` is amortized across frames into `AcousticSourceState`; apply is throttleable; results +
314
- scratch are pooled. JS constant factors are accepted; the budget is the contract.
315
-
316
- ---
317
-
318
- ## 6. Render seam (in sopra — the only WebAudio change)
319
-
320
- `EventInstance.#buildOutputChain` (today `voices → instanceGain → attenuationGain → panner → bus`) gains,
321
- **only when the instance is acoustic**, an insert + a parallel transmission branch:
322
-
323
- ```
324
- voices → instanceGain → attenuationGain → airAbsLP → occlusionGain → occlusionLP → panner → bus
325
- └→ transmission 3-band (parallel GainNodes) ─┘
326
- ```
327
-
328
- `EventInstance.setAcoustic(solution)` ramps those `AudioParam`s (smoothing — no zipper):
329
- `occlusionGain ← 1-occlusion`, `occlusionLP.frequency ← f(occlusion)`, the three transmission band gains
330
- ← `(1-occlusion) + occlusion·transmission[band]` (**parallel crossover, not series shelves** — band gains
331
- are independent and linear), `airAbsLP.frequency ← solution.medium.airAbsorption`. All nodes default to
332
- unity / open → an acoustics-off or 2D event is byte-identical to today. (Reverb is untouched here; it is
333
- the P6 probe-driven concern.)
334
-
335
- ---
336
-
337
- ## 7. Phased plan
338
-
339
- Each phase ships behind black-box `*.spec.js` run from `H:/git/moh` root
340
- (`npx jest --config jest.conf.json engine/sound/simulation`). Real objects per house rules; the WebAudio
341
- boundary (only P3+) uses `MockAudioContext`.
342
-
343
- - **P0 — Core occluder substrate (no ECS, no WebAudio). ← building now.** `AcousticMaterial` class +
344
- adapter; `RayHit` class; `AcousticOccluderIndex` (per-body local BLAS via `ebvh_build_for_geometry_morton`,
345
- `Ray3`-based `closestHit`/`anyHit` into a caller `RayHit`, O(1) `setTransform`).
346
- *Exit:* a hand-built box room answers closest-hit + per-body material correctly; a ray through an
347
- opening misses; moving a body via `setTransform` changes the result; `anyHit` early-outs; material
348
- round-trips. Zero ECS/WebAudio.
349
- - **P1 — `OcclusionSolver` + `VolumeField` + state (still no ECS/WebAudio).** Volumetric sampling
350
- (`sphere_fibonacci_point` + `seededRandom` rotation), temporal accumulation in `AcousticSourceState`,
351
- smoothing; `VolumeField` blend with `AcousticMedium`.
352
- *Exit:* occlusion monotonic vs. wall coverage; fully walled → 1 with the wall's material in
353
- transmission; open → 0; frame-stable; deterministic for a seed; volume blend + boundary interpolation
354
- correct. Pure functions on geometry, allocation-free.
355
- - **P2 — ECS binding for occlusion.** `AcousticBody` + adapter; `AcousticSimulationSystem`
356
- (reactive link/unlink + `setTransform`; `apply` loops live 3D instances → solver; owns the per-instance
357
- state map).
358
- *Exit:* real `EntityManager` + real `AcousticBody`/`Transform`/`Collider`; add/remove/move a body
359
- changes the solution; cost bounded to ≤ budget. No WebAudio (assert on returned solutions).
360
- - **P3 — Render seam (first audible occlusion + transmission).** `EventInstance.setAcoustic` + the
361
- no-op-default node insert; `AudioEmitter.acoustic` flag; `AudioEmitterSystem` calls `acousticSim.apply`
362
- between `refresh` and `sopra.update`.
363
- *Exit (MockAudioContext):* occlusion moves the gain + lowpass; transmission bands respond to material;
364
- acoustics-off events identical to today; off-by-default.
365
- - **P4 — `AcousticVolume` (medium).** Component + adapter; `VolumeField` wired so air-absorption follows
366
- the listener's blended volume.
367
- *Exit:* blend weights + boundary interpolation correct; air absorption follows the listener's volume;
368
- no pop crossing a boundary.
369
- - **P5 — Perf hardening + occluder TLAS.** Amortization/throttle knobs; scratch-pool audit (zero
370
- per-frame alloc); a body-level BVH (TLAS) so `closestHit` is O(log bodies); `bench/` calibrating
371
- ms/tick + rays/tick at budget=64.
372
- *Exit:* measured ≤ target ms/tick; no GC churn; many-body scenes scale.
373
- - **P6 — Probe volume + premium tiers (gated).** The automatic probe-volume **bake** (D6: density-knobbed
374
- probe placement over the playable space, per-probe reflection/reverb IR + inter-probe visibility,
375
- serialized via the registry, user-triggered) → **reverb** (probe IR into a double-buffered
376
- `ConvolverNode` on sopra's reverb send bus, crossfaded as the listener crosses probe cells) and
377
- **pathing** (baked probe-visibility graph — **NOT** navmesh; navmesh connectivity ≠ acoustic
378
- connectivity: a window/cliff/ramp carries sound with no navmesh edge). Plus **FOA directional reverb
379
- field** (✓ LANDED 2026-06-20 — per-band baked arrival direction + B-format `FoaProbeReverbRenderer`; see
380
- the dated note up top) and **source directivity** (✓ LANDED 2026-06-20 — `AcousticDirectivity`
381
- monopole/dipole on `AudioEmitter`, solved into `directivityGain`; see the dated note up top).
382
-
383
- ---
384
-
385
- ## 8. Runtime cost (the contract)
386
-
387
- Bounded by the ≤ 64 live voices, **world-size-independent**. Calibration constant `c` = per-ray ebvh
388
- closest-hit (≈1 µs occlusion in JS — measure with `bench/`). Occlusion+transmission =
389
- `liveVoices × rayCount × c`: 8 rays/voice ≈ 0.5 ms, 16 ≈ 1.0 ms; temporal amortization (rayCount spread
390
- over F frames) + throttle (15–20 Hz) cut it 3–4×. Medium (air absorption) + volume blend are closed-form
391
- (< 0.05 ms). Realistic v1 (occlusion + transmission + medium, reverb still sopra's existing) ≈
392
- **0.3–1.0 ms/tick** main-thread, dominated by occlusion ray count. Render adds ~5 native nodes per
393
- acoustic voice on the **separate** audio thread. The lever is `liveVoices × rayCount`; the only spike
394
- (traced reflections, P6) is precomputed into the probe volume and never on the per-frame path.
395
-
396
- ---
397
-
398
- ## 9. Integration & blast radius
399
-
400
- | Touch | Change | Risk |
401
- |---|---|---|
402
- | `AudioEmitterSystem` | optional injected `acousticSim`; one `apply()` call between refresh & tick; read `listenerTransform.rotation` | low |
403
- | `LiveEmitterSet` | +1 accessor to enumerate live instances (bounded) | low |
404
- | `EventInstance` (sopra) | `setAcoustic` + no-op-default node insert in `#buildOutputChain` | **med** (hot chain — unity default, re-run `spatialization.spec`) |
405
- | `AudioEmitter` | `acoustic` opt-in flag (+ later `directivity`) | low |
406
- | `ReverbEffect`/`BusGraph` (sopra) | double-buffered convolver for probe reverb (**P6 only**) | med (reverb path, deferred) |
407
- | **New** | all of `sound/simulation/**` | n/a (self-contained) |
408
-
409
- **Untouched:** `SopraEngine` public API, the clip graph / containers / parameters / `VoiceManager` /
410
- voice-stealing / bus tree / snapshots / ducking, the `SpatialAudioIndex`/`LiveEmitterSet` cull+budget
411
- logic, the legacy `SoundEmitter` path, save-format back-compat. The simulation **consumes** the live set;
412
- it never alters culling, polyphony, or the mixer graph. `EventDescription` carries no medium.
413
-
414
- **Gate:** lands on the `AudioEmitter`/`AudioEmitterSystem` path, not yet in `makeMirEngineConfig`. Nothing
415
- here is observable in-game until the sopra strangler cut-over completes.
416
-
417
- ---
418
-
419
- ## ECS wiring notes (probe field + regions)
420
-
421
- **`AcousticProbeFieldSystem` — single field (v1).** The baked `AcousticProbeField` is an ECS component
422
- (`typeName` + `toJSON`/`fromJSON` + `AcousticProbeFieldSerializationAdapter`); the system links it and wires
423
- it into the simulator (`setProbeField`) for pathing + probe reverb. **Only one field is supported for now:**
424
- the FIRST linked field is wired, any others are silently ignored (no error). TODO — **multiple probe fields**:
425
- e.g. per-region / streamed fields with the active field selected by listener position, or merged into one
426
- graph. Needs a field registry + a selection rule on the simulator (today `setProbeField` holds exactly one).
427
- Until then a scene has exactly one probe field.
428
-
429
- **Region index refit.** `AcousticRegionIndex` is BVH-backed (O(log n) blend queries); regions track
430
- `Transform.position` by reference, so the simulator re-fits ALL region leaves once per frame in `apply()`.
431
- TODO — refit only the regions that actually moved (needs move tracking on `AcousticVolumeSystem`, like the
432
- occluder system's `onChanged` subscription); fine while region counts are small.