@woosh/meep-engine 3.60.4 → 3.60.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/CHANGELOG.md +2621 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts +11 -0
  63. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  64. package/src/shade/renderer/Renderer.js +50 -6
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  67. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  68. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  69. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  70. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  71. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  72. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
  74. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  75. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
  77. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  78. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
  80. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
  82. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  83. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  85. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
  86. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
  88. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  89. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  91. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  92. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  93. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
  94. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
  95. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  111. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  112. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  113. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  114. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  115. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  116. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  117. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  118. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  119. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  120. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  121. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  122. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  123. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  124. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  125. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  126. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  127. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  128. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  129. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  130. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  131. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  136. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  137. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  138. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  139. package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
  140. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  141. package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
  142. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  143. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  144. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  145. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
  146. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  147. package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
  149. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  150. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
  151. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  152. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
  153. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  154. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
  155. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
  156. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
  158. package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
  159. package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
  160. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  161. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  162. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  163. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  164. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  165. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  166. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  168. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  169. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  170. package/src/shade/renderer/water/shader_water.js +22 -13
  171. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  172. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  173. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  174. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  175. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  176. package/editor/REWORK_PLAN_2026_08.md +0 -692
  177. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  178. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  179. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  180. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  181. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  182. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  183. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  184. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  185. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  186. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  187. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  188. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  189. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  190. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  191. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  192. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  193. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  194. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  195. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  196. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  197. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  198. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  199. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  200. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  201. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  202. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  203. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  204. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  205. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  206. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  207. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  208. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  209. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  210. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  211. package/src/REVIEW_2026_08_06/generation.md +0 -176
  212. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  213. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  214. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  215. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  216. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  217. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  218. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  219. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  220. package/src/REVIEW_2026_08_06/view.md +0 -667
  221. package/src/REVIEW_2026_08_06.md +0 -610
  222. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  223. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  224. package/src/core/bvh8/NOTES.md +0 -63
  225. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  226. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  227. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  228. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  229. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  230. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  231. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  232. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  233. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  234. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  235. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  236. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  237. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  238. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  239. package/src/engine/REVIEW_2026_07_03.md +0 -211
  240. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  241. package/src/engine/control/first-person/DESIGN.md +0 -658
  242. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  243. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  244. package/src/engine/control/first-person/TODO.md +0 -160
  245. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  246. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  247. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  248. package/src/engine/ecs/ik/PLAN.md +0 -179
  249. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  250. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  251. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  252. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  253. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  254. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  255. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  256. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  257. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  258. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  259. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  260. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  261. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  262. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  263. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  264. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  265. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  266. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  267. package/src/engine/physics/cloth/PLAN.md +0 -3056
  268. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  269. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  270. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  271. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  272. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  273. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  274. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  275. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  276. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  277. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  278. package/src/format/image/avif/DECISIONS.md +0 -545
  279. package/src/format/image/jpeg/NOTES.md +0 -3
  280. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  281. package/src/generation/COORDINATES.md +0 -54
  282. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  283. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  284. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  285. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  286. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  287. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  288. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  289. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  290. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  291. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  292. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  293. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  294. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  295. package/src/shade/RENDERER_CONTRACT.md +0 -697
  296. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  297. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  298. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  299. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  300. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  301. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  302. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  303. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  304. package/src/shade/renderer/NOTES.md +0 -78
  305. package/src/shade/renderer/PLAN.md +0 -8
  306. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  307. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  308. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  309. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  310. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  311. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  312. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  313. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  314. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  315. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  316. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  317. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  318. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  319. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  320. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  321. package/src/shade/renderer/camera/orbital/README.md +0 -81
  322. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  323. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  324. package/src/shade/renderer/camera/orbital/index.js +0 -9
  325. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  326. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  327. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  328. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  329. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  330. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  331. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  332. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  333. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  334. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  335. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  336. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  337. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  338. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  339. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  340. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  341. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  342. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  343. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
  344. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
  345. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
  346. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
  347. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
  348. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
  349. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
  350. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
  351. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
  352. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
  353. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
  354. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
  355. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  356. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  357. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  358. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  359. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  360. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  361. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  362. package/src/shade/renderer/hiz/NOTES.md +0 -3
  363. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  364. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  365. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  366. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  367. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  368. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  369. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  370. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  371. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  372. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  373. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  374. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  375. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  376. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  377. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  378. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  379. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  380. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  381. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  382. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  383. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  384. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  385. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  386. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  387. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  388. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  389. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  390. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  391. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  392. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  393. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  394. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  395. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  396. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  397. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  398. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  399. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  400. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  401. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  402. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  403. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  404. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  405. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  406. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  407. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  408. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  409. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  410. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  411. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  412. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  413. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  414. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  415. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  416. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  417. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  418. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  419. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,414 +1,429 @@
