@woosh/meep-engine 3.60.4 → 3.60.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/CHANGELOG.md +2602 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  63. package/src/shade/renderer/Renderer.js +7 -5
  64. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  67. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  68. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  69. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  70. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  71. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  72. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
  74. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
  75. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
  77. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  78. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  80. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  81. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  82. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  83. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  85. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  86. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  87. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
  88. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  89. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
  90. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  91. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  92. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  93. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  94. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  96. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  98. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  99. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  100. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  101. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  102. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  103. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  104. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  105. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  106. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  107. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  108. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  109. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  110. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  111. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  112. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  113. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  114. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  115. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  116. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  117. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  118. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  119. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  120. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  121. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  122. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  123. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  124. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  126. package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
  127. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  128. package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
  129. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  130. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  131. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  132. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  133. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  134. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  135. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  136. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  137. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  138. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  139. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  140. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  141. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  142. package/src/shade/renderer/water/shader_water.js +22 -13
  143. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  144. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  145. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  146. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  147. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  148. package/editor/REWORK_PLAN_2026_08.md +0 -692
  149. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  150. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  151. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  152. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  153. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  154. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  155. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  156. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  157. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  158. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  159. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  160. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  161. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  162. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  163. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  164. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  165. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  166. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  167. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  168. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  169. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  170. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  171. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  172. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  173. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  174. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  175. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  176. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  177. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  178. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  179. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  180. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  181. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  182. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  183. package/src/REVIEW_2026_08_06/generation.md +0 -176
  184. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  185. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  186. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  187. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  188. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  189. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  190. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  191. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  192. package/src/REVIEW_2026_08_06/view.md +0 -667
  193. package/src/REVIEW_2026_08_06.md +0 -610
  194. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  195. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  196. package/src/core/bvh8/NOTES.md +0 -63
  197. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  198. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  199. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  200. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  201. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  202. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  203. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  204. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  205. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  206. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  207. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  208. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  209. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  210. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  211. package/src/engine/REVIEW_2026_07_03.md +0 -211
  212. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  213. package/src/engine/control/first-person/DESIGN.md +0 -658
  214. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  215. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  216. package/src/engine/control/first-person/TODO.md +0 -160
  217. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  218. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  219. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  220. package/src/engine/ecs/ik/PLAN.md +0 -179
  221. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  222. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  223. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  224. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  225. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  226. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  227. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  228. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  229. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  230. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  231. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  232. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  233. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  234. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  235. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  236. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  237. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  238. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  239. package/src/engine/physics/cloth/PLAN.md +0 -3056
  240. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  241. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  242. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  243. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  244. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  245. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  246. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  247. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  248. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  249. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  250. package/src/format/image/avif/DECISIONS.md +0 -545
  251. package/src/format/image/jpeg/NOTES.md +0 -3
  252. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  253. package/src/generation/COORDINATES.md +0 -54
  254. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  255. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  256. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  257. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  258. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  259. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  260. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  261. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  262. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  263. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  264. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  265. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  266. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  267. package/src/shade/RENDERER_CONTRACT.md +0 -697
  268. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  269. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  270. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  271. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  272. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  273. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  274. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  275. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  276. package/src/shade/renderer/NOTES.md +0 -78
  277. package/src/shade/renderer/PLAN.md +0 -8
  278. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  279. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  280. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  281. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  282. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  283. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  284. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  285. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  286. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  287. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  288. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  289. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  290. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  291. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  292. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  293. package/src/shade/renderer/camera/orbital/README.md +0 -81
  294. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  295. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  296. package/src/shade/renderer/camera/orbital/index.js +0 -9
  297. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  298. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  299. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  300. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  301. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  302. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  303. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  304. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  305. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  306. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  307. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  308. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  309. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  310. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  311. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  312. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  313. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  314. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  315. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  316. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  317. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  318. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  319. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  320. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  321. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  322. package/src/shade/renderer/hiz/NOTES.md +0 -3
  323. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  324. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  325. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  326. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  327. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  328. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  329. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  330. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  331. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  332. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  333. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  334. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  335. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  336. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  337. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  338. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  339. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  340. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  341. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  342. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  343. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  344. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  345. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  346. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  347. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  348. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  349. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  350. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  351. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  352. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  353. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  354. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  355. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  356. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  357. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  358. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  359. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  360. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  361. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  362. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  363. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  364. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  365. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  366. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  367. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  368. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  369. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  370. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  371. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  372. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  373. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  374. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  375. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  376. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  377. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  378. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  379. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,350 +1,405 @@
