@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,547 +0,0 @@
1
- # Meep Procedural Foliage & Tree Generation System — Architecture & Design Document
2
-
3
- ## 1. Executive Summary & Architectural Philosophy
4
-
5
- This document specifies a production-grade, State-of-the-Art (SotA) procedural tree and foliage generation system for **Meep Engine** (`src/generation/foliage/`), comparable in capability to SpeedTree while engineered from the ground up around Meep's data-oriented, zero-allocation primitives and visibility-buffer (`MeshletGeometry` / `StandardShadeMaterial` / `Prefab`) rendering architecture.
6
-
7
- ### Core Design Tenets
8
- 1. **Turn-Key Top Layer, Layered Override API Underneath**:
9
- - **Top Layer (1-line turn-key)**: `generate_tree({ preset: TreePreset.Oak, seed: 42 })` or `place_tree(scene_context, dataset, { preset: "pine", position: [10, 0, -5] })` produces a complete, multi-LOD, wind-rigged, PBR-materialized tree asset (`TreeAsset` / `SceneBundle` / `Prefab`) with zero external asset files required.
10
- - **Mid Layer (Species & Generator Descriptors)**: Declarative `TreeSpeciesConfig`, a branch generator graph (`BranchGeneratorConfig` nodes joined by `BranchSpawnRule` edges, foliage placed by `FoliageSpawnRule`s), `CrownConfig`, `FoliageConfig`, `BarkMaterialConfig`, `FoliageMaterialConfig`, and `TreeWindConfig` with `AnimationCurve` profiles and full JSON serialization.
11
- - **Low Layer (Pure Pipeline Passes)**: Composable, allocation-conscious pure functions operating on `Graph` skeletons, `Transform64` node frames, Hermite spine buffers, `PointHashGrid3` crown fields, and `Geometry` / `Attribute` buffers.
12
- 2. **Zero Duplicate Adjacent Infrastructure**:
13
- - **Coordinate System**: Strictly Meep's right-handed **Y-up** convention (`Vector3.up = (0, 1, 0)`, ground plane `X-Z`).
14
- - **Splines & Profiles**: 3D branch spines are piecewise **Cubic Hermite** segments evaluated via `spline3_hermite` and `spline3_hermite_derivative`. 1D distribution profiles (radius taper modifier, child length scaling, insertion angle, internode density) use Meep's `AnimationCurve` and `Keyframe` (`src/engine/animation/curve/AnimationCurve.js`).
15
- - **Topological Skeleton (`Graph` + `Transform64` + `Attribute`)**: The hierarchical branch graph is stored directly in Meep's directed **`Graph`** (`src/core/graph/v2/Graph.js`, using `EdgeDirectionType.Forward` edges from `src/core/graph/Edge.js`), while each node's 3D position, Rotation-Minimizing Frame (`[R, S, T]`), and cross-sectional radius are stored in **`Transform64`** (`src/engine/ecs/transform/Transform64.js`), and per-node / per-segment attributes are packed into **`Attribute`** buffers (`src/shade/renderer/geometry/Attribute.js`). (`BinaryTopology` is a polygonal surface mesh structure with unordered edge vertices and is not contorted into a directed graph.)
16
- - **Spatial Acceleration**: Crown competition and space colonization use **`PointHashGrid3`** (`src/core/geom/3d/hash-grid/PointHashGrid3.js`) for zero-allocation $O(N)$ neighborhood queries.
17
- - **Math, Noise, & Determinism**: Uses `v3_*`, `quat3_*`, `m4_*`, `aabb3_*`, `tube_frame_transport`, `sdnoise3_array`, `curl_noise_3d`, `seededRandom`, `hash_mix2`, and `hash_mix3`.
18
- - **Real-Time Rendering Native to Shade**: Emits `Geometry` and `MeshletGeometry` (`meshlet_geometry_build_from_geometry`), `StandardShadeMaterial` (with procedural `Sampler2D` $\to$ `ShadeImage` $\to$ `ShadeTexture` albedo/normal/ORM synthesis when custom textures are omitted), skeletal `Skin` bindings (`StandardAttributes.SkinningJoints` + `StandardAttributes.SkinningWeights`), GPU fluid-driven `FoliageWindRig`s (`shader_foliage_wind_apply` sampling `GPUSceneWind`), `SceneBundle`s, and compiled `Prefab`s (`prefab_compile`).
19
-
20
- ---
21
-
22
- ## 2. System Architecture & Pipeline Overview
23
-
24
- ```
25
- ┌─────────────────────────────────────────────────────────────────────────────┐
26
- │ TOP-LEVEL TURN-KEY API │
27
- │ generate_tree(options) / build_tree_prefab(options) / place_tree(...) │
28
- │ Presets: Oak, Pine, Birch, Willow, Maple, Spruce, Palm, Shrub, Fern │
29
- └──────────────────────────────────────┬──────────────────────────────────────┘
30
- │
31
- ▼
32
- ┌─────────────────────────────────────────────────────────────────────────────┐
33
- │ STAGE 1: SKELETON TOPOLOGY & HYBRID GROWTH (Graph + Transform64 + Attribute)│
34
- │ • Parametric Allometric Growth (Weber & Penn levels 0..L_max) │
35
- │ • Crown Envelope SDFs + Space Colonization (PointHashGrid3) │
36
- │ • Tropisms (Gravitropism, Phototropism/Heliotropism, Curl/Simplex Gnarl) │
37
- │ • Dichotomous/Sympodial Trunk Splitting & Apical Dominance │
38
- │ • Da Vinci / Murray Pipe-Model Cross-Section Accumulation (r_p^α = Σ r_i^α)│
39
- │ • Rotation-Minimizing Frames (RMF: Double-Reflection + tube_frame_transport)│
40
- └──────────────────────────────────────┬──────────────────────────────────────┘
41
- │
42
- ┌─────────────────┴─────────────────┐
43
- ▼ ▼
44
- ┌─────────────────────────────────────────┐ ┌─────────────────────────────────┐
45
- │ STAGE 2A: BARK & BRANCH MESH SYNTHESIS │ │ STAGE 2B: PHYLLOTAXIS & FOLIAGE │
46
- │ • Hermite Spine Sampling (spline3_*) │ │ • Phyllotactic Node Placement │
47
- │ • Root Buttressing & Multi-Lobe Flare │ │ (Golden Angle 137.5°, │
48
- │ • Bark Flutes & Knot Swelling │ │ Decussate, Opposite, Whorl) │
49
- │ • Seamless Branch Welding / Collars │ │ • Heliotropic & Gravitropic │
50
- │ (Ray-Cylinder Snap + Normal Slerp) │ │ Petiole Orientation │
51
- │ • Adaptive Ring Collapse (Watertight) │ │ • Folded V-Cards, Cross-Cards, │
52
- │ • Quantized Seamless Bark UVs │ │ Alpha-Tight Hulls, & Fronds │
53
- └────────────────────┬────────────────────┘ └────────────────┬────────────────┘
54
- └─────────────────┬─────────────────────┘
55
- ▼
56
- ┌─────────────────────────────────────────────────────────────────────────────┐
57
- │ STAGE 3: REAL-TIME SHADING, FLUID WIND SKINNING, & MULTI-LOD COMPILATION │
58
- │ • Analytic Canopy AO + Spherized/Puffed Foliage Normals │
59
- │ • Skeletal Joint Extraction (Skin) & Per-Vertex Joint/Weight Binding │
60
- │ • GPU Fluid-Driven Foliage Bone Rig (FoliageWindRig + GPUSceneWind) │
61
- │ • Multi-LOD Chain (LOD0..LOD3) with Area-Compensated Card Decimation │
62
- │ • Procedural PBR Texture & StandardShadeMaterial Synthesis │
63
- │ • MeshletGeometry, SceneBundle, & Prefab Compilation │
64
- └─────────────────────────────────────────────────────────────────────────────┘
65
- ```
66
-
67
- ---
68
-
69
- ## 3. Core Engine Primitives Leveraged (`Graph`, `Transform64`, `Attribute`)
70
-
71
- Rather than contorting `BinaryTopology` (which is a Blender BMesh-style polygonal surface mesh structure with unordered edge endpoints) into a directed graph, the foliage system builds directly on Meep's dedicated graph, transform, and attribute classes:
72
-
73
- 1. **`Graph` & `Edge` (`src/core/graph/v2/Graph.js`, `src/core/graph/Edge.js`)**:
74
- - Represents the directed skeletal topology of the tree (`EdgeDirectionType.Forward` edges `parent_v -> child_v`), connecting both intra-branch Cubic Hermite spine segments and inter-branch lateral attachments into a single rooted arborescence.
75
- 2. **`Transform64` & `t64_look_rotation` (`src/engine/ecs/transform/Transform64.js`, `t64_look_rotation.js`)**:
76
- - Stores each skeleton node's and each foliage attachment's 3D position (`translation` at offset `12`), orthonormal Rotation-Minimizing Frame (`rotation` quaternion at offset `16` mapping local $+X \to \mathbf{R}_v$, $+Y \to \mathbf{S}_v$, $+Z \to \mathbf{T}_v$), and cross-sectional radius (`scale` at offset `20`) in a single contiguous 23-float64 buffer.
77
- 3. **`Attribute` (`src/shade/renderer/geometry/Attribute.js`)**:
78
- - Stores typed-array per-node, per-segment, and per-attachment channels (`Attribute.from(typedArray, itemSize, name)`) with `AttributeSpec` metadata, versioning, hashing, and deep cloning.
79
-
80
- ---
81
-
82
- ## 4. Stage 1: Skeleton Topology & Hybrid Growth Engine
83
-
84
- ### 4.1 `TreeSkeleton` Layout on `Graph`, `Transform64`, and `Attribute`
85
- A `TreeSkeleton` combines a `Graph<number>` (`skeleton.graph`), an array of `Transform64` node frames (`skeleton.node_transforms`), and typed `Attribute` buffers:
86
-
87
- #### Node Transforms & Node `Attribute`s (Skeleton Nodes)
88
- - **`node_transforms[v]: Transform64`**:
89
- - `translation` (`f64[3]` at offset 12): Node 3D position $\mathbf{p}_v = (x, y, z)$ with $+Y$ up.
90
- - `rotation` (`f64[4]` at offset 16): Unit quaternion orienting local $+X$ (`right`) along RMF radial vector $\mathbf{R}_v$, local $+Y$ (`up`) along binormal $\mathbf{S}_v = \mathbf{T}_v \times \mathbf{R}_v$, and local $+Z$ (`forward`) along unit spine tangent $\mathbf{T}_v$.
91
- - `scale` (`f64[3]` at offset 20): Uniform cross-sectional radius $R_v$ at node $v$.
92
- - **Per-Node `Attribute`s**:
93
- - `attr_node_branch_info` (`Int32Array`, `itemSize = 4`): `[branch_id, level, parent_branch_id, in_segment_id]`.
94
- - `attr_node_spine_param` (`Float32Array`, `itemSize = 3`): `[t_normalized, arc_length_s, phase_hash]` where $t \in [0, 1]$ is position along the current branch spine, $s$ is cumulative arc length from branch base, and `phase_hash` $\in [0, 1]$ is the deterministic wind phase.
95
- - `attr_node_joint` (`Uint16Array`, `itemSize = 2`): `[skin_joint_index, parent_skin_joint_index]` for skeletal wind skinning.
96
-
97
- #### Segment `Attribute`s (Cubic Hermite Spine Segments)
98
- Each Cubic Hermite spine segment $e = (v_0 \to v_1)$ adds a directed `EdgeDirectionType.Forward` edge in `skeleton.graph` and stores:
99
- - `attr_segment_endpoints` (`Int32Array`, `itemSize = 2`): `[v0, v1]`.
100
- - `attr_segment_hermite_m0` (`Float32Array`, `itemSize = 3`): Exit tangent vector $\mathbf{m}_0$ at $v_0$ (scaled by chord length $\|\mathbf{p}_{v_1} - \mathbf{p}_{v_0}\|$).
101
- - `attr_segment_hermite_m1` (`Float32Array`, `itemSize = 3`): Entry tangent vector $\mathbf{m}_1$ at $v_1$ (scaled by chord length).
102
- - `attr_segment_metrics` (`Float32Array`, `itemSize = 2`): `[segment_length, parent_attach_t]`.
103
-
104
- Evaluating any point or derivative at local parameter $u \in [0, 1]$ along edge $e$ directly invokes:
105
- - `spline3_hermite(u, p0x, p1x, m0x, m1x)` (for $x, y, z$)
106
- - `spline3_hermite_derivative(u, p0x, p1x, m0x, m1x)` (for $x, y, z$)
107
-
108
- ### 4.2 Hybrid Parametric + Space-Colonization Growth Algorithm
109
- A tree grows by one of two front ends (`TreeGrowth`, `generate_tree`'s `growth`; TWO_FRONT_ENDS_BRIEF_2026_10_28.md):
110
- `TreeGrowth.Graph`, the default, grows the framework below alone (`tree_skeleton_grow_framework`) and draws its species'
111
- shoot prototypes on its carriers (`tree_shoot_prototypes`, `tree_shoot_instances`): the wood any LOD draws grafted
112
- onto each carrier, every leaf and twig the prototype's cuts at the tree's error, for most trees;
113
- `TreeGrowth.Botanical` grows that framework and then every shoot system of `species.shoot_rules` on it
114
- (`tree_skeleton_grow`, `tree_skeleton_grow_shoots`). The botanical tree's framework is the graph tree, node for node,
115
- thickened by the shoots it carries. Everything after the skeleton draws both alike. A species is the same for both but
116
- where the botanical front end grows its framework from shoots: the pine, grown from its seed, has its own graph framework
117
- (`make_tree_species_preset`'s `growth`).
118
-
119
- Branches are grown breadth-first from the trunk (`species.branches[0]`). Every `species.branch_rules` edge
120
- `source -> target` (always `source < target`, so the graph is acyclic) spawns branches of generator `target` along
121
- each branch of generator `source`; one generator may spawn several kinds of children (boughs, roots, stubs, sprouts,
122
- inter-whorl branches) and several generators may spawn the same kind (fan-in). Branching depth $l$ counts lateral
123
- hops from the trunk; split forks keep their parent's depth and generator.
124
- 1. **Crown Envelope & Space Colonization Field**:
125
- - The crown volume is defined by a configurable `CrownEnvelopeType` (`Conical`, `Spherical`, `Hemispherical`, `Cylindrical`, `TaperedCylindrical`, `Flame`, `InverseConical`, `TendFlame`, `Weeping`, or custom `AnimationCurve` profile) centered at $(0, H_{\text{crown}}, 0)$.
126
- - When `space_colonization_weight > 0`, $N_{\text{attract}}$ attraction points are sampled deterministically inside the crown envelope using `seededRandom` and indexed in a `PointHashGrid3` with cell size equal to the attraction radius $d_i$.
127
- 2. **Branch Spawn & Phyllotactic Budding**:
128
- - Along each parent branch, each outgoing rule spawns its children inside `[attach_min, attach_max]` according to the rule's `PhyllotaxisMode` (`SpiralGolden` $137.507764^\circ$, `AlternateDistichous` $180^\circ$, `OppositeDecussate` $180^\circ + 90^\circ$ flip, `Opposite` $180^\circ$, `Whorled` $360^\circ / M$, `FlareLobes` on the crests of the parent's basal buttress lobes).
129
- - Child branch length $L_l(t_p)$ is modulated by the rule's `length_profile: AnimationCurve` and, for rules with `crown_envelope`, the crown envelope $S_{\text{env}}(h_{\text{norm}})$. Children of a rule without `crown_envelope` (roots, trunk sprouts) are neither shrunk by the envelope nor kept inside it.
130
- - Self-pruning: below a crown rule's `attach_min` the rule once grew children too, at the same nodes continued down the stem; they died in the crown's shade. Each keeps `(1 - self_pruning) - age` of its length as a dead stub (age 0 just below the living children, 1 at the stem base; size at death `(1 - age)` of today's), and once that no longer clears the bark it is grown over and becomes a bark scar (knot).
131
- - Generators with `root` grow structural surface roots: they descend onto the ground plane $y = 0$ and creep along it, add no pipe-model area to their stem, and never receive a wind joint.
132
- - Initial child heading $\mathbf{T}_c(0)$ diverges from parent tangent $\mathbf{T}_p(t_p)$ by insertion angle $\alpha_{\text{insert}}(t_p)$ around the azimuth $\phi_k$ in the parent's RMF plane $(\mathbf{R}_p, \mathbf{S}_p)$.
133
- - The child's initial RMF normal $\mathbf{R}_c(0)$ is aligned with the adaxial (upper crotch) projection of $\mathbf{T}_p$:
134
- $$\mathbf{R}_c(0) = \text{normalize}\big(\mathbf{T}_p - (\mathbf{T}_p \cdot \mathbf{T}_c(0))\mathbf{T}_c(0)\big)$$
135
- guaranteeing that $\theta = 0$ on the child's cross-section always lies at the top of the branch collar.
136
- - **Dorsiventral parents** (`BranchGeneratorConfig.plagiotropism` $p > 0$, lateral generators only):
137
- - **The plane.** A plagiotropic parent bears its buds in the plane of its tangent $\mathbf{T}_p$ and the horizontal
138
- $\mathbf{H} = \mathbf{T}_p \times \mathbf{e}_y$ across it. The plane's normal is
139
- $\mathbf{N} = \mathbf{H} \times \mathbf{T}_p$, which points up.
140
- - **Ventral knockout.** No bud is emitted into the downward cone of half-angle $p\,\pi/2$.
141
- - A bud whose own heading points into the cone does not break. That test is about where the bud sits on the
142
- bough.
143
- - Nor may fanning, or a turn for clearance, carry a bud's emitted heading into the cone. Each such candidate is
144
- rejected, and a bud with none left does not break.
145
- - Contact projection of a child's first segment can still deflect it in afterwards.
146
- - **Fanning.** The surviving buds' radial direction loses $p\,|\mathbf{H}|$ of its component along $\mathbf{N}$,
147
- fanning them into the plane. A vertical parent has no such plane, and its children are not fanned.
148
- - **Which species.** Plagiotropism follows the species' architectural model (Hallé, Oldeman & Tomlinson's architectural models, as listed by Pfisterer (2000, *Mitt. Biol. Bundesanst.* 370) and Millet, Bouchard & Édelin (1999, *Écoscience* 6: 187–203)):
149
- - **Massart's model** (*Picea*, *Abies*): tiers of plagiotropic branches. The spruce preset sets it.
150
- - **Rauh's model** (*Pinus*, *Acer*, *Quercus*, *Betula*): branches orthotropic and built like the trunk. Those
151
- presets set none.
152
- - **Troll's model** (*Fagus*, *Tilia*, *Ulmus*): every axis plagiotropic. Not among the presets.
153
- - The knockout is the least sourced part: laterals of a plagiotropic branch lie in its horizontal plane, but no
154
- *Picea*-specific source was found for the fate of its ventral buds. On spruce it barely acts, since the buds are
155
- already distichous.
156
- - **Replaces.** This replaces an undocumented emission rule keyed on the *child's* gravitropism, which biased every
157
- lateral's buds upward and off its underside.
158
- - **Pads:** its effect was small (oak 0.750 with it, 0.789 without).
159
- - **Headings:** its effect was not. Without it, oak has 3.8% of twigs more than 30° below the horizontal against
160
- 1.4% (mean heading y 0.327 against 0.398), and birch 1.2% against 0.6%.
161
- - **No basis:** Rauh-model branches are orthotropic and branch radially, and the positional bias reported for
162
- some of them is slight hypotony (lower-side laterals favoured; Millet et al. 1999), not an upward one.
163
- 3. **Stepped Spine Integration with Tropisms, Gnarl, & Splits**:
164
- - As segment $k \to k+1$ advances by $\Delta s = L_l / N_{\text{seg}}$:
165
- - **Intrinsic curvature**: Pitch rotation around $\mathbf{S}_k$ by $\Delta \theta_{\text{curve}}(t_k)$ and helical twist around $\mathbf{T}_k$.
166
- - **Gravitropism (Y-up)**: Bending toward $-\mathbf{e}_y = (0, -1, 0)$ (or $+\mathbf{e}_y$ for negative gravitropism), weighted by mechanical tip compliance $\text{lerp}(0.2, 1.0, t^\gamma)$.
167
- - **Phototropism**: Steering toward $\text{normalize}(\alpha_{\text{sky}}\mathbf{e}_y + (1-\alpha_{\text{sky}})\mathbf{d}_{\text{radial}})$ to seek sky light and escape interior crown self-shading.
168
- - **Curl / Simplex Gnarl**: 3D divergence-free `curl_noise_3d` (or `sdnoise3_array`) projected perpendicular to $\mathbf{T}_k$.
169
- - **Plagiotropism**: a lateral shoot with `plagiotropism` $p$ is steered by $-p\,T_{k,y}\,\mathbf{e}_y$ towards the horizontal. The apical `tip_upcurl` still turns its tip up, so conifer boughs keep their upturned ends.
170
- - **Straightness**: `straightness` $\lambda$ adds $\lambda(\mathbf{T}_0 - \mathbf{T}_k)$, a pull back towards the heading the branch was given, so strong gnarl does not carry a branch out of its sector. $\mathbf{T}_0$ is the bud's heading. For the fork that continues a split it becomes the heading the split deflected it to, as the other forks aim along their own. It resists every deviation from that heading, droop included.
171
- - **Space Colonization Pull**: Queries `PointHashGrid3.forEachNear` around $\mathbf{p}_k$, pulling $\mathbf{T}_{k+1}$ toward unclaimed attraction points within radius $d_i$ and marking attraction points within kill radius $d_k$ as consumed.
172
- - **Sympodial / Dichotomous Forking (`split_probability`, `split_angle`, `split_Spread`)**: At segment $k$, a stem can bifurcate or trifurcate into $M \in \{2, 3\}$ daughter branches that diverge symmetrically in azimuth and pitch.
173
- - **RMF Transport**: Advances $(\mathbf{R}_k, \mathbf{S}_k) \to (\mathbf{R}_{k+1}, \mathbf{S}_{k+1})$ via Wang et al. (2008) **Double Reflection** with fallback to `tube_frame_transport`.
174
- 4. **Bottom-Up Pipe-Model Cross-Section Accumulation**:
175
- - After all branch levels are generated in `skeleton.graph`, a bottom-up post-order pass accumulates cross-sectional area using the Da Vinci / Murray Pipe Model law:
176
- $$R_{\text{pipe}}(v) = \left( R_{\text{tip}}^\alpha + \sum_{e=(v \to u)} R_{\text{pipe}}(u)^\alpha \right)^{1/\alpha}, \quad \alpha \in [2.0, 2.8]$$
177
- - The final radius at node $v$ blends the artist-controlled parametric taper curve (`radius_profile: AnimationCurve`) with the physical pipe model via `pipe_model_weight` $\in [0, 1]$.
178
- 5. **Annual Shoot Layer** (`skeleton/tree_skeleton_grow_shoots.js`, `skeleton/shoot_systems_simulate.js`; see
179
- `CROWN_FILLING_BRIEF_2026_10_26.md` and `SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md`):
180
- - **Input.** Each `species.shoot_rules` entry (`ShootSystemRule`, its bud zones `ShootBudZone`) grows the
181
- shoot system on every living branch of its `source` generator, after the pipe-model pass. A lateral is a branch
182
- of the rule's `target` for its mother's order (short shoots `short_target`), one level below its carrier.
183
- - **Time.** The framework is as old as it took to grow at `shoot_growth.leader_growth`; each carrier carries its
184
- annual units over its length. The tree grows `max` of that and `shoot_growth.age` seasons. A carrier that
185
- stopped growing before then grows on from its tip as an axis of its own order and generator, written onto it, so a
186
- tree grown from a seed leader (the pine) is one stem from the ground up. The stem's units are
187
- `shoot_growth.leader_unit(height)` (Kellomäki & Kurttio 1991, Eq. 6), not its unit before.
188
- - **Each season, tree-wide**, under a voxel light field (`ShootLightField`: leaf area, Beer-Lambert from a standard
189
- overcast sky) rebuilt round the crown as it grows:
190
- - **Vigour.** The light each axis's tip receives flows down to its carrier and back up, shared at each node with
191
- apical control `shoot_growth.apical_control` (Borchert-Honda, as Palubicki et al. 2009); a new unit's mean
192
- length is scaled by its axis's vigour relative to the most vigorous. At 0.5 every vigour is 1.
193
- - **Extension.** Every living axis grows a terminal unit. Its course turns by phototropism (towards where the
194
- light field grows brighter), gravitropism, and a lateral's plagiotropism and straightness; zigzag kinks the unit
195
- off the course, not the course. Short shoots survive as their light allows.
196
- - **Buds.** Last season's units burst their zones' buds (and this season's, sylleptically). A bud breaks where
197
- there is room, else turns by the golden angle round its node.
198
- - **Shedding.** A new shoot survives at `net_yield(Q, gross) / gross`, `gross` the yield of the unit it grew on:
199
- in full light every shoot is kept, and only shade sheds. A shed axis takes everything on it.
200
- - **Wood.** The wood thickens with what it carries (`ShootGirth`): Table 7 (`d = 0.27 + 0.13 age + 0.02 l` cm)
201
- for a unit of its age, the pipe model at the species' exponent, and 1 / 0.82 of a lateral where it joins.
202
- - **Avoidance** (`ShootFrameworkHash`, `ShootWoodHash`). No unit grows into the ground, through framework wood, or
203
- through older shoot wood it does not join: a mother either side of where it grew and over its crotch, a
204
- grandmother at its mother's base, a carrier's extension and the carrier's laterals by its tip, and siblings'
205
- first units within the collar they share (out of the mother's wood, at least half way). A shoot whose line
206
- thicker (or as thick and older) wood has grown into dies; so does a lateral whose tip the wood its mother grew
207
- since has closed over, and a carrier its parent has grown over, with its twigs. Graph branches buried by the
208
- thickening are dead.
209
- - **Leaves pay.** A lateral of a generator that bears no leaves (no foliage rule) does not grow.
210
- - **The record.** Every carrier and twig records where each of its annual units starts
211
- (`TreeSkeleton.branch_unit_start_t`), for the foliage pass (§6.1).
212
-
213
- ---
214
-
215
- ## 5. Stage 2A: Bark & Branch Mesh Synthesis
216
-
217
- ### 5.1 Root Flare, Buttressing, & Fluted Cross-Sections
218
- At longitudinal spline parameter $t \in [0, 1]$ (arc-length $s$) and cross-sectional azimuth $\theta \in [0, 2\pi)$:
219
- $$R(t, \theta) = R_{\text{node}}(t) \cdot \Big[ 1 + A_{\text{flare}}(1 - \text{smoothstep}(0, t_{\text{flare}}, t))^{p_{\text{flare}}} \Psi_{\text{lobes}}(\theta, t) + A_{\text{flute}} \sin(k_{\text{flute}}\theta + \omega_{\text{twist}} s) \Big]$$
220
- where $\Psi_{\text{lobes}}(\theta, t) = \sum_{m=1}^{N_{\text{lobes}}} w_m \max(0, \cos(\theta - \phi_m - \omega_{\text{twist}} t))^{s_{\text{lobe}}}$ creates realistic root buttresses at the base of the trunk ($l = 0$).
221
-
222
- ### 5.2 Seamless Branch Welding (Collar Blending)
223
- For any lateral branch ($l \ge 1$) attached to a parent branch of radius $R_p$ at point $\mathbf{x}_p$ with parent axis $\mathbf{T}_p$:
224
- 1. **Collar Ring Projection onto Parent Cylinder**:
225
- - For the first $K_{\text{weld}}$ rings ($u = k / K_{\text{weld}} \in [0, 1]$), the base collar radius is flared by `collar_spread_upper` (crotch side $\theta \approx 0$) and `collar_spread_lower` (underside $\theta \approx \pi$).
226
- - Each base vertex ($u = 0$) is projected backward along $-\mathbf{T}_{c,0}$ onto the parent branch cylinder surface of radius $R_p$ around axis $\mathbf{T}_p$ (clamped cleanly to $\le 0.92 R_p$ radial offset so wide child branches never miss the parent cylinder).
227
- - Intermediate collar rings ($0 < u < 1$) blend via Hermite weight $(1 - u)^2$ between the parent-conforming collar curve and the cylindrical child branch tube.
228
- 2. **Normal Blending ($C^1$ Shading Continuity)**:
229
- - At $u = 0$, the vertex normal is set to the parent cylinder's outward radial normal $\mathbf{n}_{\text{parent}}$ at the contact point.
230
- - Across $u \in [0, 1]$, the vertex normal is interpolated via spherical/normalized linear blend between $\mathbf{n}_{\text{parent}}$ and the child's analytic tapered tube normal $\mathbf{n}_{\text{child}}$.
231
-
232
- ### 5.3 Watertight Tessellation at a Geometric Error
233
- - Each LOD draws the bark to its error $\epsilon$ (`TreeLODConfig.error`, m): a branch is drawn while its wood is at
234
- least $\epsilon$ thick and its parent is drawn, and its spine ends where it thins to $\epsilon$.
235
- - Rings stand where the surface needs them: candidates at every node, every segment's middle and every collar and knot
236
- centre are measured all round (spine, radius, lobes, flutes, ovalization, collar bosses, knots, the weld's flare; bark
237
- relief is the normal map's), and Douglas-Peucker (`polyline_simplify_by_error`) keeps those the rings either side
238
- would miss by more than $\epsilon / 2$.
239
- - Each kept ring has the fewest sides $M_i$ whose polygon misses none of its measured points, nor its shape at any
240
- chord's middle, by more than $\epsilon / 2$; for round wood of radius $R$ that is $R (1 - \cos(\pi / M_i)) \le \epsilon / 2$.
241
- - Whenever $M_{i+1} < M_i$ between consecutive rings $i$ and $i+1$, a **manifold zippering strip** advances around $\theta \in [0, 2\pi]$ on whichever ring has the smaller next normalized angle $j / M$, emitting $M_i + M_{i+1}$ triangles with **zero T-junctions** and preserving UV seam duplication at $\theta = 0$ and $\theta = 2\pi$.
242
- - Branch tips are closed with either a tapered apex fan (when $R_{\text{tip}} \le \epsilon$) or a rounded cap.
243
-
244
- ### 5.4 Quantized Seamless Bark UVs
245
- - At each branch base, circumferential tile count is quantized to an integer:
246
- $$K_{\text{wrap}} = \max\!\left(1, \, \text{round}(2\pi R_0 \cdot \rho_{\text{tex}})\right)$$
247
- - Vertex $j \in \{0, \dots, M_i\}$ receives $U_{i,j} = K_{\text{wrap}} \cdot (j / M_i) + \tau_{\text{twist}} s_i$, ensuring $U_{i,M_i} - U_{i,0} = K_{\text{wrap}} \in \mathbb{Z}$ (zero vertical texture seam) and $V_i = s_i \cdot \rho_{\text{tex}}$.
248
-
249
- ---
250
-
251
- ## 6. Stage 2B: Botanical Phyllotaxis & Foliage Synthesis
252
-
253
- ### 6.1 Phyllotactic Attachment Generator
254
- Generates `FoliageAttachment` transforms along carrier branches of levels $l \in [l_{\text{min}}, L_{\max}]$:
255
- - Supports `SpiralGolden` ($137.507764^\circ$), `AlternateDistichous` ($180^\circ$), `Tristichous` ($120^\circ$), `Opposite` ($2\times 180^\circ$), `OppositeDecussate` ($2\times 180^\circ$ with $90^\circ$ alternation), and `Whorled` ($M$ organs per node), with nodes spaced evenly over the carrier's leafy span.
256
- - **Card density is derived, not authored** (`skeleton/foliage_card_density.js`):
257
- - **The sleeve.** A card leaves the shoot at insertion angle $\alpha$ and reaches $L$, so the shoot wears a foliage
258
- sleeve of radius $R = L \sin\alpha$.
259
- - **One leaf per line of sight.** The carrier holds just enough leaf that a line of sight through that sleeve meets
260
- one leaf on average. By Cauchy's formula the sleeve's mean projected area is a quarter of its surface ($2\pi R$ per
261
- metre), and a flat leaf's is half its area. So the leaf area is $\pi R$ per metre, and
262
- $$n = \frac{\pi \sin\alpha \,(1 - v_a)}{S \, s \, \phi \, P}\ \text{cards per metre}.$$
263
- The terms:
264
- - $S$ is the side of the species' square card, the size its tile draws its leaf at (`foliage_tile_layout`, §6.3),
265
- and $s$ the card scale on that shoot.
266
- - $\phi$ is the atlas's measured leaf coverage (`FoliageAtlasCutout.coverage`).
267
- - $P$ is the number of planes a card stands up (2 for `CrossCard`, 3 for `TriStarCluster`).
268
- - $v_a$ is where the tile's leaf attaches (`FoliageTileLayout.anchor_v`): the card's length spans the tile from
269
- there.
270
- - **Leafy span.** It starts at the rule's `attach_min`, honoured up to 0.92 (`foliage_leafy_span_start`), for the
271
- cards and the sail alike.
272
- - **Rounding.** The expected count is rounded with a golden-ratio dither per (branch, rule), so it is exact on
273
- average.
274
- - **Annual units replace the rule.** A branch that records its annual units (`TreeSkeleton.branch_unit_start_t`,
275
- written by the annual shoot layer, §4.2) carries, on each unit, its leaves (`leaves_per_unit + leaves_per_metre L`,
276
- times `leaf_survival` at the unit's age; a short shoot `leaves_per_short_shoot` at its tip), in place of the
277
- density rule (`foliage_unit_card_spans`).
278
- - **A card a leaf.** Each leaf is a card at its own node along the unit, leaving the shoot at the rule's insertion
279
- angle and turned by its phyllotaxis. A needle-shoot card draws a stretch of shoot with its needles instead, as
280
- many as the shoot bears there, and lies along it.
281
- - **Maturity.** Each card draws its own maturity from its branch.
282
- - **Wind.** The joint mechanics load the same card on that unit.
283
- - **Wind.** The joint mechanics take the same $\pi R$ per metre as the foliage's sail. The wind rig and the cards
284
- agree within 0–3.5% on every preset (size variance and length floors).
285
- - **Abscission and wilt** (`skeleton/foliage_senescence.js`):
286
- - **Each tile's onset.** The pigment model ages each atlas tile at its own pace: a tile of maturity $\mu$ is at stage
287
- $\sigma_k = \sigma(0.80 + 0.36|\mu - 0.35|) + 0.12\sigma^2$ (`foliage_variant_senescence`), and retains
288
- $1 - \sigma_k(1.36 - \text{shielding})$ of its chlorophyll. Its exposed lamina is bare once $\sigma_k = 1/1.36$.
289
- `foliage_variant_abscission_onset` solves that for the tree's senescence, $\sigma_0(\mu)$: 0.66 for mature tiles,
290
- 0.73 for juvenile ones and 0.82 at $\mu = 0.35$. No leaf falls or dries before its own tile's onset.
291
- - **Each card's threshold.** After that, exposure orders the fall. A card's threshold
292
- $\theta \in [\sigma_0(\mu), 1]$ comes from the mean of its sun exposure ($0.62\,\rho_{\text{shell}} + 0.38\,h_{\text{norm}}$)
293
- and its position along its shoot. Outer and apical leaves fall first, and the crown is bare at $\sigma = 1$.
294
- - **Dryness.** Between its onset and its fall the card dries: $d = (\sigma - \sigma_0)/(\theta - \sigma_0)$.
295
- - The mesh builder takes a folding card (`FoldedVCard`, `RibbedFrond`, `CutoutHull`) towards a leaf with no turgor:
296
- the fold closes towards $\pi/2$, the arch goes to 0, and the droop goes to 1. `CrossCard` and `TriStarCluster`
297
- have no fold and do not wilt.
298
- - A card just before its fall is nearly shut, a valid sliver.
299
- - **Wind.** The joint mechanics shed the same leaves from their sail. They judge the expected leaf (no jitter) at each
300
- segment's middle.
301
- - **Heliotropic & Gravitropic Orientation**:
302
- - Reorients each leaf/frond basis $(\mathbf{F}, \mathbf{U}, \mathbf{W})$ so its adaxial normal $\mathbf{U}$ tilts toward the sky + canopy-outward light vector (`phototropism` $\in [0, 1]$) while its forward tip $\mathbf{F}$ droops under `gravitropism` $\in [-1, 1]$, with seeded angular jitter to prevent specular aliasing.
303
-
304
- ### 6.2 Foliage Topologies
305
- Supports 5 production real-time foliage card/mesh archetypes:
306
- 1. **`FoldedVCard`**: $2 \times 2$ or $2 \times 3$ grid with transverse V-fold angle $\beta_{\text{fold}}$, longitudinal midrib arch $h_{\text{arch}} \sin(\pi v)$, and tip camber $-h_{\text{camber}} v^2$. Never appears razor-flat at grazing view angles.
307
- 2. **`CrossCard` (needle shoot)**: Two orthogonal intersecting V-cards rotated by $90^\circ$ around the shoot axis $\mathbf{F}$; each plane draws the needles in its sector round the shoot (§6.3).
308
- 3. **`TriStarCluster` (needle shoot)**: Three cards arranged at $60^\circ$ star angles, each drawing its sector's needles.
309
- 4. **`RibbedFrond` (Palms, Ferns, Cycads, Weeping Boughs)**: Multi-segment curved Cubic Hermite frond spine with RMF transport, longitudinal V-fold variation, and width profile $W(t) = W_{\max} \sin(\pi t^{p_w})$.
310
- 5. **`CutoutHull` (Fitted Alpha-Bound Card, the broadleaves' leaf)**: the convex hull of everything its atlas tile
311
- draws, reduced to 6 vertices and fanned around a midrib vertex.
312
- - **Shape.** Each half turns about the midrib by `fold_angle`, and the card arches and droops along its length like
313
- a frond spine.
314
- - **Fitting.** `make_foliage_material` fits the hulls while it synthesizes the atlas (`FoliageAtlasCutout`):
315
- - Each covered texel row contributes the outer corners of its first and last texel that has any alpha.
316
- - `convex_hull_monotone_2d` hulls those points.
317
- - `convex_hull_fixed_count_2d_relaxation` reduces the hull to 6 vertices inside the tile, inset by half a texel
318
- (its `bounds`), so no corner reaches the atlas neighbour.
319
- - When no edge can be removed without leaving the tile, the unbounded fit is clipped to the tile
320
- (`polygon2_clip_axis_halfplane`) and relaxed again.
321
- - If that stalls too, the hull is the silhouette's bounding box as a hexagon. It is looser, but it holds every drawn
322
- texel. Clamping the unbounded fit's corners instead would cut the leaf.
323
- - **Result.** A willow's lanceolate leaf is cut far tighter than a hazel's broad one (`foliage_atlas_cutout.spec`).
324
- - **Custom material.** With a caller's own material, the cards cover whole tiles.
325
-
326
- ### 6.3 Leaf Architecture and the Atlas Tile
327
- Every tile draws the species' own leaf at its true size (`material/leaf_geometry.js`, `material/foliage_tile.js`;
328
- `LEAF_ARCHITECTURE_BRIEF_2026_10_26.md`):
329
- - **The leaf, as floras describe it** (`LeafArchitecture`, in the terms of Ellis et al. 2009, *Manual of Leaf
330
- Architecture*): blade length and length/width ratio, where it is widest, apex and base angles and shapes, pinnate or
331
- palmate lobes with their sinus depth, teeth a centimetre and their depth and order, secondary veins and their
332
- angle, petiole length; a compound leaf's leaflets and rachis. Each preset cites its flora.
333
- - **The outline** is a monotone cubic Hermite envelope through the base, the base angle's point a quarter of the way up,
334
- the widest point, the apex angle's point and the apex; rounded ends are arcs, acuminate ones concave. A pinnately
335
- lobed blade is a body out to the sinus floors plus a rounded lobe along each secondary vein; a palmate one is a lobe
336
- per primary vein over a body; teeth are offset along the outline's normal. All contours wind the same way, so
337
- `polygon2_rasterize_coverage` fills their union by the nonzero rule with exact coverage across each row.
338
- - **The tile** draws the mature leaf filling it within a 2% margin, attached at the bottom middle; younger leaves are
339
- smaller. The card is that tile at that scale: its size is the leaf's. The resolution draws the leaf's finest feature
340
- (a tooth, a sinus) four texels across and its stems two, so they survive the alpha test.
341
- - **Needle shoots** draw a stretch of shoot as long as a needle, its needles shared among the card's planes, each
342
- plane showing those in its sector round the shoot, foreshortened by their azimuth.
343
-
344
- ---
345
-
346
- ## 7. Stage 3: Shading, Wind Rigging, Materials, & Multi-LODs
347
-
348
- ### 7.1 Canopy Ambient Occlusion & Spherized Foliage Normals
349
- - **Per-Vertex Canopy AO (`StandardAttributes.Color`)**:
350
- - Combines macro crown ellipsoid depth $AO_{\text{crown}}(\mathbf{v}) \in [AO_{\text{core}}, 1.0]$ with local hierarchy depth $AO_{\text{local}}(v) \in [0.7, 1.0]$ (darkening inner branch crotches and petiole bases while brightening outer sun-exposed tips).
351
- - Multiplied with optional per-cluster hue/value jitter in `StandardAttributes.Color` (`vec3<f32>`), which `StandardShadeMaterial` automatically multiplies with `texture_albedo` in the G-buffer pass.
352
- - **Tint headroom.** Vertex colours are encoded as `unorm8`, so on their own they can only darken. Each card's tint
353
- (`FoliageAttachmentSet.tints`) is free to exceed 1. The builder writes `tint / tint_scale`, where `tint_scale` is
354
- the largest tint channel, and the foliage material's `diffuse_color` (the shader's `albedo_color`) carries
355
- `tint_scale` back. The product is exactly `albedo · tint · AO`. Across the presets `tint_scale` is about 1.1, and
356
- about half of all tint channels exceed 1.
357
- - **Spherized / Puffed Foliage Normals (`StandardAttributes.Normal`)**:
358
- - Blends the geometric card normal $\mathbf{n}_{\text{card}}$ with the canopy-outward normal $\text{normalize}(\mathbf{v} - \mathbf{C}_{\text{crown}})$ by `normal_puffiness` $\in [0, 0.85]$ before running `geometry.ensureTangents()`, giving leaf clusters soft volumetric canopy lighting.
359
-
360
- ### 7.2 Real-Time Wind Encoding & GPU Fluid-Driven Foliage Bone Animation
361
- Meep's visibility-buffer renderer (`Shade`) deforms `MeshletGeometry` on the GPU via Remedy / *Alan Wake 2*-style dual-quaternion compute skinning (`GPUAnimationManager` + `GPUMeshSkinningContext`) and publishes a unified 3D fluid dynamics wind field (`GPUSceneWind`, combining `GlobalFluidEffector` far-field wind + gusts and the 3D MAC `GPUFluidCascadeStack` local wakes, vortices, and explosions) samplable on the GPU via `chunk_wind_field_sample` (`wind_field_sample(pos_ws)`). Rather than shipping baked keyframe animation clips, foliage bones are driven directly on the GPU by the fluid dynamics wind field:
362
- 1. **`uv1` Wind Weight Packing (`StandardAttributes.TextureCoordinates1`)**:
363
- - Every bark and foliage vertex writes normalized `uv1 = [wind_hierarchy_weight, wind_edge_flutter_weight]` in $[0, 1]^2$ (encoded losslessly to `u16x2` in `MeshletBatch`).
364
- 2. **Skeletal Joint Hierarchy & `Skin` Generation**:
365
- - The tree generator maps structural nodes (trunk sections + primary boughs up to a configurable joint budget $J_{\max} \le 64$) to `SceneNode` joints in pre-order.
366
- - Every bark and foliage vertex binds up to 4 joints (`StandardAttributes.SkinningJoints`: `Uint16Array(4 * V)`, `StandardAttributes.SkinningWeights`: `Float32Array(4 * V)` summing to $1.0$). A bark ring moves with the joint whose span it is in, alone: a joint turns its whole span about its pivot, as the rig placed it, so the bark is continuous across every pivot (which the joint turning it does not move) and a child's joint pivots where the bark it grows from carries it; between rings the mesh eases a pivot's crease over the ring segment around it. A child's first ring is seated in its parent's bark, carried as that bark carries it, and so is the child's wood before its own first joint. Blending a span with the joints above it, as the weights once did by `t_norm` along the branch, tore the bark at the pivot ending the span (the palm's trunk opened 7.6 cm in the reference wind). Leaves and cluster cards take the weights of the bark where they hang.
367
- 3. **GPU Fluid-Driven Foliage Bone System (`FoliageWindRig` + `shader_foliage_wind_apply` + `GPUSceneWind`)**:
368
- - **Data Tables (`ANIMATION_DATABASE_SPEC`)**:
369
- - `animation_foliage_rigs` (`ANIMATION_FOLIAGE_RIG_STRUCT`): stores `joints_first`, `joint_count`, `root_node` (`transforms` row of the tree root), and `weight`.
370
- - `animation_foliage_joints` (`ANIMATION_FOLIAGE_JOINT_STRUCT`, 64 B / 16 words per bone): stores static physical aeroelastic parameters (`rest_rotation`, unit `branch_axis` $\hat{\mathbf{d}}_j$, Euler-Bernoulli cantilever `compliance` $c_j$, `natural_frequency` $\omega_j$, `damping_ratio` $\zeta_j$, `max_angle` $\theta_{\max,j}$, `turbulence` $\tau_j$, `node`, `rig`) alongside persistent GPU-integrated dynamic state (`angular_displacement` $\boldsymbol{\theta}_j$, `angular_velocity` $\dot{\boldsymbol{\theta}}_j$, `flutter_phase` $\phi_j$).
371
- - **GPU Compute Pass (`shader_foliage_wind_apply.js`)**:
372
- - Dispatched inside `GPUAnimationManager.tick()` alongside `shader_animation_apply`, binding `scene_context.wind` via `wind_field_add_resources` and `chunk_wind_field_sample` (`WIND_FIELD_UNIFORM` switch).
373
- - Reads each bone's world position $\mathbf{p}_{\text{ws}} = \text{joint\_node.global}[3].xyz$, samples the 3D fluid velocity $\mathbf{w}_{\text{ws}} = \text{wind\_field\_sample}(\mathbf{p}_{\text{ws}})$, and transforms $\mathbf{w}_{\text{ws}}$ into the tree root's model space $\mathbf{w}_{\text{model}}$.
374
- - Computes cross-flow aerodynamic drag torque $\boldsymbol{\tau}_{\text{drag}} \propto (\hat{\mathbf{d}}_j \times \mathbf{w}_{\text{model}}) \cdot c_j(0.5 + 0.5\|\mathbf{w}_{\text{model}}\|)$ plus Strouhal vortex-shedding oscillation along the orthogonal basis $(\mathbf{e}_1, \mathbf{e}_2) \perp \hat{\mathbf{d}}_j$, with asymptotic soft saturation $\theta_{\max,j} \cdot x / (1 + x)$ so extreme fluid impulses never snap branches past $\theta_{\max,j}$.
375
- - Integrates an unconditionally stable implicit 2nd-order damped harmonic spring-damper oscillator ($\ddot{\boldsymbol{\theta}} + 2\zeta\omega\dot{\boldsymbol{\theta}} + \omega^2(\boldsymbol{\theta} - \boldsymbol{\theta}_{\text{target}}) = \mathbf{0}$), writes $(\boldsymbol{\theta}_j, \dot{\boldsymbol{\theta}}_j, \phi_j)$ back to `animation_foliage_joints`, and accumulates the resulting local quaternion into `pose_accumulator` via `pose_accumulator_add_rotation`.
376
- - Downstream `shader_animation_pose_resolve` $\to$ `graph_scene_update_transform_hierarchy` $\to$ `shader_skin_matrix_prep` $\to$ `GPUMeshSkinningContext` (dual-quaternion meshlet deformation + BLAS/TLAS BVH refit) executes unchanged with zero scale conflicts.
377
-
378
- ### 7.3 Procedural PBR `StandardShadeMaterial` Synthesis
379
- When the caller does not pass `custom_bark_material` or `custom_foliage_material`, the system synthesizes studio-quality procedural PBR textures using `Sampler2D` $\to$ `ShadeImage.fromSampler2D` $\to$ `ShadeTexture.from`. Both are the species', whatever the tree's seed or growth: a `TreeSpeciesCache` passed to `generate_tree` makes a bark material once per `bark_material` and a leaf atlas once per `foliage` and `foliage_material`, and shares them between the trees made alike, each tree tinting a leaf material of its own over the shared atlas.
380
- 1. **`make_bark_material(config)`**:
381
- - Generates tileable (`TextureWrapType.Repeat`) bark **Albedo** (fissured ridges, lenticels/stripes for birch, warm heartwood/moss undertones), **Tangent-Space Normal Map** (derived analytically from height gradients), and **ORM Map** (`R`: fissure occlusion, `G`: micro-roughness, `B`: 0 metalness) on a `StandardShadeMaterial` (`TransparencyMode.Opaque`, `ShadeDrawSide.Front`).
382
- 2. **`make_foliage_material(species)`**:
383
- - Generates the species' leaf (or needle shoot) **Albedo + Alpha Cutout** texture from its `LeafArchitecture` (§6.3: outline coverage, midvein and secondary veins, petiole, premultiplied RGBA compatible with Shade's `albedo_unpremultiply` and hashed alpha test), **Tangent-Space Normal Map** (camber, vein relief, bullation), and **ORM Map** on a `StandardShadeMaterial` (`TransparencyMode.AlphaTested`, `ShadeDrawSide.Double`, `transmission_factor: 0`).
384
-
385
- ### 7.4 Multi-LOD Chain
386
- Each LOD (default 3) is the tree drawn to a geometric error $\epsilon_k$, in metres (`LOD_REWORK_BRIEF_2026_10_27.md`):
387
- - **Bark** (§5.3): wood at least $\epsilon_k$ thick, its rings and sides as few as keep the surface within it.
388
- - **Cluster cards for what the wood leaves out.** Each cut is one card (`tree_clusters`, `tree_cluster_cards`): an
389
- undrawn branch on drawn wood with everything it carries, or a drawn branch's undrawn tip; a leaf on drawn wood joins
390
- its branch's nearest cut. The card lies in the plane what it draws spreads in: its leaves' cards and its twigs' bands,
391
- each by its area (the least-spread axis is its normal), facing away from the crown's centre. Where its leaves attach
392
- is not enough: a palm's attach along a rachis arching in a vertical plane while they spread to either side. Its depth is not held to the error, as
393
- SpeedTree's cluster cards' is not; holding every leaf within the error of a plane needs 12-16 cm before LOD0 fits.
394
- - **A few tiles for every cut** (`tree_cluster_representatives`): the fewest cuts whose tiles draw every cut of every
395
- LOD with its leaves magnified no further than the tree's own leaves vary (the 10th to 90th percentile of their
396
- sizes), within the tree's texture ceiling. A cut draws its representative on its own plane, as large as it draws
397
- (its leaves' and twigs' area: sized by its extent instead, the shrub's crown lost .12 of its density), hanging where it
398
- hangs, turned to run out its way. All of a tree's LODs share the one atlas.
399
- - **The texel is the leaf's**: the leaf material's own (`FoliageTileLayout.texel`), coarsened by halves only while the
400
- cover does not fit the texture ceiling, to what still tells the leaf from another
401
- (`FoliageTileLayout.legible_texel`: its outline's finest feature, teeth aside, four texels across, a needle two
402
- across its width), and past it only where even that does not fit: a blurred leaf is still the tree's, a tile drawn
403
- past the leaves' spread is not (its twigs as thick as boughs); a coarser LOD's representative at the error of the
404
- LOD before it, where that one is drawn to a pixel. Tied to the LOD's error, LOD0's leaves were six texels long.
405
- - **The bake** (`tree_cluster_bake`): each representative's tile is drawn orthographically from the leaves and twigs
406
- the tree grew, at its texel, 4x4 samples a texel, back to front in linear light. Every leaf is first pressed
407
- onto its card, turned about where it attaches until it lies in the card's plane, so a card shows the leaf area the
408
- tree grew whichever way the leaves face; projecting them instead loses half a leaf turned 60 degrees away. Twigs
409
- are bands their length by their diameter. Albedo, normal (in the card's frame) and ORM tiles pack into one atlas per
410
- LOD (`MaxRectanglesPacker`), each card a 6-vertex hull fitted to its tile's alpha
411
- (`foliage_atlas_cutout_fit_alpha`), fanned, 6 triangles. Canopy AO is in the tiles, not the vertices.
412
- - **The rig per LOD** (`tree_lod_plan`): the joint walk (`tree_skeleton_assign_skin_joints`, §7.2) runs over the
413
- wood the LOD draws, no further out than its bark, at a tolerance of `max(deflection_tolerance, eps_k)`: a sway
414
- smaller than the shape's error cannot be seen. A coarser LOD places joints only where the finer has one, so a switch
415
- keeps the joints both share. A card is skinned as the bark point it hangs from
416
- (`interpolate_ring_skin_weights4`); its flutter grows with distance from that point. Each LOD's builders bind its
417
- rig (`tree_skeleton_bind_skin_joints`) before meshing.
418
- - **Each LOD's error from its ceiling** (`tree_lod_plan`): the finest, a half-octave apart from
419
- `TREE_LOD_ERROR_FINEST` (1 cm), at which the tree's triangles and its rig's joints per m^2 of what it grew
420
- (`tree_grown_side_area`) fit `TREE_RENDER_COST_CEILING` at that LOD, and never finer than the LOD before. The atlas is
421
- held to the ceiling's texture bytes per m^2.
422
- - **The leaves as grown** (`tree_mesh_build_foliage`, every leaf a card) are the reference the bakes draw from and the
423
- measures hold the LODs to; no LOD draws them.
424
-
425
- ---
426
-
427
- ## 8. Module File Organization (`src/generation/foliage/`)
428
-
429
- Following Meep's strict one-export-per-file (`PascalCase.js` for classes/enums, `snake_case.js` for pure functions) convention:
430
-
431
- ```
432
- src/generation/foliage/
433
- config/
434
- CrownEnvelopeType.js
435
- PhyllotaxisMode.js
436
- FoliageCardType.js
437
- FoliageBarkType.js
438
- TreePreset.js
439
- BranchGeneratorConfig.js
440
- BranchSpawnRule.js
441
- FoliageSpawnRule.js
442
- ShootSystemRule.js
443
- CrownConfig.js
444
- FoliageConfig.js
445
- BarkMaterialConfig.js
446
- FoliageMaterialConfig.js
447
- TreeWindConfig.js
448
- TreeLODConfig.js
449
- TreeSpeciesConfig.js (+ .spec.js)
450
- presets/
451
- make_tree_species_preset.js (+ .spec.js)
452
- skeleton/
453
- TreeSkeleton.js (+ .spec.js)
454
- crown_envelope_evaluate.js (+ .spec.js)
455
- spine_frame_double_reflection.js (+ .spec.js)
456
- tree_skeleton_grow.js (+ .spec.js)
457
- tree_skeleton_grow_framework.js
458
- tree_skeleton_fit_crown_frame.js
459
- tree_skeleton_copy_branches.js (+ .spec.js)
460
- tree_skeleton_extend_branch.js
461
- tree_skeleton_floor_girth.js
462
- tree_skeleton_compute_pipe_radii.js (+ .spec.js)
463
- shoot_demography.js (+ .spec.js)
464
- tree_skeleton_grow_shoots.js (+ .spec.js)
465
- tree_skeleton_assign_skin_joints.js (+ .spec.js)
466
- tree_skeleton_bind_skin_joints.js
467
- tree_skeleton_grow_growth_modifiers.spec.js
468
- foliage_card_density.js
469
- foliage_senescence.js
470
- mesh/
471
- branch_collar_project.js (+ .spec.js)
472
- branch_ring_triangulate.js (+ .spec.js)
473
- tree_mesh_build_bark.js (+ .spec.js)
474
- foliage_collect_attachments.js (+ .spec.js, _density.spec.js)
475
- foliage_seasons.spec.js
476
- tree_mesh_build_foliage.js (+ .spec.js, _cutout.spec.js)
477
- tree_mesh_apply_canopy_ao.js (+ .spec.js)
478
- foliage_scale_spread.js
479
- tree_clusters.js (+ .spec.js)
480
- tree_cluster_cards.js (+ .spec.js)
481
- tree_mesh_build_clusters.js
482
- tree_cluster_representatives.js (+ .spec.js)
483
- material/
484
- make_bark_material.js (+ .spec.js)
485
- make_foliage_material.js (+ .spec.js)
486
- compute_foliage_variant_atlas_layout.js
487
- foliage_leaf_silhouette.js
488
- FoliageAtlasCutout.js
489
- foliage_atlas_cutout.js (+ .spec.js)
490
- tree_cluster_bake.js (+ .spec.js)
491
- tree_cluster_atlas.js
492
- tree_cluster_press.js
493
- tree_cluster_tiles.js
494
- tree_cluster_atlas_pack.js
495
- foliage_material_from_samplers.js
496
- animation/
497
- build_tree_wind_rig.js (+ .spec.js)
498
- asset/
499
- TreeLODAsset.js
500
- TreeAsset.js
501
- TreeSpeciesCache.js (+ .spec.js)
502
- tree_shoot_prototypes.js (+ .spec.js)
503
- tree_shoot_instances.js (+ .spec.js)
504
- tree_lod_plan.js (+ .spec.js)
505
- generate_tree.js (+ .spec.js)
506
- place_tree.js (+ .spec.js)
507
- ```
508
-
509
- ---
510
-
511
- ## 9. Adversarial Design Review & Required Revisions
512
-
513
- An adversarial audit of §§1–8 against the `packages/meep-engine/src` implementation identified 10 critical invariants and edge cases, all resolved in the final design below:
514
-
515
- 1. **`Graph`, `Transform64`, and `Attribute` Integration (No `BinaryTopology` Contortion)**:
516
- - *Finding*: `BinaryTopology` is a polygonal surface mesh structure with unordered edge endpoints (`v1`, `v2`), not a general-purpose directed graph.
517
- - *Resolution*: `TreeSkeleton` uses Meep's directed `Graph` (`src/core/graph/v2/Graph.js`, `EdgeDirectionType.Forward`) for topology, `Transform64` (`src/engine/ecs/transform/Transform64.js`, `t64_look_rotation`) for node 3D positions, RMF bases (`[R, S, T]`), and cross-sectional radii, and `Attribute` (`src/shade/renderer/geometry/Attribute.js`) for per-node and per-segment buffers.
518
- 2. **Deep-Copy Isolation on `TreeSkeleton.copy()` and `clone()`**:
519
- - *Finding*: Cloning a `TreeSkeleton` must not alias `Transform64` instances or `Attribute` typed arrays.
520
- - *Resolution*: `TreeSkeleton.prototype.copy()` deep-copies `this.graph`, each `Transform64` in `this.node_transforms`, and all node/segment `Attribute` instances via `Attribute.prototype.copy()`.
521
- 3. **`PointHashGrid3` Non-Incremental Rebuild, Static `VISITED` Scratch, & XOR Hash Collisions**:
522
- - *Finding*: `PointHashGrid3` uses a module-static `VISITED` array in `forEachNear` (forbidding nested calls) and Teschner XOR hashing (requiring exact distance filtering).
523
- - *Resolution*: `tree_skeleton_grow` builds `PointHashGrid3` once with `cell_size = max_attraction_radius`, tracks consumed attraction points in a separate `Uint8Array(N_attract)` `alive` buffer, never nests `forEachNear`, and filters candidates by `alive[idx] === 1` and exact squared distance $d^2 \le r_{\text{attract}}^2$.
524
- 4. **Seeded Noise Offset & Mulberry32 Hash Avalanche**:
525
- - *Finding*: `sdnoise3_array` and `curl_noise_3d` are unseeded, and `hash_mix2` / `hash_mix3` (`(a * 31 + b) | 0`) lack bit avalanche if divided directly by $2^{32}$.
526
- - *Resolution*: All per-branch/per-node seeds mixed with `hash_mix3` are passed through `seededRandom` (Mulberry32 avalanche) before sampling floats, and all 3D noise evaluations add a seed-derived spatial offset $\mathbf{o}_{\text{seed}} \in [-500, 500]^3$.
527
- 5. **Lazy `MeshletGeometry` / `Prefab` Evaluation & Zero Degenerate Triangles**:
528
- - *Finding*: `geometry_to_meshlets_meshoptimizer` asserts `MeshoptClusterizer.ready` (async WASM), and `meshlet_batch_to_bvh` asserts `root === 0`, which fails if `MeshoptClusterizer` strips any index-degenerate triangle (`i0 === i1 || i1 === i2 || i2 === i0`) or if a 0-triangle geometry is clusterized.
529
- - *Resolution*:
530
- - `TreeLODAsset.bark_meshlet_geometry`, `foliage_meshlet_geometry`, `scene_bundle`, and `prefab` are lazy memoized getters.
531
- - `M_min >= 3` is enforced on all branch rings, tapered zero-radius branch tips use an $M$-triangle apex fan (zero degenerate triangles), and empty foliage sets `foliage_meshlet_geometry = null`.
532
- 6. **Branch Collar Projection & Dichotomous Fork Guards**:
533
- - *Finding*: Steep insertion angles ($\alpha \to 0^\circ, 180^\circ$) cause `0/0` in $\mathbf{R}_{c,0}$ and unbounded axial ray pullback $\tau \to \infty$; large child radii ($R_c \approx R_p$) bunch vertices if clamped post-flare; terminal dichotomous splits should not project onto the lateral cylinder wall.
534
- - *Resolution*: Fall back to `tube_frame_transport` when $\|\mathbf{T}_p - (\mathbf{T}_p \cdot \mathbf{T}_{c,0})\mathbf{T}_{c,0}\|^2 \le 10^{-8}$, clamp axial pullback $|\tau| \le 1.25 R_p$, scale collar flare radius prior to ring emission so $R_{\text{lateral}} \le 0.88 R_p$, and use direct terminal ring blending for terminal splits (`parent_attach_t >= 0.95`).
535
- 7. **Double-Reflection RMF Degeneracy Guards**:
536
- - *Finding*: Coincident points ($c_1 \le 10^{-12}$) or pure lateral steps with unchanged tangent ($c_2 \le 10^{-12}$) divide by zero in Wang et al.'s double reflection.
537
- - *Resolution*: Guard $c_1 \le 10^{-12}$ via `tube_frame_transport`, and when $c_2 \le 10^{-12}$ treat the second reflection as identity followed by Gram-Schmidt orthonormalization.
538
- 8. **Double-Sided Foliage Backface Normal Negation in `fragment_gbuffer.js`**:
539
- - *Finding*: `fragment_gbuffer.js` negates `world_vertex_normal` when `dot(world_face_normal, view_direction) < 0`. Replacing card normals with pure radial crown normals causes back-facing sunlit cards to flip their normal into the dark trunk interior and can trigger Gram-Schmidt tangent singularities when $\mathbf{n} \parallel \mathbf{t}_{\text{uv}}$.
540
- - *Resolution*: Orient card front faces outward ($\mathbf{U} \cdot \mathbf{n}_{\text{canopy}} \ge 0$), constrain `normal_puffiness` so $\mathbf{n}_{\text{vertex}} \cdot \mathbf{n}_{\text{face}} \ge 0.55$ (smooth V-fold dome + bounded skyward tilt), and encode macro volumetric crown shading in `StandardAttributes.Color` (`AO_crown * AO_local`).
541
- 9. **`StandardShadeMaterial` & `ShadeTexture` Pipeline Invariants**:
542
- - *Finding*: Default `ambient_factors = LinearModifier(1, 1)` saturates `out.ambient` to `>= 1.0`; `transmission_factor > 0` makes cutout card corners cast refractive shadows in the path tracer; `ShadeImage` defaults to `AlphaMode.Straight` (which premultiplies on GPU upload) and `ColorSpace.SRGB`.
543
- - *Resolution*: Set `ambient_factors.set(1, 0)` on both materials, keep `transmission_factor = 0` on cutout foliage, write dilated straight RGBA with `AlphaMode.Straight` on foliage albedo, and set `image.color_space = ColorSpace.None`, `image.alpha_mode = AlphaMode.Opaque`, `texture.color_space = ColorSpace.LinearSRGB` on normal and ORM textures.
544
- 10. **Zero-Defect `Skin`, `SceneBundle`, & GPU Fluid-Driven `FoliageWindRig` Playback**:
545
- - *Finding*: `prefab_normalize_skin_frames` requires rigid bind frames (`frame_defect === 0`, `residual === 0`) and leaf mesh nodes (`obstructed.length === 0`); shipping baked keyframe wind clips would ignore Meep's 3D fluid dynamics simulation (`GPUSceneWind`); `prefab_place` does not register `FoliageWindRig`s automatically.
546
- - *Resolution*: Author `tree_root` (`node 0`), joint nodes (`1..J`) with identity rest rotations `[0, 0, 0, 1]` and exact translation inverse-bind matrices $T(-\mathbf{p}_j)$, and leaf mesh nodes (`parent: 0`, identity local transform) sharing one `Skin`. `build_tree_wind_rig` authors a `FoliageWindRig` whose bones sample `GPUSceneWind` (`chunk_wind_field_sample`) in `shader_foliage_wind_apply`. `place_tree` registers the `FoliageWindRig` on `scene_context.animation_manager` with a position-desynchronized `flutter_phase`, and `unplace_tree` unregisters `foliage_rig_ids` before `prefab_unplace`.
547
-