1
- import { BlendState } from "../../../descriptor/blend/BlendState.js";
2
- import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
3
- import { DEPTH_STENCIL_FOREGROUND_ONLY } from "../../depth/DEPTH_STENCIL_FOREGROUND_ONLY.js";
4
- import { chunk_direction_view_to_world } from "../../shader/chunk/camera/chunk_direction_view_to_world.js";
5
- import { chunk_direction_world_to_view } from "../../shader/chunk/camera/chunk_direction_world_to_view.js";
6
- import { chunk_project_position_from_depth } from "../../shader/chunk/camera/chunk_project_position_from_depth.js";
7
- import { chunk_rgbe9995_encode } from "../../shader/chunk/color/rgbe9995/chunk_rgbe9995_encode.js";
8
- import { chunk_get_view_space_depth } from "../../shader/chunk/depth/chunk_get_view_space_depth.js";
9
- import { chunk_mat4_extract_position } from "../../shader/chunk/geometry/mat4/chunk_mat4_extract_position.js";
10
- import { chunk_decode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_decode_g_buffer_normal.js";
11
- import { chunk_encode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_encode_g_buffer_normal.js";
12
- import { chunk_v3_matrix4_rotate } from "../../shader/chunk/geometry/vec3/chunk_v3_matrix4_rotate.js";
13
- import { chunk_fast_acos } from "../../shader/chunk/math/fast/chunk_fast_acos.js";
14
- import { PI_DECLARATION } from "../../shader/chunk/math/PI_DECLARATION.js";
15
- import { PI_HALF_DECLARATION } from "../../shader/chunk/math/PI_HALF_DECLARATION.js";
16
- import { chunk_spatio_temporal_noise_r2_64 } from "../../shader/chunk/noise/chunk_spatio_temporal_noise_r2_64.js";
17
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
18
- import { ImageShader } from "../../shader/ImageShader.js";
19
- import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
20
- import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
21
- import { HILBERT_R2_INDEX_TEXTURE } from "../../texture/noise/HILBERT_R2_INDEX_TEXTURE.js";
22
- import { BLACK_PIXEL_TEXTURE } from "../../texture/util/BLACK_PIXEL_TEXTURE.js";
23
- import { SAMPLER_NEAREST } from "../../texture/SAMPLER_LINEAR_UPSCALE.js";
24
- import { chunk_is_background } from "../../shader/chunk/depth/chunk_is_background.js";
25
- import { chunk_gtao_compute_mip_level } from "./chunk_gtao_compute_mip_level.js";
26
- import { chunk_gtao_sample_depth } from "./chunk_gtao_sample_depth.js";
27
- import { chunk_integrate_bent_normal_fast } from "./chunk_integrate_bent_normal_fast.js";
28
- import { chunk_horizon_integrate_lighting_sample } from "./chunk_integrate_lighting_sample.js";
29
- import {
30
- GTAO_EFFECT_FALLOFF_RANGE,
31
- GTAO_EFFECT_RADIUS,
32
- GTAO_QUALITY_PROFILES,
33
- GTAO_QUALITY_TYPE
34
- } from "./GTAO_CONSTANTS.js";
35
- import { GTAO_RENDER_SETTINGS } from "./GTAO_RENDER_SETTINGS.js";
36
-
37
- const resources = new ShaderResourceSetDescriptor();
38
-
39
- // see fragment_shader_gtao — the same per-pass settings, carried as immediate data
40
- resources.setImmediate("settings", GTAO_RENDER_SETTINGS);
41
- resources.createGroup()
42
- .addTexture("tDepth")
43
- .addTexture("tHZB")
44
- .addSampler("sPoint", "non-filtering", SAMPLER_NEAREST)
45
- .addTexture("tNormal", "uint")
46
- .addTexture("tColor", "unfilterable-float", "2d", false, BLACK_PIXEL_TEXTURE)
47
- .addTexture("tNoise", "uint", "2d", false, HILBERT_R2_INDEX_TEXTURE)
48
- .addUniform("camera", CAMERA_UNIFORM_STRUCT)
49
- ;
50
-
51
- /**
52
- * One step below the AO-only shader's Medium, because every sample here also integrates incoming
53
- * radiance. A deliberate difference, unlike the ones this fork used to carry by accident.
54
- * @type {{slices:number,steps:number}}
55
- */
56
- const QUALITY_SETTINGS = GTAO_QUALITY_PROFILES[GTAO_QUALITY_TYPE.Low];
57
-
58
- // this is our own thickness heuristic that relies on sooner discarding samples behind the center
59
- const GTAO_DEFAULT_THIN_OCCLUDER_COMPENSATION = 0.0;
60
-
61
- /*
62
- based on https://github.com/GameTechDev/XeGTAO/tree/e7698f874e90f2516fca26c696ec3cd2c70e505a
63
- */
64
- const body = CodeChunk.from(
65
- //language=WGSL
66
- `
67
- const scale = 1.0;
68
-
69
- const thinOccluderCompensation = ${GTAO_DEFAULT_THIN_OCCLUDER_COMPENSATION};
70
-
71
- // small crevices more important than big surfaces
72
- const sampleDistributionPower = 2.0;
73
-
74
- const SLICE_COUNT = ${QUALITY_SETTINGS.slices};
75
-
76
- const STEPS = ${QUALITY_SETTINGS.steps};
77
-
78
- struct Output{
79
- @location(0) visibility: vec2<f32>, // first 2 moment
80
- @location(1) bent_normal: vec2<u32>, // octahedral encoding
81
- @location(2) irradiance: u32, // rgbe9995
82
- }
83
-
84
- @fragment
85
- fn main(
86
- @builtin(position) coord: vec4<f32>,
87
- @location(0) uv: vec2<f32>,
88
- ) -> Output {
89
-
90
- // fadeout precompute optimisation
91
- const falloffRange = ${GTAO_EFFECT_FALLOFF_RANGE} * ${GTAO_EFFECT_RADIUS};
92
-
93
- const falloffFrom = ${GTAO_EFFECT_RADIUS} * (1.0 - ${GTAO_EFFECT_FALLOFF_RANGE});
94
- const falloffMul = -1.0 / ( falloffRange );
95
- const falloffAdd = falloffFrom / ( falloffRange ) + 1.0;
96
-
97
- let texel_position_u32 = vec2<u32>(coord.xy);
98
-
99
- let ViewportSize = textureDimensions(tDepth);
100
- let ViewportPixelSize = 1. / vec2<f32>(ViewportSize);
101
-
102
- var device_depth = textureLoad(tDepth, texel_position_u32, 0).r;
103
-
104
- // NOTE: no need to reject based on depth, already handled via depthStencil
105
-
106
- var viewspaceZ = get_view_space_depth(device_depth, camera);
107
-
108
- // Move center pixel slightly towards camera to avoid imprecision artifacts due to depth buffer imprecision; offset depends on depth texture format used
109
- viewspaceZ *= 0.99999; // this is good for FP32 depth buffer
110
-
111
- let position_ws = project_position_from_depth(uv, device_depth, camera.view_projection_matrix_inverse );
112
- let view_position_ws = mat4_extract_position(camera.view_matrix_inverse);
113
- let view_direction_ws = normalize(view_position_ws - position_ws);
114
-
115
- let view_normal_ws = decode_g_buffer_normal(textureLoad(tNormal, texel_position_u32, 0).xy); // shading normal
116
- let view_normal_vs = direction_world_to_view(view_normal_ws, camera);
117
-
118
- let noiseTexel = spatio_temporal_noise_r2_64(texel_position_u32, settings.frame_index, tNoise);
119
-
120
- let noiseSample = noiseTexel.x;
121
- let noiseSlice = noiseTexel.y;
122
-
123
- // quality settings / tweaks / hacks
124
- const pixelTooCloseThreshold = 1.3; // if the offset is under approx pixel size (pixelTooCloseThreshold), push it out to the minimum distance
125
-
126
- // approx viewspace pixel size at pixCoord; approximation of NDCToViewspace( normalizedScreenPos.xy + consts.ViewportPixelSize.xy, pixCenterPos.z ).xy - pixCenterPos.xy;
127
- // device_depth_to_view_space.z = 1/a = aspect * tan(fovY/2) = tan(fovX/2), pairs with horizontal pixel size.
128
- // factor of 2 converts a single uv-step (= 1 pixel) into the matching ndc-step (range 2 wide).
129
- // This read .w — tan(fovY/2) — with no factor of 2, i.e. 2*aspect too small, 3.56x at 16:9, which
130
- // put every AO sample that much further out than the effect radius asked for.
131
- let NDCToViewMul_x_PixelSize = 2.0 * camera.device_depth_to_view_space.z * ViewportPixelSize.x;
132
- let pixelDirRBViewspaceSizeAtCenterZ = viewspaceZ * NDCToViewMul_x_PixelSize;
133
-
134
- let screenspaceRadius = abs( ${GTAO_EFFECT_RADIUS} / pixelDirRBViewspaceSizeAtCenterZ);
135
-
136
- // fade out for small screen radii
137
- var visibility = 0.0;
138
- var bent_normal:vec3<f32>;
139
- var lighting: vec3<f32>;
140
- var lighting_weight_total = 0.0;
141
-
142
- // this is the min distance to start sampling from to avoid sampling from the center pixel (no useful data obtained from sampling center pixel)
143
- let minS = pixelTooCloseThreshold / screenspaceRadius;
144
-
145
- const INV_SLICE_COUNT = 1.0 / f32(SLICE_COUNT);
146
-
147
- for (var slice = 0; slice < SLICE_COUNT; slice++) {
148
-
149
- let sliceK = ( f32(slice) + noiseSlice ) * INV_SLICE_COUNT;
150
-
151
- // lines 5,6 from the paper
152
- let phi = sliceK * PI; // slice angle
153
-
154
- let cosPhi = cos(phi);
155
- let sinPhi = sin(phi);
156
-
157
- let omega = vec2(cosPhi, -sinPhi) * screenspaceRadius;
158
-
159
- // line 8 from the paper
160
- let sliceViewDir = vec3(cosPhi, sinPhi, 0.0);
161
- let sliceWorldDir = v3_matrix4_rotate(sliceViewDir, camera.view_matrix_inverse);
162
-
163
- // line 9 from the paper
164
- // NOTE: optimized with FMA, readability suffers
165
- let orthoWorldDir = fma( vec3( -dot(sliceWorldDir, view_direction_ws) ), view_direction_ws, sliceWorldDir );
166
-
167
- // line 10 from the paper
168
- // axisVec is orthogonal to sliceViewDir and viewVec, used to define projectedNormal
169
- let axisVec = normalize( cross(orthoWorldDir, view_direction_ws) );
170
-
171
- // line 11 from paper
172
- let projectedWorldNormal = fma( -axisVec, vec3( dot(view_normal_ws, axisVec) ), view_normal_ws );
173
-
174
- // line 13 from the paper
175
- let signNorm = sign( dot( orthoWorldDir, projectedWorldNormal ) );
176
-
177
- // line 14 from the paper
178
- var projectedNormalVecLength = length(projectedWorldNormal);
179
- let norm_cos = saturate( dot( projectedWorldNormal, view_direction_ws ) / projectedNormalVecLength );
180
-
181
- // line 15 from the paper
182
- let n = signNorm * fast_acos(norm_cos);
183
-
184
- // this is a lower weight target; not using -1 as in the original paper because it is under horizon, so a 'weight' has different meaning based on the normal
185
- let lowHorizonCos0 = cos(n + PI_HALF);
186
- let lowHorizonCos1 = -lowHorizonCos0; // cos(n - PI_HALF);
187
-
188
- // lines 17, 18 from the paper, manually unrolled the 'side' loop
189
- var horizonCos0 = lowHorizonCos0; // -1
190
- var horizonCos1 = lowHorizonCos1; // -1
191
-
192
- const INV_STEPS = 1.0 / f32(STEPS);
193
-
194
- // Calculate lighting integrant factors correctly in view space.
195
- let light_integrant_front = 0.5 * vec2(dot(view_normal_vs.xy, sliceViewDir.xy), view_normal_vs.z);
196
- // The back-side integrant has a flipped X component because the slice direction is flipped.
197
- let light_integrant_back = vec2(-light_integrant_front.x, light_integrant_front.y);
198
-
199
- var sliceLighting: vec3<f32>;
200
-
201
- for (var step_index = 0; step_index < STEPS; step_index++) {
202
-
203
- // R1 sequence (http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/)
204
- // Standard multiplier is 0.6180339887498948482 = ( 1 / GOLDEN_RATION )
205
- let stepBaseNoise = f32(slice + step_index * STEPS) * 0.6180339887498948482;
206
-
207
- let stepNoise = fract(noiseSample + stepBaseNoise);
208
-
209
- // approx line 20 from the paper, with added noise
210
- var s = ( f32(step_index) + stepNoise ) * INV_STEPS;
211
-
212
- // additional distribution modifier
213
- s = pow( s, sampleDistributionPower );
214
-
215
- // avoid sampling center pixel
216
- s += minS;
217
-
218
- // approx lines 21-22 from the paper, unrolled
219
- var sampleOffset = s * omega;
220
-
221
- // omega = vec2(cosPhi, -sinPhi) * screenspaceRadius has length screenspaceRadius
222
- let sampleOffsetLength = s * screenspaceRadius;
223
- let mipLevel = gtao_compute_mip_level(sampleOffsetLength);
224
-
225
- // Snap to pixel center (more correct direction math, avoids artifacts due to sampling pos not matching depth texel center - messes up slope - but adds other
226
- // artifacts due to them being pushed off the slice). Also use full precision for high res cases.
227
- sampleOffset = round( sampleOffset ) * ViewportPixelSize;
228
-
229
- let sampleScreenPos0 = uv + sampleOffset;
230
-
231
- let SZ0 = gtao_sample_depth(sampleScreenPos0, mipLevel, camera);
232
- let samplePos0 = project_position_from_depth(sampleScreenPos0, SZ0, camera.view_projection_matrix_inverse);
233
-
234
- let sampleScreenPos1 = uv - sampleOffset;
235
- let SZ1 = gtao_sample_depth(sampleScreenPos1, mipLevel, camera);
236
- let samplePos1 = project_position_from_depth(sampleScreenPos1, SZ1, camera.view_projection_matrix_inverse);
237
-
238
- let sampleDelta0 = (samplePos0 - position_ws); // using lpfloat for sampleDelta causes precision issues
239
- let sampleDelta1 = (samplePos1 - position_ws); // using lpfloat for sampleDelta causes precision issues
240
-
241
- let sampleDist0 = length( sampleDelta0 );
242
- let sampleDist1 = length( sampleDelta1 );
243
-
244
- // approx lines 23, 24 from the paper, unrolled
245
- let sampleHorizonVec0 = sampleDelta0 / sampleDist0;
246
- let sampleHorizonVec1 = sampleDelta1 / sampleDist1;
247
-
248
- let weight0 = saturate( fma(sampleDist0, falloffMul, falloffAdd) );
249
- let weight1 = saturate( fma(sampleDist1, falloffMul, falloffAdd) );
250
-
251
- // sample horizon cos
252
- var shc0 = dot( sampleHorizonVec0, view_direction_ws );
253
- var shc1 = dot( sampleHorizonVec1, view_direction_ws );
254
-
255
- // discard unwanted samples
256
- shc0 = mix( lowHorizonCos0, shc0, weight0 ); // this would be more correct but too expensive: cos(lerp( acos(lowHorizonCos0), acos(shc0), weight0 ));
257
- shc1 = mix( lowHorizonCos1, shc1, weight1 ); // this would be more correct but too expensive: cos(lerp( acos(lowHorizonCos1), acos(shc1), weight1 ));
258
-
259
- if(shc0 > horizonCos0 && !is_background(SZ0) ){
260
-
261
- let s0 = horizon_integrate_lighting_sample(
262
- sampleScreenPos0,
263
- view_normal_ws, // ref_normal
264
- sampleHorizonVec0, // ref_direction
265
- horizonCos0, // h0 (previous horizon)
266
- shc0, // h1 (new horizon)
267
- light_integrant_back
268
- );
269
-
270
- sliceLighting += s0;
271
- }
272
-
273
- if(shc1 > horizonCos1 && !is_background(SZ1) ){
274
-
275
- let s1 = horizon_integrate_lighting_sample(
276
- sampleScreenPos1,
277
- view_normal_ws, // ref_normal
278
- sampleHorizonVec1, // ref_direction
279
- horizonCos1, // h0 (previous horizon)
280
- shc1, // h1 (new horizon)
281
- light_integrant_front
282
- );
283
-
284
- sliceLighting += s1;
285
- }
286
-
287
- // this is a version where thicknessHeuristic is completely disabled
288
- horizonCos0 = max( horizonCos0, shc0 );
289
- horizonCos1 = max( horizonCos1, shc1 );
290
-
291
- }
292
-
293
- // line ~27, unrolled
294
- let h0 = -fast_acos(horizonCos1);
295
- let h1 = fast_acos(horizonCos0);
296
-
297
- let norm_sin = sin(n);
298
- let norm_sin2 = 2.0 * norm_sin;
299
-
300
- let iarc0 = ( fma( h0 , norm_sin2, norm_cos ) - cos( fma( 2.0, h0, - n)) ) * 0.25;
301
- let iarc1 = ( fma( h1 , norm_sin2, norm_cos ) - cos( fma( 2.0, h1, - n)) ) * 0.25;
302
-
303
- // Slight overdarkening on high slopes is compensated by tilting projected length toward 1.
304
- // In the training set, 0.05 is close (PSNR 21.34) to disabled (PSNR 21.45).
305
- // Scoped to the visibility branch so bent normals keep their unfudged slice weighting — this
306
- // used to assign back into projectedNormalVecLength, so the bent-normal accumulation below got
307
- // the fudged weight too.
308
- let visibilityProjLength = mix( projectedNormalVecLength, 1, 0.05 );
309
-
310
- let localVisibility = visibilityProjLength * ( iarc0 + iarc1 );
311
-
312
- visibility += localVisibility;
313
-
314
- // unfudged, like the bent normal below: the fudge corrects the visibility integral only
315
- sliceLighting *= projectedNormalVecLength;
316
-
317
- lighting += sliceLighting;
318
-
319
- // see "Algorithm 2 Extension that computes bent normals b."
320
- let slice_tangent_ws = normalize(orthoWorldDir);
321
- let local_bent_ts = integrate_bent_normal(
322
- horizonCos1,
323
- horizonCos0,
324
- norm_cos,
325
- norm_sin,
326
- );
327
-
328
- let t0 = local_bent_ts.x;
329
- let t1 = local_bent_ts.y;
330
-
331
- var slice_bent_normal_ws = slice_tangent_ws * t0 + view_direction_ws * t1;
332
-
333
- bent_normal = fma(slice_bent_normal_ws, vec3(projectedNormalVecLength), bent_normal);
334
- }
335
-
336
- visibility *= INV_SLICE_COUNT;
337
-
338
- visibility = pow(visibility, scale);
339
-
340
- // disallow total occlusion (which wouldn't make any sense anyhow since pixel is visible but also helps with packing bent normals)
341
- visibility = max(0.03, visibility);
342
-
343
- bent_normal = normalize(bent_normal);
344
-
345
- lighting *= PI * INV_SLICE_COUNT;
346
-
347
- var out: Output;
348
- out.visibility = vec2(visibility, visibility * visibility);
349
- out.bent_normal = encode_g_buffer_normal( bent_normal );
350
- out.irradiance = rgbe9995_encode( lighting );
351
-
352
- return out;
353
- }
354
- `, [
355
- chunk_get_view_space_depth,
356
- PI_DECLARATION,
357
- PI_HALF_DECLARATION,
358
-
359
- chunk_decode_g_buffer_normal,
360
- chunk_encode_g_buffer_normal,
361
- chunk_spatio_temporal_noise_r2_64,
362
-
363
- chunk_fast_acos,
364
-
365
- chunk_direction_world_to_view,
366
- chunk_direction_view_to_world,
367
- chunk_is_background,
368
- chunk_mat4_extract_position,
369
- chunk_project_position_from_depth,
370
- chunk_v3_matrix4_rotate,
371
- chunk_integrate_bent_normal_fast,
372
- chunk_gtao_compute_mip_level,
373
- chunk_gtao_sample_depth,
374
-
375
- //
376
- chunk_rgbe9995_encode,
377
- chunk_horizon_integrate_lighting_sample,
378
- ]);
379
-
380
- export const fragment_shader_gtao_with_irradiance = new ImageShader({
381
- descriptor: ShaderDescriptor.from(
382
- {
383
- label: "GTAO",
384
- resources,
385
- body
386
- },
387
- ),
388
- depthStencil: DEPTH_STENCIL_FOREGROUND_ONLY,
389
- targets: [
390
- {
391
- label: "Occlusion",
392
- // first 2 moments of visibility
393
- format: "rg16float",
394
- clearValue: [1, 1], // Stores visibility, so 1 == not occluded
395
- blend: BlendState.from({
396
- color: {
397
- operation: "add",
398
- srcFactor: "one",
399
- dstFactor: "zero",
400
- }
401
- })
402
- },
403
- {
404
- label: "Bent Normals",
405
- // Direction is encoded with octahedral
406
- format: "rg16uint",
407
- },
408
- {
409
- label: "Irradiance",
410
- // encoded as RGBE9995
411
- format:"r32uint"
412
- }
413
- ]
414
- });
1
+ import { BlendState } from "../../../descriptor/blend/BlendState.js";
2
+ import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
3
+ import { DEPTH_STENCIL_FOREGROUND_ONLY } from "../../depth/DEPTH_STENCIL_FOREGROUND_ONLY.js";
4
+ import { chunk_direction_view_to_world } from "../../shader/chunk/camera/chunk_direction_view_to_world.js";
5
+ import { chunk_project_position_from_depth } from "../../shader/chunk/camera/chunk_project_position_from_depth.js";
6
+ import { chunk_rgbe9995_encode } from "../../shader/chunk/color/rgbe9995/chunk_rgbe9995_encode.js";
7
+ import { chunk_get_view_space_depth } from "../../shader/chunk/depth/chunk_get_view_space_depth.js";
8
+ import { chunk_mat4_extract_position } from "../../shader/chunk/geometry/mat4/chunk_mat4_extract_position.js";
9
+ import { chunk_decode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_decode_g_buffer_normal.js";
10
+ import { chunk_encode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_encode_g_buffer_normal.js";
11
+ import { chunk_v3_matrix4_rotate } from "../../shader/chunk/geometry/vec3/chunk_v3_matrix4_rotate.js";
12
+ import { chunk_fast_acos } from "../../shader/chunk/math/fast/chunk_fast_acos.js";
13
+ import { PI_DECLARATION } from "../../shader/chunk/math/PI_DECLARATION.js";
14
+ import { PI_HALF_DECLARATION } from "../../shader/chunk/math/PI_HALF_DECLARATION.js";
15
+ import { chunk_spatio_temporal_noise_r2_64 } from "../../shader/chunk/noise/chunk_spatio_temporal_noise_r2_64.js";
16
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
17
+ import { ImageShader } from "../../shader/ImageShader.js";
18
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
19
+ import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
20
+ import { HILBERT_R2_INDEX_TEXTURE } from "../../texture/noise/HILBERT_R2_INDEX_TEXTURE.js";
21
+ import { BLACK_PIXEL_TEXTURE } from "../../texture/util/BLACK_PIXEL_TEXTURE.js";
22
+ import { SAMPLER_NEAREST } from "../../texture/SAMPLER_LINEAR_UPSCALE.js";
23
+ import { chunk_is_background } from "../../shader/chunk/depth/chunk_is_background.js";
24
+ import { chunk_gtao_compute_mip_level } from "./chunk_gtao_compute_mip_level.js";
25
+ import { chunk_gtao_sample_depth } from "./chunk_gtao_sample_depth.js";
26
+ import { chunk_integrate_bent_normal_fast } from "./chunk_integrate_bent_normal_fast.js";
27
+ import { chunk_horizon_integrate_lighting_sample } from "./chunk_integrate_lighting_sample.js";
28
+ import {
29
+ GTAO_EFFECT_FALLOFF_RANGE,
30
+ GTAO_EFFECT_RADIUS,
31
+ GTAO_QUALITY_PROFILES,
32
+ GTAO_QUALITY_TYPE
33
+ } from "./GTAO_CONSTANTS.js";
34
+ import { GTAO_RENDER_SETTINGS } from "./GTAO_RENDER_SETTINGS.js";
35
+
36
+ const resources = new ShaderResourceSetDescriptor();
37
+
38
+ // see fragment_shader_gtao — the same per-pass settings, carried as immediate data
39
+ resources.setImmediate("settings", GTAO_RENDER_SETTINGS);
40
+ resources.createGroup()
41
+ .addTexture("tDepth")
42
+ .addTexture("tHZB")
43
+ .addSampler("sPoint", "non-filtering", SAMPLER_NEAREST)
44
+ .addTexture("tNormal", "uint")
45
+ .addTexture("tColor", "unfilterable-float", "2d", false, BLACK_PIXEL_TEXTURE)
46
+ .addTexture("tNoise", "uint", "2d", false, HILBERT_R2_INDEX_TEXTURE)
47
+ .addUniform("camera", CAMERA_UNIFORM_STRUCT)
48
+ ;
49
+
50
+ /**
51
+ * One step below the AO-only shader's Medium, because every sample here also integrates incoming
52
+ * radiance. A deliberate difference, unlike the ones this fork used to carry by accident.
53
+ * @type {{slices:number,steps:number}}
54
+ */
55
+ const QUALITY_SETTINGS = GTAO_QUALITY_PROFILES[GTAO_QUALITY_TYPE.Low];
56
+
57
+ // this is our own thickness heuristic that relies on sooner discarding samples behind the center
58
+ const GTAO_DEFAULT_THIN_OCCLUDER_COMPENSATION = 0.0;
59
+
60
+ /*
61
+ based on https://github.com/GameTechDev/XeGTAO/tree/e7698f874e90f2516fca26c696ec3cd2c70e505a
62
+ */
63
+ const body = CodeChunk.from(
64
+ //language=WGSL
65
+ `
66
+ const scale = 1.0;
67
+
68
+ const thinOccluderCompensation = ${GTAO_DEFAULT_THIN_OCCLUDER_COMPENSATION};
69
+
70
+ // small crevices more important than big surfaces
71
+ const sampleDistributionPower = 2.0;
72
+
73
+ const SLICE_COUNT = ${QUALITY_SETTINGS.slices};
74
+
75
+ const STEPS = ${QUALITY_SETTINGS.steps};
76
+
77
+ struct Output{
78
+ @location(0) visibility: vec2<f32>, // first 2 moment
79
+ @location(1) bent_normal: vec2<u32>, // octahedral encoding
80
+ @location(2) irradiance: u32, // rgbe9995
81
+ }
82
+
83
+ @fragment
84
+ fn main(
85
+ @builtin(position) coord: vec4<f32>,
86
+ @location(0) uv: vec2<f32>,
87
+ ) -> Output {
88
+
89
+ // fadeout precompute optimisation
90
+ const falloffRange = ${GTAO_EFFECT_FALLOFF_RANGE} * ${GTAO_EFFECT_RADIUS};
91
+
92
+ const falloffFrom = ${GTAO_EFFECT_RADIUS} * (1.0 - ${GTAO_EFFECT_FALLOFF_RANGE});
93
+ const falloffMul = -1.0 / ( falloffRange );
94
+ const falloffAdd = falloffFrom / ( falloffRange ) + 1.0;
95
+
96
+ let texel_position_u32 = vec2<u32>(coord.xy);
97
+
98
+ let ViewportSize = textureDimensions(tDepth);
99
+ let ViewportPixelSize = 1. / vec2<f32>(ViewportSize);
100
+
101
+ var device_depth = textureLoad(tDepth, texel_position_u32, 0).r;
102
+
103
+ // NOTE: no need to reject based on depth, already handled via depthStencil
104
+
105
+ var viewspaceZ = get_view_space_depth(device_depth, camera);
106
+
107
+ // Move center pixel slightly towards camera to avoid imprecision artifacts due to depth buffer imprecision; offset depends on depth texture format used
108
+ viewspaceZ *= 0.99999; // this is good for FP32 depth buffer
109
+
110
+ let position_ws = project_position_from_depth(uv, device_depth, camera.view_projection_matrix_inverse );
111
+ let view_position_ws = mat4_extract_position(camera.view_matrix_inverse);
112
+ let view_direction_ws = normalize(view_position_ws - position_ws);
113
+
114
+ let view_normal_ws = decode_g_buffer_normal(textureLoad(tNormal, texel_position_u32, 0).xy); // shading normal
115
+
116
+ let noiseTexel = spatio_temporal_noise_r2_64(texel_position_u32, settings.frame_index, tNoise);
117
+
118
+ let noiseSample = noiseTexel.x;
119
+ let noiseSlice = noiseTexel.y;
120
+
121
+ // quality settings / tweaks / hacks
122
+ const pixelTooCloseThreshold = 1.3; // if the offset is under approx pixel size (pixelTooCloseThreshold), push it out to the minimum distance
123
+
124
+ // approx viewspace pixel size at pixCoord; approximation of NDCToViewspace( normalizedScreenPos.xy + consts.ViewportPixelSize.xy, pixCenterPos.z ).xy - pixCenterPos.xy;
125
+ // device_depth_to_view_space.z = 1/a = aspect * tan(fovY/2) = tan(fovX/2), pairs with horizontal pixel size.
126
+ // factor of 2 converts a single uv-step (= 1 pixel) into the matching ndc-step (range 2 wide).
127
+ // This read .w — tan(fovY/2) — with no factor of 2, i.e. 2*aspect too small, 3.56x at 16:9, which
128
+ // put every AO sample that much further out than the effect radius asked for.
129
+ let NDCToViewMul_x_PixelSize = 2.0 * camera.device_depth_to_view_space.z * ViewportPixelSize.x;
130
+ let pixelDirRBViewspaceSizeAtCenterZ = viewspaceZ * NDCToViewMul_x_PixelSize;
131
+
132
+ let screenspaceRadius = abs( ${GTAO_EFFECT_RADIUS} / pixelDirRBViewspaceSizeAtCenterZ);
133
+
134
+ // fade out for small screen radii
135
+ var visibility = 0.0;
136
+ var bent_normal:vec3<f32>;
137
+ var lighting: vec3<f32>;
138
+ var lighting_weight_total = 0.0;
139
+
140
+ // this is the min distance to start sampling from to avoid sampling from the center pixel (no useful data obtained from sampling center pixel)
141
+ let minS = pixelTooCloseThreshold / screenspaceRadius;
142
+
143
+ // The slices' angle is measured around the view ray, from the camera's right made perpendicular to it: at
144
+ // the screen's centre that is the screen's own x, as the paper has it. The ray never runs along it inside a
145
+ // frustum. See fragment_shader_gtao, which this follows in world space.
146
+ let camera_right_ws = v3_matrix4_rotate(vec3(1.0, 0.0, 0.0), camera.view_matrix_inverse);
147
+ let slice_basis_x = normalize(fma(vec3(-dot(camera_right_ws, view_direction_ws)), view_direction_ws, camera_right_ws));
148
+ let slice_basis_y = cross(view_direction_ws, slice_basis_x);
149
+
150
+ let center_clip = camera.view_projection_matrix * vec4(position_ws, 1.0);
151
+
152
+ const INV_SLICE_COUNT = 1.0 / f32(SLICE_COUNT);
153
+
154
+ for (var slice = 0; slice < SLICE_COUNT; slice++) {
155
+
156
+ let sliceK = ( f32(slice) + noiseSlice ) * INV_SLICE_COUNT;
157
+
158
+ // lines 5,6 from the paper
159
+ let phi = sliceK * PI; // slice angle
160
+
161
+ let cosPhi = cos(phi);
162
+ let sinPhi = sin(phi);
163
+
164
+ // line 8 from the paper, with phi the slice's angle around this texel's own view ray: the integrals below
165
+ // are written in that angle. The paper takes phi on screen, which is the same angle only at the screen's
166
+ // centre; off it, slices spread evenly on screen bunch around the view ray, the two of a frame stop
167
+ // cancelling, and an open plane's bent normal leans by degrees towards the screen's edges.
168
+ let sliceWorldDir = cosPhi * slice_basis_x + sinPhi * slice_basis_y;
169
+
170
+ // The slice's plane holds the view ray, so on screen it is a line through this texel, along the
171
+ // projection's derivative in the slice's direction: (d(clip.xy) * clip.w - clip.xy * d(clip.w)) / clip.w^2,
172
+ // its scale dropped, into uv and then pixels.
173
+ let slice_clip = camera.view_projection_matrix * vec4(sliceWorldDir, 0.0);
174
+ let slice_screen = (slice_clip.xy * center_clip.w - center_clip.xy * slice_clip.w) * vec2(0.5, -0.5) * vec2<f32>(ViewportSize);
175
+ let omega = normalize(slice_screen) * screenspaceRadius;
176
+
177
+ // line 9 from the paper
178
+ // NOTE: optimized with FMA, readability suffers
179
+ let orthoWorldDir = fma( vec3( -dot(sliceWorldDir, view_direction_ws) ), view_direction_ws, sliceWorldDir );
180
+
181
+ // line 10 from the paper
182
+ // axisVec is orthogonal to sliceViewDir and viewVec, used to define projectedNormal
183
+ let axisVec = normalize( cross(orthoWorldDir, view_direction_ws) );
184
+
185
+ // line 11 from paper
186
+ let projectedWorldNormal = fma( -axisVec, vec3( dot(view_normal_ws, axisVec) ), view_normal_ws );
187
+
188
+ // line 13 from the paper
189
+ let signNorm = sign( dot( orthoWorldDir, projectedWorldNormal ) );
190
+
191
+ // line 14 from the paper
192
+ var projectedNormalVecLength = length(projectedWorldNormal);
193
+ let norm_cos = saturate( dot( projectedWorldNormal, view_direction_ws ) / projectedNormalVecLength );
194
+
195
+ // line 15 from the paper
196
+ let n = signNorm * fast_acos(norm_cos);
197
+
198
+ // this is a lower weight target; not using -1 as in the original paper because it is under horizon, so a 'weight' has different meaning based on the normal
199
+ let lowHorizonCos0 = cos(n + PI_HALF);
200
+ let lowHorizonCos1 = -lowHorizonCos0; // cos(n - PI_HALF);
201
+
202
+ // lines 17, 18 from the paper, manually unrolled the 'side' loop
203
+ var horizonCos0 = lowHorizonCos0; // -1
204
+ var horizonCos1 = lowHorizonCos1; // -1
205
+
206
+ const INV_STEPS = 1.0 / f32(STEPS);
207
+
208
+ // The lighting integrant's factors, in the slice's own frame: a direction in it is
209
+ // cos(theta) * view + sin(theta) * tangent, so N.w splits into N.tangent and N.view. At the screen's
210
+ // centre that is the view-space N.xy along the slice and N.z this read before the slices followed the ray.
211
+ let slice_tangent_ws = normalize(orthoWorldDir);
212
+ let light_integrant_front = 0.5 * vec2(dot(view_normal_ws, slice_tangent_ws), dot(view_normal_ws, view_direction_ws));
213
+ // The back-side integrant has a flipped X component because the slice direction is flipped.
214
+ let light_integrant_back = vec2(-light_integrant_front.x, light_integrant_front.y);
215
+
216
+ var sliceLighting: vec3<f32>;
217
+
218
+ for (var step_index = 0; step_index < STEPS; step_index++) {
219
+
220
+ // R1 sequence (http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/)
221
+ // Standard multiplier is 0.6180339887498948482 = ( 1 / GOLDEN_RATION )
222
+ let stepBaseNoise = f32(slice + step_index * STEPS) * 0.6180339887498948482;
223
+
224
+ let stepNoise = fract(noiseSample + stepBaseNoise);
225
+
226
+ // approx line 20 from the paper, with added noise
227
+ var s = ( f32(step_index) + stepNoise ) * INV_STEPS;
228
+
229
+ // additional distribution modifier
230
+ s = pow( s, sampleDistributionPower );
231
+
232
+ // avoid sampling center pixel
233
+ s += minS;
234
+
235
+ // approx lines 21-22 from the paper, unrolled
236
+ var sampleOffset = s * omega;
237
+
238
+ // omega is a unit screen direction times screenspaceRadius, so has length screenspaceRadius
239
+ let sampleOffsetLength = s * screenspaceRadius;
240
+ let mipLevel = gtao_compute_mip_level(sampleOffsetLength);
241
+
242
+ // Snap to pixel center (more correct direction math, avoids artifacts due to sampling pos not matching depth texel center - messes up slope - but adds other
243
+ // artifacts due to them being pushed off the slice). Also use full precision for high res cases.
244
+ sampleOffset = round( sampleOffset ) * ViewportPixelSize;
245
+
246
+ let sampleScreenPos0 = uv + sampleOffset;
247
+
248
+ let SZ0 = gtao_sample_depth(sampleScreenPos0, mipLevel, camera);
249
+ let samplePos0 = project_position_from_depth(sampleScreenPos0, SZ0, camera.view_projection_matrix_inverse);
250
+
251
+ let sampleScreenPos1 = uv - sampleOffset;
252
+ let SZ1 = gtao_sample_depth(sampleScreenPos1, mipLevel, camera);
253
+ let samplePos1 = project_position_from_depth(sampleScreenPos1, SZ1, camera.view_projection_matrix_inverse);
254
+
255
+ let sampleDelta0 = (samplePos0 - position_ws); // using lpfloat for sampleDelta causes precision issues
256
+ let sampleDelta1 = (samplePos1 - position_ws); // using lpfloat for sampleDelta causes precision issues
257
+
258
+ let sampleDist0 = length( sampleDelta0 );
259
+ let sampleDist1 = length( sampleDelta1 );
260
+
261
+ // approx lines 23, 24 from the paper, unrolled
262
+ let sampleHorizonVec0 = sampleDelta0 / sampleDist0;
263
+ let sampleHorizonVec1 = sampleDelta1 / sampleDist1;
264
+
265
+ let weight0 = saturate( fma(sampleDist0, falloffMul, falloffAdd) );
266
+ let weight1 = saturate( fma(sampleDist1, falloffMul, falloffAdd) );
267
+
268
+ // sample horizon cos
269
+ var shc0 = dot( sampleHorizonVec0, view_direction_ws );
270
+ var shc1 = dot( sampleHorizonVec1, view_direction_ws );
271
+
272
+ // discard unwanted samples
273
+ shc0 = mix( lowHorizonCos0, shc0, weight0 ); // this would be more correct but too expensive: cos(lerp( acos(lowHorizonCos0), acos(shc0), weight0 ));
274
+ shc1 = mix( lowHorizonCos1, shc1, weight1 ); // this would be more correct but too expensive: cos(lerp( acos(lowHorizonCos1), acos(shc1), weight1 ));
275
+
276
+ if(shc0 > horizonCos0 && !is_background(SZ0) ){
277
+
278
+ let s0 = horizon_integrate_lighting_sample(
279
+ sampleScreenPos0,
280
+ view_normal_ws, // ref_normal
281
+ sampleHorizonVec0, // ref_direction
282
+ horizonCos0, // h0 (previous horizon)
283
+ shc0, // h1 (new horizon)
284
+ light_integrant_back
285
+ );
286
+
287
+ sliceLighting += s0;
288
+ }
289
+
290
+ if(shc1 > horizonCos1 && !is_background(SZ1) ){
291
+
292
+ let s1 = horizon_integrate_lighting_sample(
293
+ sampleScreenPos1,
294
+ view_normal_ws, // ref_normal
295
+ sampleHorizonVec1, // ref_direction
296
+ horizonCos1, // h0 (previous horizon)
297
+ shc1, // h1 (new horizon)
298
+ light_integrant_front
299
+ );
300
+
301
+ sliceLighting += s1;
302
+ }
303
+
304
+ // this is a version where thicknessHeuristic is completely disabled
305
+ horizonCos0 = max( horizonCos0, shc0 );
306
+ horizonCos1 = max( horizonCos1, shc1 );
307
+
308
+ }
309
+
310
+ // line ~27, unrolled
311
+ let h0 = -fast_acos(horizonCos1);
312
+ let h1 = fast_acos(horizonCos0);
313
+
314
+ let norm_sin = sin(n);
315
+ let norm_sin2 = 2.0 * norm_sin;
316
+
317
+ let iarc0 = ( fma( h0 , norm_sin2, norm_cos ) - cos( fma( 2.0, h0, - n)) ) * 0.25;
318
+ let iarc1 = ( fma( h1 , norm_sin2, norm_cos ) - cos( fma( 2.0, h1, - n)) ) * 0.25;
319
+
320
+ // Slight overdarkening on high slopes is compensated by tilting projected length toward 1.
321
+ // In the training set, 0.05 is close (PSNR 21.34) to disabled (PSNR 21.45).
322
+ // Scoped to the visibility branch so bent normals keep their unfudged slice weighting — this
323
+ // used to assign back into projectedNormalVecLength, so the bent-normal accumulation below got
324
+ // the fudged weight too.
325
+ let visibilityProjLength = mix( projectedNormalVecLength, 1, 0.05 );
326
+
327
+ let localVisibility = visibilityProjLength * ( iarc0 + iarc1 );
328
+
329
+ visibility += localVisibility;
330
+
331
+ // unfudged, like the bent normal below: the fudge corrects the visibility integral only
332
+ sliceLighting *= projectedNormalVecLength;
333
+
334
+ lighting += sliceLighting;
335
+
336
+ // see "Algorithm 2 Extension that computes bent normals b."
337
+ let local_bent_ts = integrate_bent_normal(
338
+ horizonCos1,
339
+ horizonCos0,
340
+ norm_cos,
341
+ norm_sin,
342
+ );
343
+
344
+ let t0 = local_bent_ts.x;
345
+ let t1 = local_bent_ts.y;
346
+
347
+ var slice_bent_normal_ws = slice_tangent_ws * t0 + view_direction_ws * t1;
348
+
349
+ bent_normal = fma(slice_bent_normal_ws, vec3(projectedNormalVecLength), bent_normal);
350
+ }
351
+
352
+ visibility *= INV_SLICE_COUNT;
353
+
354
+ visibility = pow(visibility, scale);
355
+
356
+ // disallow total occlusion (which wouldn't make any sense anyhow since pixel is visible but also helps with packing bent normals)
357
+ visibility = max(0.03, visibility);
358
+
359
+ bent_normal = normalize(bent_normal);
360
+
361
+ lighting *= PI * INV_SLICE_COUNT;
362
+
363
+ var out: Output;
364
+ out.visibility = vec2(visibility, visibility * visibility);
365
+ out.bent_normal = encode_g_buffer_normal( bent_normal );
366
+ out.irradiance = rgbe9995_encode( lighting );
367
+
368
+ return out;
369
+ }
370
+ `, [
371
+ chunk_get_view_space_depth,
372
+ PI_DECLARATION,
373
+ PI_HALF_DECLARATION,
374
+
375
+ chunk_decode_g_buffer_normal,
376
+ chunk_encode_g_buffer_normal,
377
+ chunk_spatio_temporal_noise_r2_64,
378
+
379
+ chunk_fast_acos,
380
+
381
+ chunk_direction_view_to_world,
382
+ chunk_is_background,
383
+ chunk_mat4_extract_position,
384
+ chunk_project_position_from_depth,
385
+ chunk_v3_matrix4_rotate,
386
+ chunk_integrate_bent_normal_fast,
387
+ chunk_gtao_compute_mip_level,
388
+ chunk_gtao_sample_depth,
389
+
390
+ //
391
+ chunk_rgbe9995_encode,
392
+ chunk_horizon_integrate_lighting_sample,
393
+ ]);
394
+
395
+ export const fragment_shader_gtao_with_irradiance = new ImageShader({
396
+ descriptor: ShaderDescriptor.from(
397
+ {
398
+ label: "GTAO",
399
+ resources,
400
+ body
401
+ },
402
+ ),
403
+ depthStencil: DEPTH_STENCIL_FOREGROUND_ONLY,
404
+ targets: [
405
+ {
406
+ label: "Occlusion",
407
+ // first 2 moments of visibility
408
+ format: "rg16float",
409
+ clearValue: [1, 1], // Stores visibility, so 1 == not occluded
410
+ blend: BlendState.from({
411
+ color: {
412
+ operation: "add",
413
+ srcFactor: "one",
414
+ dstFactor: "zero",
415
+ }
416
+ })
417
+ },
418
+ {
419
+ label: "Bent Normals",
420
+ // Direction is encoded with octahedral
421
+ format: "rg16uint",
422
+ },
423
+ {
424
+ label: "Irradiance",
425
+ // encoded as RGBE9995
426
+ format:"r32uint"
427
+ }
428
+ ]
429
+ });