1
- import { assert } from "../../../core/assert.js";
2
- import { max2 } from "../../../core/math/max2.js";
3
- import { round_up } from "../../../core/math/round_up.js";
4
- import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
5
- import { TextureViewDescriptor } from "../../descriptor/texture/TextureViewDescriptor.js";
6
- import { texture_mip_level_count } from "../../util/texture_mip_extent.js";
7
- import { hzb_pick_alignment } from "./hzb_pick_alignment.js";
8
- import { hzb_plan_reduction_steps } from "./hzb_plan_reduction_steps.js";
9
- import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
10
- import { shader_hzb_reduce_any, shader_hzb_reduce_mip0 } from "./shader_hzb_reduce_any.js";
11
- import { shader_hzb_reduce_mip0_clip } from "./shader_hzb_reduce_mip0_clip.js";
12
- import { shader_hzb_spd_2, shader_hzb_spd_3, shader_hzb_spd_4 } from "./shader_hzb_spd.js";
13
-
14
- /**
15
- * @typedef {import("../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
16
- * @typedef {import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext} ShadeGPUCommandContext
17
- * @typedef {import("../GraphicsContext.js").GraphicsContext} GraphicsContext
18
- * @typedef {import("../texture/GPUTextureContext.js").GPUTextureContext} GPUTextureContext
19
- * @typedef {import("./hzb_plan_reduction_steps.js").HZBReductionStep} HZBReductionStep
20
- */
21
-
22
- export class HierarchicalZBuffer {
23
-
24
- /**
25
- * @type {GPUTextureContext}
26
- */
27
- #texture;
28
-
29
- /**
30
- * @type {string|GPUTextureFormat}
31
- */
32
- #format = HZB_TEXTURE_FORMAT
33
-
34
- /**
35
- * Precomputed reduction schedule from mip 0 to the 1x1 tail for the current HZB dimensions.
36
- * @type {HZBReductionStep[]}
37
- */
38
- #steps = [];
39
-
40
- /**
41
- * Offer the pipelines {@link build} dispatches — see {@link PipelineEnquiry}.
42
- *
43
- * @param {PipelineEnquiry} enquiry
44
- */
45
- static enquirePipelines(enquiry) {
46
- enquiry.compute.push(
47
- shader_hzb_reduce_mip0.pipeline,
48
- shader_hzb_reduce_mip0_clip.pipeline,
49
- shader_hzb_reduce_any.pipeline,
50
- shader_hzb_spd_2.pipeline,
51
- shader_hzb_spd_3.pipeline,
52
- shader_hzb_spd_4.pipeline,
53
- );
54
- }
55
-
56
- /**
57
- *
58
- * @returns {GPUTextureContext}
59
- */
60
- get texture() {
61
- return this.#texture;
62
- }
63
-
64
-
65
- /**
66
- * @type {GraphicsContext}
67
- */
68
- #graphics;
69
-
70
- /**
71
- *
72
- * @type {number[]}
73
- */
74
- #viewport_size = [1, 1];
75
-
76
- /**
77
- *
78
- * @param {GraphicsContext} graphics
79
- */
80
- constructor(graphics) {
81
- this.#graphics = graphics;
82
-
83
- this.#texture = graphics.textures.contextFromDescriptor(TextureDescriptor.from({
84
- label: "Hierarchical Z Buffer",
85
- format: this.#format,
86
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING,
87
- mipLevelCount: 1,
88
- size: [1, 1]
89
- }));
90
-
91
-
92
- }
93
-
94
- /**
95
- * @param {number} mip
96
- * @returns {GPUTextureView}
97
- */
98
- #obtain_mip_view(mip) {
99
- return this.#texture.obtainView(TextureViewDescriptor.from({
100
- baseMipLevel: mip,
101
- mipLevelCount: 1,
102
- dimension: "2d",
103
- baseArrayLayer: 0,
104
- arrayLayerCount: 1
105
- }));
106
- }
107
-
108
- /**
109
- *
110
- * @param {ShadeGPUCommandContext} encoder
111
- * @param {GPUTextureContext} source
112
- * @param {number[]} [source_offset] [x0,y0]
113
- */
114
- build(
115
- encoder,
116
- source,
117
- source_offset
118
- ) {
119
-
120
- assert.defined(encoder, 'encoder');
121
- assert.notNull(encoder, 'encoder');
122
- assert.equal(encoder.isGPUCommandContext, true, 'encoder is not a GPUCommandContext')
123
-
124
- assert.defined(source, 'source');
125
- assert.notNull(source, 'source');
126
- assert.equal(source.isGPUTextureContext, true, 'source is not a GPUTextureContext')
127
-
128
- // the first pass is special, we need to read from source texture and write to first mip level of hzb
129
-
130
- const texture = this.#texture;
131
-
132
- assert.equal(texture.isDestroyed, false, 'texture is destroyed');
133
-
134
- let source_view = source.obtainView(TextureViewDescriptor.from({
135
- baseMipLevel: 0,
136
- mipLevelCount: 1,
137
- dimension: "2d",
138
- baseArrayLayer: 0,
139
- arrayLayerCount: 1
140
- }));
141
-
142
- const destination_view = this.#obtain_mip_view(0);
143
-
144
- const viewport_size = this.#viewport_size;
145
-
146
- const is_clipped_variant = source_offset !== undefined
147
- && (
148
- (
149
- source_offset[0] !== 0
150
- || source_offset[1] !== 0
151
- )
152
- || (
153
- viewport_size[0] !== source.width
154
- || viewport_size[1] !== source.height
155
- )
156
- );
157
-
158
- if (is_clipped_variant) {
159
- // special case for clip region
160
- const mip0_resolution = this.#mip_resolution(0);
161
-
162
- shader_hzb_reduce_mip0_clip.dispatchThreads({
163
- encoder,
164
- bindings: {
165
- tInput: source_view,
166
- tOutput: destination_view,
167
- settings: {
168
- clip_region: [
169
- source_offset[0], source_offset[1],
170
- viewport_size[0], viewport_size[1],
171
- ],
172
- output_resolution: mip0_resolution,
173
- },
174
- },
175
- thread_count_x: mip0_resolution[0],
176
- thread_count_y: mip0_resolution[1],
177
- });
178
- } else {
179
-
180
- this.#do_reduction_pass(encoder, shader_hzb_reduce_mip0, source_view, destination_view, 0);
181
- }
182
-
183
- source_view = destination_view;
184
-
185
- const steps = this.#steps;
186
- const step_count = steps.length;
187
-
188
- for (let s = 0; s < step_count; s++) {
189
- const { base_mip, mip_count } = steps[s];
190
-
191
- if (mip_count === 1) {
192
- const target_mip = base_mip + 1;
193
- const out_view = this.#obtain_mip_view(target_mip);
194
-
195
- this.#do_reduction_pass(encoder, shader_hzb_reduce_any, source_view, out_view, target_mip);
196
-
197
- source_view = out_view;
198
- } else {
199
- const out1 = this.#obtain_mip_view(base_mip + 1);
200
- const out2 = this.#obtain_mip_view(base_mip + 2);
201
- const out1_res = this.#mip_resolution(base_mip + 1);
202
- const group_count_x = (out1_res[0] + 15) >>> 4;
203
- const group_count_y = (out1_res[1] + 15) >>> 4;
204
-
205
- if (mip_count === 2) {
206
- shader_hzb_spd_2.dispatch({
207
- encoder,
208
- bindings: { tInput: source_view, tOut1: out1, tOut2: out2 },
209
- group_count_x,
210
- group_count_y,
211
- });
212
- source_view = out2;
213
- } else if (mip_count === 3) {
214
- const out3 = this.#obtain_mip_view(base_mip + 3);
215
- shader_hzb_spd_3.dispatch({
216
- encoder,
217
- bindings: { tInput: source_view, tOut1: out1, tOut2: out2, tOut3: out3 },
218
- group_count_x,
219
- group_count_y,
220
- });
221
- source_view = out3;
222
- } else {
223
- const out3 = this.#obtain_mip_view(base_mip + 3);
224
- const out4 = this.#obtain_mip_view(base_mip + 4);
225
- shader_hzb_spd_4.dispatch({
226
- encoder,
227
- bindings: { tInput: source_view, tOut1: out1, tOut2: out2, tOut3: out3, tOut4: out4 },
228
- group_count_x,
229
- group_count_y,
230
- });
231
- source_view = out4;
232
- }
233
- }
234
- }
235
- }
236
-
237
- /**
238
- *
239
- * @param {ShadeGPUCommandContext} encoder
240
- * @param {ComputeShader} shader
241
- * @param {GPUTextureView} source_view
242
- * @param {GPUTextureView} destination_view
243
- * @param {number} index
244
- */
245
- #do_reduction_pass(
246
- encoder,
247
- shader,
248
- source_view,
249
- destination_view,
250
- index
251
- ) {
252
- const output_resolution = this.#mip_resolution(index);
253
-
254
- shader.dispatchThreads({
255
- encoder,
256
- bindings: {
257
- tInput: source_view,
258
- tOutput: destination_view,
259
- output_resolution,
260
- },
261
- thread_count_x: output_resolution[0],
262
- thread_count_y: output_resolution[1],
263
- });
264
-
265
- }
266
-
267
- /**
268
- * Scratch for {@link #mip_resolution}. The value is serialised into the pass's immediate bytes
269
- * before the next call, so one array can serve every mip.
270
- *
271
- * @type {number[]}
272
- */
273
- #mip_resolution_scratch = [1, 1];
274
-
275
- /**
276
- * Size of mip `index` of the HZB, which is what the reduction pass writing into it needs to know.
277
- *
278
- * Each mip halves the one above it, floored at one texel — the same walk that used to be
279
- * precomputed into a uniform buffer of every mip's resolution and bound at a per-mip dynamic
280
- * offset. As immediate data there is nothing to precompute into.
281
- *
282
- * @param {number} index
283
- * @returns {number[]}
284
- */
285
- #mip_resolution(index) {
286
- const size = this.#texture.size;
287
-
288
- const out = this.#mip_resolution_scratch;
289
-
290
- out[0] = max2(1, size[0] >>> index);
291
- out[1] = max2(1, size[1] >>> index);
292
-
293
- return out;
294
- }
295
-
296
- /**
297
- *
298
- * @param {number} x
299
- * @param {number} y
300
- */
301
- setViewportSize(x, y) {
302
- assert.isNonNegativeInteger(x, 'x');
303
- assert.isNonNegativeInteger(y, 'y');
304
-
305
- this.#viewport_size[0] = x;
306
- this.#viewport_size[1] = y;
307
-
308
- const base_w = Math.max(x >>> 1, 1);
309
- const base_h = Math.max(y >>> 1, 1);
310
-
311
- const [align_w, align_h] = hzb_pick_alignment(x, y, 1.05);
312
-
313
- const hzb_w = round_up(base_w, align_w);
314
- const hzb_h = round_up(base_h, align_h);
315
-
316
- this.#resize(hzb_w, hzb_h);
317
- }
318
-
319
- /**
320
- *
321
- * @param {number} x
322
- * @param {number} y
323
- */
324
- #resize(
325
- x,
326
- y
327
- ) {
328
-
329
- const texture = this.#texture;
330
- const size = texture.size;
331
-
332
- if (size[0] === x && size[1] === y) {
333
- // no size change
334
- return;
335
- }
336
-
337
- // a screen-space depth pyramid, 2D always
338
- const mip_count = texture_mip_level_count(x, y, 1, "2d");
339
-
340
- texture.descriptor.mipLevelCount = mip_count;
341
-
342
- texture.resize(x, y);
343
-
344
- this.#steps = hzb_plan_reduction_steps(x, y);
345
- }
346
-
347
- destroy() {
348
- this.#texture.destroy();
349
- }
350
- }
1
+ import { assert } from "../../../core/assert.js";
2
+ import { max2 } from "../../../core/math/max2.js";
3
+ import { round_up } from "../../../core/math/round_up.js";
4
+ import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
5
+ import { TextureViewDescriptor } from "../../descriptor/texture/TextureViewDescriptor.js";
6
+ import { texture_mip_level_count } from "../../util/texture_mip_extent.js";
7
+ import { ShaderSwitchSet } from "../shader/compiler/ShaderSwitchSet.js";
8
+ import { HZB_FOOTPRINT_X } from "./HZB_FOOTPRINT_X.js";
9
+ import { HZB_FOOTPRINT_Y } from "./HZB_FOOTPRINT_Y.js";
10
+ import { HZBFootprint } from "./HZBFootprint.js";
11
+ import { hzb_footprint_texels } from "./hzb_footprint_texels.js";
12
+ import { hzb_pick_alignment } from "./hzb_pick_alignment.js";
13
+ import { hzb_plan_reduction_steps } from "./hzb_plan_reduction_steps.js";
14
+ import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
15
+ import { shader_hzb_reduce_any } from "./shader_hzb_reduce_any.js";
16
+ import { shader_hzb_reduce_mip0 } from "./shader_hzb_reduce_mip0.js";
17
+ import { shader_hzb_spd_2, shader_hzb_spd_3, shader_hzb_spd_4 } from "./shader_hzb_spd.js";
18
+
19
+ /**
20
+ * @typedef {import("../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
21
+ * @typedef {import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext} ShadeGPUCommandContext
22
+ * @typedef {import("../GraphicsContext.js").GraphicsContext} GraphicsContext
23
+ * @typedef {import("../texture/GPUTextureContext.js").GPUTextureContext} GPUTextureContext
24
+ * @typedef {import("./hzb_plan_reduction_steps.js").HZBReductionStep} HZBReductionStep
25
+ */
26
+
27
+ /**
28
+ * Every footprint mip 0 can be reduced with, 2x2, 3x2, 2x3 and 3x3.
29
+ * @type {ShaderSwitchSet[]}
30
+ */
31
+ const MIP0_FOOTPRINTS = [
32
+ ShaderSwitchSet.EMPTY,
33
+ ShaderSwitchSet.EMPTY.with(HZB_FOOTPRINT_X, HZBFootprint.Three),
34
+ ShaderSwitchSet.EMPTY.with(HZB_FOOTPRINT_Y, HZBFootprint.Three),
35
+ ShaderSwitchSet.EMPTY.with(HZB_FOOTPRINT_X, HZBFootprint.Three).with(HZB_FOOTPRINT_Y, HZBFootprint.Three),
36
+ ];
37
+
38
+ /**
39
+ * The footprint mip 0 is reduced with along one axis: the widest of any of its texels.
40
+ *
41
+ * @param {number} source_size viewport texels on the axis
42
+ * @param {number} output_size mip 0 texels on the axis
43
+ * @returns {HZBFootprint}
44
+ */
45
+ function mip0_footprint(source_size, output_size) {
46
+ const texels = hzb_footprint_texels(source_size, output_size);
47
+
48
+ // mip 0 is never smaller than half the viewport, which keeps every footprint within 3
49
+ assert.lessThanOrEqual(texels, 3, `footprint of ${output_size} HZB texels over ${source_size}`);
50
+
51
+ return texels <= 2 ? HZBFootprint.Two : HZBFootprint.Three;
52
+ }
53
+
54
+ export class HierarchicalZBuffer {
55
+
56
+ /**
57
+ * @type {GPUTextureContext}
58
+ */
59
+ #texture;
60
+
61
+ /**
62
+ * @type {string|GPUTextureFormat}
63
+ */
64
+ #format = HZB_TEXTURE_FORMAT
65
+
66
+ /**
67
+ * Precomputed reduction schedule from mip 0 to the 1x1 tail for the current HZB dimensions.
68
+ * @type {HZBReductionStep[]}
69
+ */
70
+ #steps = [];
71
+
72
+ /**
73
+ * The footprint mip 0 is reduced with, for the current viewport and mip 0 size.
74
+ * @type {ShaderSwitchSet}
75
+ */
76
+ #mip0_footprint = ShaderSwitchSet.EMPTY;
77
+
78
+ /**
79
+ * Scratch for mip 0's immediates, serialised into the pass's immediate bytes before the next build,
80
+ * as {@link #mip_resolution_scratch} is.
81
+ *
82
+ * @type {{clip_region: number[], output_resolution: number[]}}
83
+ */
84
+ #mip0_settings = { clip_region: [0, 0, 1, 1], output_resolution: [1, 1] };
85
+
86
+ /**
87
+ * Offer the pipelines {@link build} dispatches — see {@link PipelineEnquiry}.
88
+ *
89
+ * @param {PipelineEnquiry} enquiry
90
+ */
91
+ static enquirePipelines(enquiry) {
92
+ for (let i = 0; i < MIP0_FOOTPRINTS.length; i++) {
93
+ enquiry.compute.push(shader_hzb_reduce_mip0.variant(MIP0_FOOTPRINTS[i]).pipeline);
94
+ }
95
+
96
+ enquiry.compute.push(
97
+ shader_hzb_reduce_any.pipeline,
98
+ shader_hzb_spd_2.pipeline,
99
+ shader_hzb_spd_3.pipeline,
100
+ shader_hzb_spd_4.pipeline,
101
+ );
102
+ }
103
+
104
+ /**
105
+ *
106
+ * @returns {GPUTextureContext}
107
+ */
108
+ get texture() {
109
+ return this.#texture;
110
+ }
111
+
112
+
113
+ /**
114
+ * @type {GraphicsContext}
115
+ */
116
+ #graphics;
117
+
118
+ /**
119
+ *
120
+ * @type {number[]}
121
+ */
122
+ #viewport_size = [1, 1];
123
+
124
+ /**
125
+ *
126
+ * @param {GraphicsContext} graphics
127
+ */
128
+ constructor(graphics) {
129
+ this.#graphics = graphics;
130
+
131
+ this.#texture = graphics.textures.contextFromDescriptor(TextureDescriptor.from({
132
+ label: "Hierarchical Z Buffer",
133
+ format: this.#format,
134
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING,
135
+ mipLevelCount: 1,
136
+ size: [1, 1]
137
+ }));
138
+
139
+
140
+ }
141
+
142
+ /**
143
+ * @param {number} mip
144
+ * @returns {GPUTextureView}
145
+ */
146
+ #obtain_mip_view(mip) {
147
+ return this.#texture.obtainView(TextureViewDescriptor.from({
148
+ baseMipLevel: mip,
149
+ mipLevelCount: 1,
150
+ dimension: "2d",
151
+ baseArrayLayer: 0,
152
+ arrayLayerCount: 1
153
+ }));
154
+ }
155
+
156
+ /**
157
+ *
158
+ * @param {ShadeGPUCommandContext} encoder
159
+ * @param {GPUTextureContext} source
160
+ * @param {number[]} [source_offset] [x0,y0]
161
+ */
162
+ build(
163
+ encoder,
164
+ source,
165
+ source_offset
166
+ ) {
167
+
168
+ assert.defined(encoder, 'encoder');
169
+ assert.notNull(encoder, 'encoder');
170
+ assert.equal(encoder.isGPUCommandContext, true, 'encoder is not a GPUCommandContext')
171
+
172
+ assert.defined(source, 'source');
173
+ assert.notNull(source, 'source');
174
+ assert.equal(source.isGPUTextureContext, true, 'source is not a GPUTextureContext')
175
+
176
+ // the first pass is special, we need to read from source texture and write to first mip level of hzb
177
+
178
+ const texture = this.#texture;
179
+
180
+ assert.equal(texture.isDestroyed, false, 'texture is destroyed');
181
+
182
+ let source_view = source.obtainView(TextureViewDescriptor.from({
183
+ baseMipLevel: 0,
184
+ mipLevelCount: 1,
185
+ dimension: "2d",
186
+ baseArrayLayer: 0,
187
+ arrayLayerCount: 1
188
+ }));
189
+
190
+ const destination_view = this.#obtain_mip_view(0);
191
+
192
+ const viewport_size = this.#viewport_size;
193
+
194
+ // the viewport's region of the source: all of it for a camera, a slot of the atlas for a shadow map
195
+ const region_x = source_offset !== undefined ? source_offset[0] : 0;
196
+ const region_y = source_offset !== undefined ? source_offset[1] : 0;
197
+
198
+ assert.lessThanOrEqual(region_x + viewport_size[0], source.width, 'viewport region past the source\'s width');
199
+ assert.lessThanOrEqual(region_y + viewport_size[1], source.height, 'viewport region past the source\'s height');
200
+
201
+ const mip0_resolution = this.#mip_resolution(0);
202
+
203
+ const settings = this.#mip0_settings;
204
+ const clip_region = settings.clip_region;
205
+
206
+ clip_region[0] = region_x;
207
+ clip_region[1] = region_y;
208
+ clip_region[2] = viewport_size[0];
209
+ clip_region[3] = viewport_size[1];
210
+
211
+ settings.output_resolution = mip0_resolution;
212
+
213
+ shader_hzb_reduce_mip0.variant(this.#mip0_footprint).dispatchThreads({
214
+ encoder,
215
+ bindings: {
216
+ tInput: source_view,
217
+ tOutput: destination_view,
218
+ settings,
219
+ },
220
+ thread_count_x: mip0_resolution[0],
221
+ thread_count_y: mip0_resolution[1],
222
+ });
223
+
224
+ source_view = destination_view;
225
+
226
+ const steps = this.#steps;
227
+ const step_count = steps.length;
228
+
229
+ for (let s = 0; s < step_count; s++) {
230
+ const { base_mip, mip_count } = steps[s];
231
+
232
+ if (mip_count === 1) {
233
+ const target_mip = base_mip + 1;
234
+ const out_view = this.#obtain_mip_view(target_mip);
235
+
236
+ this.#do_reduction_pass(encoder, shader_hzb_reduce_any, source_view, out_view, target_mip);
237
+
238
+ source_view = out_view;
239
+ } else {
240
+ const out1 = this.#obtain_mip_view(base_mip + 1);
241
+ const out2 = this.#obtain_mip_view(base_mip + 2);
242
+ const out1_res = this.#mip_resolution(base_mip + 1);
243
+ const group_count_x = (out1_res[0] + 15) >>> 4;
244
+ const group_count_y = (out1_res[1] + 15) >>> 4;
245
+
246
+ if (mip_count === 2) {
247
+ shader_hzb_spd_2.dispatch({
248
+ encoder,
249
+ bindings: { tInput: source_view, tOut1: out1, tOut2: out2 },
250
+ group_count_x,
251
+ group_count_y,
252
+ });
253
+ source_view = out2;
254
+ } else if (mip_count === 3) {
255
+ const out3 = this.#obtain_mip_view(base_mip + 3);
256
+ shader_hzb_spd_3.dispatch({
257
+ encoder,
258
+ bindings: { tInput: source_view, tOut1: out1, tOut2: out2, tOut3: out3 },
259
+ group_count_x,
260
+ group_count_y,
261
+ });
262
+ source_view = out3;
263
+ } else {
264
+ const out3 = this.#obtain_mip_view(base_mip + 3);
265
+ const out4 = this.#obtain_mip_view(base_mip + 4);
266
+ shader_hzb_spd_4.dispatch({
267
+ encoder,
268
+ bindings: { tInput: source_view, tOut1: out1, tOut2: out2, tOut3: out3, tOut4: out4 },
269
+ group_count_x,
270
+ group_count_y,
271
+ });
272
+ source_view = out4;
273
+ }
274
+ }
275
+ }
276
+ }
277
+
278
+ /**
279
+ *
280
+ * @param {ShadeGPUCommandContext} encoder
281
+ * @param {ComputeShader} shader
282
+ * @param {GPUTextureView} source_view
283
+ * @param {GPUTextureView} destination_view
284
+ * @param {number} index
285
+ */
286
+ #do_reduction_pass(
287
+ encoder,
288
+ shader,
289
+ source_view,
290
+ destination_view,
291
+ index
292
+ ) {
293
+ const output_resolution = this.#mip_resolution(index);
294
+
295
+ shader.dispatchThreads({
296
+ encoder,
297
+ bindings: {
298
+ tInput: source_view,
299
+ tOutput: destination_view,
300
+ output_resolution,
301
+ },
302
+ thread_count_x: output_resolution[0],
303
+ thread_count_y: output_resolution[1],
304
+ });
305
+
306
+ }
307
+
308
+ /**
309
+ * Scratch for {@link #mip_resolution}. The value is serialised into the pass's immediate bytes
310
+ * before the next call, so one array can serve every mip.
311
+ *
312
+ * @type {number[]}
313
+ */
314
+ #mip_resolution_scratch = [1, 1];
315
+
316
+ /**
317
+ * Size of mip `index` of the HZB, which is what the reduction pass writing into it needs to know.
318
+ *
319
+ * Each mip halves the one above it, floored at one texel — the same walk that used to be
320
+ * precomputed into a uniform buffer of every mip's resolution and bound at a per-mip dynamic
321
+ * offset. As immediate data there is nothing to precompute into.
322
+ *
323
+ * @param {number} index
324
+ * @returns {number[]}
325
+ */
326
+ #mip_resolution(index) {
327
+ const size = this.#texture.size;
328
+
329
+ const out = this.#mip_resolution_scratch;
330
+
331
+ out[0] = max2(1, size[0] >>> index);
332
+ out[1] = max2(1, size[1] >>> index);
333
+
334
+ return out;
335
+ }
336
+
337
+ /**
338
+ *
339
+ * @param {number} x
340
+ * @param {number} y
341
+ */
342
+ setViewportSize(x, y) {
343
+ assert.isNonNegativeInteger(x, 'x');
344
+ assert.isNonNegativeInteger(y, 'y');
345
+ // an empty viewport has no depth to reduce, and mip 0 clamps its reads to a region it would not have
346
+ assert.greaterThan(x, 0, 'x');
347
+ assert.greaterThan(y, 0, 'y');
348
+
349
+ const viewport_size = this.#viewport_size;
350
+
351
+ if (viewport_size[0] === x && viewport_size[1] === y) {
352
+ // no size change; a shadow map's view is resized every frame
353
+ return;
354
+ }
355
+
356
+ viewport_size[0] = x;
357
+ viewport_size[1] = y;
358
+
359
+ const base_w = Math.max(x >>> 1, 1);
360
+ const base_h = Math.max(y >>> 1, 1);
361
+
362
+ const [align_w, align_h] = hzb_pick_alignment(x, y, 1.05);
363
+
364
+ const hzb_w = round_up(base_w, align_w);
365
+ const hzb_h = round_up(base_h, align_h);
366
+
367
+ this.#resize(hzb_w, hzb_h);
368
+
369
+ this.#mip0_footprint = ShaderSwitchSet.EMPTY
370
+ .with(HZB_FOOTPRINT_X, mip0_footprint(x, hzb_w))
371
+ .with(HZB_FOOTPRINT_Y, mip0_footprint(y, hzb_h));
372
+ }
373
+
374
+ /**
375
+ *
376
+ * @param {number} x
377
+ * @param {number} y
378
+ */
379
+ #resize(
380
+ x,
381
+ y
382
+ ) {
383
+
384
+ const texture = this.#texture;
385
+ const size = texture.size;
386
+
387
+ if (size[0] === x && size[1] === y) {
388
+ // no size change
389
+ return;
390
+ }
391
+
392
+ // a screen-space depth pyramid, 2D always
393
+ const mip_count = texture_mip_level_count(x, y, 1, "2d");
394
+
395
+ texture.descriptor.mipLevelCount = mip_count;
396
+
397
+ texture.resize(x, y);
398
+
399
+ this.#steps = hzb_plan_reduction_steps(x, y);
400
+ }
401
+
402
+ destroy() {
403
+ this.#texture.destroy();
404
+ }
405
+ }