@woosh/meep-engine 3.53.0 → 3.55.0

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 (249) hide show
  1. package/package.json +1 -1
  2. package/src/core/math/noise/worley_noise_2d.d.ts +14 -0
  3. package/src/core/math/noise/worley_noise_2d.d.ts.map +1 -0
  4. package/src/core/math/noise/worley_noise_2d.js +74 -0
  5. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts +6 -1
  6. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts.map +1 -1
  7. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.js +363 -325
  8. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.d.ts +93 -14
  9. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.d.ts.map +1 -1
  10. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.js +322 -183
  11. package/src/engine/graphics/texture/atlas/ReferencedTextureAtlas.d.ts +9 -0
  12. package/src/engine/graphics/texture/atlas/ReferencedTextureAtlas.d.ts.map +1 -1
  13. package/src/engine/graphics/texture/atlas/ReferencedTextureAtlas.js +110 -83
  14. package/src/engine/graphics/texture/atlas/SpriteAtlas.d.ts +42 -0
  15. package/src/engine/graphics/texture/atlas/SpriteAtlas.d.ts.map +1 -0
  16. package/src/engine/{graphics3/decal/DecalAtlas.js → graphics/texture/atlas/SpriteAtlas.js} +202 -194
  17. package/src/engine/{graphics3/decal/DecalAtlasFill.d.ts → graphics/texture/atlas/SpriteAtlasFill.d.ts} +4 -4
  18. package/src/engine/graphics/texture/atlas/SpriteAtlasFill.d.ts.map +1 -0
  19. package/src/engine/graphics/texture/atlas/SpriteAtlasFill.js +30 -0
  20. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts +7 -0
  21. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
  22. package/src/engine/graphics/texture/atlas/TextureAtlas.js +11 -1
  23. package/src/engine/{graphics3/decal/decal_atlas_border.d.ts → graphics/texture/atlas/sprite_atlas_border.d.ts} +12 -12
  24. package/src/engine/graphics/texture/atlas/sprite_atlas_border.d.ts.map +1 -0
  25. package/src/engine/{graphics3/decal/decal_atlas_border.js → graphics/texture/atlas/sprite_atlas_border.js} +69 -69
  26. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  27. package/src/engine/graphics3/DecalSystem.js +447 -450
  28. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +9 -22
  29. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  30. package/src/engine/graphics3/GPUParticleEmitterSystem.js +892 -951
  31. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  32. package/src/generation/foliage/FOLIAGE_DESIGN.md +2 -1
  33. package/src/generation/foliage/config/BarkMaterialConfig.d.ts +4 -3
  34. package/src/generation/foliage/config/BarkMaterialConfig.d.ts.map +1 -1
  35. package/src/generation/foliage/config/BarkMaterialConfig.js +6 -6
  36. package/src/generation/foliage/config/FoliageBarkType.d.ts +11 -0
  37. package/src/generation/foliage/config/FoliageBarkType.d.ts.map +1 -0
  38. package/src/generation/foliage/config/FoliageBarkType.js +16 -0
  39. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts +58 -5
  40. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts.map +1 -1
  41. package/src/generation/foliage/config/FoliageMaterialConfig.js +279 -181
  42. package/src/generation/foliage/index.d.ts +2 -1
  43. package/src/generation/foliage/index.js +44 -43
  44. package/src/generation/foliage/material/make_bark_material.d.ts.map +1 -1
  45. package/src/generation/foliage/material/make_bark_material.js +23 -95
  46. package/src/generation/foliage/material/make_foliage_material.d.ts +29 -3
  47. package/src/generation/foliage/material/make_foliage_material.d.ts.map +1 -1
  48. package/src/generation/foliage/material/make_foliage_material.js +605 -359
  49. package/src/generation/foliage/mesh/branch_collar_project.d.ts.map +1 -1
  50. package/src/generation/foliage/mesh/branch_collar_project.js +205 -203
  51. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts +15 -0
  52. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts.map +1 -1
  53. package/src/generation/foliage/mesh/foliage_collect_attachments.js +569 -502
  54. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  55. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +1049 -1047
  56. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts +2 -1
  57. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts.map +1 -1
  58. package/src/generation/foliage/mesh/tree_mesh_build_foliage.js +454 -415
  59. package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
  60. package/src/generation/foliage/presets/make_tree_species_preset.js +870 -837
  61. package/src/generation/foliage/skeleton/crown_envelope_evaluate.js +121 -121
  62. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts +10 -7
  63. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts.map +1 -1
  64. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js +206 -179
  65. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
  66. package/src/generation/foliage/skeleton/tree_skeleton_grow.js +1871 -1104
  67. package/src/shade/RENDERER_CONTRACT.md +5 -2
  68. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts.map +1 -1
  69. package/src/shade/device/SHADE_DEVICE_FLOOR.js +2 -0
  70. package/src/shade/playground/foliage_wind/foliage_world.d.ts +6 -0
  71. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  72. package/src/shade/playground/foliage_wind/foliage_world.js +602 -593
  73. package/src/shade/playground/foliage_wind/index.html +260 -254
  74. package/src/shade/playground/foliage_wind/main.js +275 -263
  75. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  76. package/src/shade/renderer/Renderer.js +1 -1
  77. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  78. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  79. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  80. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  81. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  82. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +1 -1
  83. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +3 -3
  84. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  85. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +350 -294
  86. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts +0 -2
  87. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts.map +1 -1
  88. package/src/shade/renderer/hiz/generate_downsampler_code.js +99 -100
  89. package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts +15 -0
  90. package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts.map +1 -0
  91. package/src/shade/renderer/hiz/hzb_pick_alignment.js +148 -0
  92. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.d.ts +28 -0
  93. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.d.ts.map +1 -0
  94. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.js +58 -0
  95. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +5 -5
  96. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  97. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +57 -67
  98. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +3 -3
  99. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
  100. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +111 -112
  101. package/src/shade/renderer/hiz/shader_hzb_spd.d.ts +5 -0
  102. package/src/shade/renderer/hiz/shader_hzb_spd.d.ts.map +1 -0
  103. package/src/shade/renderer/hiz/shader_hzb_spd.js +160 -0
  104. package/src/shade/renderer/light/GPULightCollection.d.ts +8 -0
  105. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  106. package/src/shade/renderer/light/GPULightCollection.js +67 -0
  107. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.d.ts +7 -0
  108. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.d.ts.map +1 -0
  109. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.js +13 -0
  110. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.d.ts +10 -0
  111. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.d.ts.map +1 -0
  112. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.js +72 -0
  113. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts +39 -0
  114. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts.map +1 -0
  115. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.js +90 -0
  116. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts +12 -0
  117. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts.map +1 -0
  118. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.js +56 -0
  119. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts +31 -0
  120. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts.map +1 -0
  121. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.js +196 -0
  122. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts +10 -0
  123. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts.map +1 -0
  124. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js +163 -0
  125. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.d.ts +4 -0
  126. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.d.ts.map +1 -0
  127. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.js +137 -0
  128. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  130. package/src/shade/renderer/particles/GPUParticleSystem.js +4 -3
  131. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +4 -3
  132. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  133. package/src/shade/renderer/particles/graph_particles_avboit.js +28 -11
  134. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +9 -13
  135. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
  136. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +25 -20
  137. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  138. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +21 -38
  139. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.d.ts.map +1 -1
  140. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +154 -147
  141. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +2 -1
  142. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  143. package/src/shade/renderer/postprocess/gtao/GTAO.js +5 -1
  144. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.d.ts +8 -0
  145. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.d.ts.map +1 -1
  146. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.js +10 -1
  147. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +5 -0
  149. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.d.ts +22 -0
  150. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.d.ts.map +1 -0
  151. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.js +33 -0
  152. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.d.ts +22 -0
  153. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.d.ts.map +1 -0
  154. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.js +56 -0
  155. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.d.ts +13 -0
  156. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.js +42 -0
  158. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts +2 -1
  159. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  160. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +382 -357
  161. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  162. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +414 -410
  163. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  164. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -7
  165. package/src/shade/renderer/shader/chunk/depth/chunk_query_depth_from_screen_space_bb.d.ts.map +1 -1
  166. package/src/shade/renderer/shader/chunk/depth/chunk_query_depth_from_screen_space_bb.js +62 -62
  167. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.d.ts +6 -0
  168. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.d.ts.map +1 -0
  169. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.js +19 -0
  170. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_get_mip_resolution.d.ts.map +1 -1
  171. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_get_mip_resolution.js +16 -10
  172. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.d.ts.map +1 -1
  173. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.js +118 -117
  174. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +41 -7
  175. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -1
  176. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +162 -58
  177. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +1 -1
  178. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +10 -12
  179. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  180. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +583 -606
  181. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +1 -1
  182. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +640 -640
  183. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +113 -0
  184. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -0
  185. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +484 -0
  186. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts +50 -0
  187. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts.map +1 -0
  188. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.js +60 -0
  189. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts +25 -0
  190. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts.map +1 -0
  191. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.js +47 -0
  192. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.d.ts +74 -0
  193. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.d.ts.map +1 -0
  194. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.js +173 -0
  195. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +26 -0
  196. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -0
  197. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +83 -0
  198. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts +36 -0
  199. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts.map +1 -0
  200. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.js +129 -0
  201. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts +121 -0
  202. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts.map +1 -0
  203. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js +370 -0
  204. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts +16 -0
  205. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts.map +1 -0
  206. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.js +191 -0
  207. package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
  208. package/src/shade/renderer/wind/GPUSceneWind.js +1 -1
  209. package/src/engine/graphics3/decal/DecalAtlas.d.ts +0 -43
  210. package/src/engine/graphics3/decal/DecalAtlas.d.ts.map +0 -1
  211. package/src/engine/graphics3/decal/DecalAtlasFill.d.ts.map +0 -1
  212. package/src/engine/graphics3/decal/DecalAtlasFill.js +0 -32
  213. package/src/engine/graphics3/decal/decal_atlas_border.d.ts.map +0 -1
  214. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts +0 -26
  215. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts.map +0 -1
  216. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.js +0 -268
  217. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.d.ts +0 -3
  218. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.d.ts.map +0 -1
  219. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.js +0 -32
  220. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts +0 -17
  221. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +0 -1
  222. package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +0 -98
  223. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts +0 -23
  224. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts.map +0 -1
  225. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.js +0 -118
  226. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts +0 -15
  227. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +0 -1
  228. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +0 -49
  229. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +0 -17
  230. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +0 -1
  231. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +0 -50
  232. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts +0 -35
  233. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +0 -1
  234. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.js +0 -105
  235. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +0 -35
  236. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +0 -1
  237. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +0 -80
  238. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts +0 -10
  239. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts.map +0 -1
  240. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.js +0 -51
  241. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +0 -28
  242. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +0 -1
  243. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +0 -39
  244. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +0 -48
  245. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +0 -1
  246. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +0 -121
  247. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +0 -28
  248. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +0 -1
  249. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +0 -237
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Declares the world-space irradiance clipmap's bindings on a shader resource group.
3
+ *
4
+ * @param {import("../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor} group
5
+ * @param {Object} [options]
6
+ * @param {boolean} [options.include_far_field=false] whether to also declare `far_field_irradiance_sh`
7
+ * @returns {import("../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor}
8
+ */
9
+ export function irradiance_clipmap_add_resources(group: import("../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor, { include_far_field }?: {
10
+ include_far_field?: boolean;
11
+ }): import("../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor;
12
+ /**
13
+ * Uniform buffer binding descriptor for `irradiance_clipmap` ({@link IRRADIANCE_CLIPMAP_STRUCT}).
14
+ * @type {ShaderResourceDescriptor}
15
+ */
16
+ export const IRRADIANCE_CLIPMAP_UNIFORM_RESOURCE: ShaderResourceDescriptor;
17
+ /**
18
+ * 3D atlas texture binding descriptor for the luma SH2 (`Y`) texture of the irradiance clipmap.
19
+ * @type {ShaderResourceDescriptor}
20
+ */
21
+ export const IRRADIANCE_CLIPMAP_ATLAS_Y_RESOURCE: ShaderResourceDescriptor;
22
+ /**
23
+ * 3D atlas texture binding descriptor for the chroma (`CoCg`) texture of the irradiance clipmap.
24
+ * @type {ShaderResourceDescriptor}
25
+ */
26
+ export const IRRADIANCE_CLIPMAP_ATLAS_COCG_RESOURCE: ShaderResourceDescriptor;
27
+ /**
28
+ * Linear clamped sampler binding descriptor for the irradiance clipmap atlas textures.
29
+ * @type {ShaderResourceDescriptor}
30
+ */
31
+ export const IRRADIANCE_CLIPMAP_SAMPLER_RESOURCE: ShaderResourceDescriptor;
32
+ /**
33
+ * World-space irradiance clipmap sampling:
34
+ *
35
+ * - `irradiance_clipmap_cascade_read_stochastic(c, position_ws, &u) -> MetroL1Irradiance`
36
+ * Evaluates a 2-tap antithetic Quadratic B-Spline (`B_2 = B_1 * B_0`) read of cascade `c`'s tile
37
+ * in `irradiance_clipmap_atlas_y` and `irradiance_clipmap_atlas_cocg`.
38
+ * - `irradiance_clipmap_cascade_read(c, position_ws) -> MetroL1Irradiance`
39
+ * Deterministic convenience wrapper around `irradiance_clipmap_cascade_read_stochastic`.
40
+ * - `irradiance_clipmap_sample_stochastic(position_ws, random_u) -> MetroL1Irradiance`
41
+ * Selects the finest cascade covering `position_ws` via continuous radial distance from `anchor`,
42
+ * computes a `smoothstep(0.0, 1.0, selection.edge_weight)` transition weight across the outer band
43
+ * (`blend_skirt` cells), and stochastically reads `selection.level` or `selection.level + 1`.
44
+ *
45
+ * ## Why Hardware Trilinear (`B_1`) Shows Visible Grid Lines (`┐`)
46
+ *
47
+ * In coarse clipmap cascades (`h = 0.5 m .. 1.0 m`), a single voxel spans 50-100 screen pixels across
48
+ * translucent smoke billboards, and near a point light the `1 / r^2` falloff is strongly convex
49
+ * (`d^2 I / dy^2 >> 0`, e.g. slope dropping by >4x from one voxel to the next):
50
+ * 1. **Dirac-Delta Curvature / Mach Bands:** Hardware trilinear interpolation (`B_1`) is piecewise
51
+ * linear (`C^0`), so inside each 60-pixel voxel cell its second derivative is identically zero
52
+ * (`d^2 I / dy^2 = 0`), and *all* of the curvature is concentrated into a 1-pixel Dirac delta
53
+ * spike along the voxel-centre plane `y = k + 0.5`:
54
+ * `d^2 I_trilinear / dy^2 = sum_k (I_{k+1} - 2*I_k + I_{k-1}) * delta(y - (k + 0.5))`.
55
+ * Because human vision (lateral inhibition / Mach band illusion) and contrast stretching respond
56
+ * to the Laplacian `nabla^2 I`, concentrating the entire slope transition onto a single plane
57
+ * produces a sharp visible bright/dark ridge line at every voxel centre.
58
+ * 2. **Oblique Billboard Saddle Cross-Terms:** Camera-facing particle billboards slice obliquely
59
+ * through the world-aligned `(x, y, z)` grid. Within each cell, trilinear interpolation is a
60
+ * hyperbolic paraboloid (`a + b*x + c*y + d*x*y + ...`) that curves along diagonals but collapses
61
+ * to straight lines on the axis-aligned planes `x = x_k, y = y_k, z = z_k`, creating visible
62
+ * grid-aligned creases where adjacent saddle patches meet.
63
+ *
64
+ * ## Why `floor(coord)`-Partitioned Sigg & Hadwiger Stochastic WRS Fails
65
+ *
66
+ * Standard 8-tap Sigg & Hadwiger tricubic B-spline (`B_3`) decomposes the 4-texel 1D cubic weights
67
+ * `(w_0, w_1, w_2, w_3)` around `tc = floor(coord)` (`f = coord - tc in [0, 1)`) into two hardware
68
+ * linear taps: tap 0 pairing `(w_0, w_1)` with weight `g_0 = w_0 + w_1`, and tap 1 pairing `(w_2, w_3)`
69
+ * with weight `g_1 = w_2 + w_3`. In deterministic 8-tap evaluation both taps are summed, so the
70
+ * `floor(coord)` partition is invisible. When sub-sampled stochastically via WRS, however:
71
+ * 1. **Tap-Pairing Flip Across `f = 1^- -> 0^+`:** At a voxel-centre plane, the 3 non-zero B-spline
72
+ * weights are `(1/6, 4/6, 1/6)`. Just below the plane (`f = 0.999`), Sigg & Hadwiger pairs the
73
+ * central `4/6` texel with the upper texel (`g_1 = 5/6` at `+0.2` voxels, `g_0 = 1/6` at `-1.0`
74
+ * voxel). Just above the plane (`f = 0.001`), `tc = floor(coord)` increments and switches the
75
+ * central `4/6` texel into the lower pair (`g_0 = 5/6` at `-0.2` voxels, `g_1 = 1/6` at `+1.0`
76
+ * voxel). The 83.3% majority tap therefore jumps backwards by `-0.4` voxels and the variance
77
+ * jumps by 2.8x across every integer coordinate plane.
78
+ * 2. **Double-Weighting Bias (`w_i^2`) in `weight1 / (weight0 + weight1)`:** Because WRS already
79
+ * selects tap `i` with probability `w_i`, blending two WRS taps by `weight1 / (weight0 + weight1)`
80
+ * weights each tap by `w_i` a second time (`w_i^2`), creating a >60% step discontinuity in the
81
+ * expected value across `tc = floor(coord)`.
82
+ *
83
+ * ## Why 2-Tap Antithetic Quadratic B-Spline (`B_2 = B_1 * B_0`) Is the Sweet Spot
84
+ *
85
+ * Hardware `textureSampleLevel` already evaluates the 3D linear tent filter `B_1`. Convolving `B_1`
86
+ * with a uniform unit box filter `B_0` on `[-0.5, +0.5]^3` via two antithetic taps at
87
+ * `center + delta` and `center - delta` (`delta in [-0.5, +0.5]^3`, mixed `0.5 / 0.5`) yields the
88
+ * exact `C^1` Quadratic B-Spline `B_2 = B_1 * B_0`:
89
+ * - **Constant Second Derivative Across Each Cell:** Because the `[-0.5, +0.5]` smoothing window is
90
+ * exactly 1 voxel wide, adjacent voxel-centre smoothing windows meet edge-to-edge and spread the
91
+ * slope change `I_{k+1} - 2*I_k + I_{k-1}` uniformly across all 60 pixels of the cell
92
+ * (`d^2 B_2 / dx^2 = const`), completely eliminating the Mach-band Dirac spike.
93
+ * - **Zero `floor(coord)` Discontinuity:** Neither the tap offsets nor the weights depend on
94
+ * `floor(coord)`, so both the mean and the variance are 100% continuous across all voxel planes.
95
+ * - **First-Order Gradient Cancellation & Compact Support:** Antithetic pairing (`+delta`, `-delta`)
96
+ * cancels all linear gradient noise `+/- dot(nabla I, delta)` on every pixel, while keeping taps
97
+ * within `+/- 0.5` voxels of `center` (half the radius of `B_3 = B_1 * B_1`), avoiding `+/- 1`
98
+ * voxel fire-bleed grain and staying strictly inside the 1-texel cascade border.
99
+ *
100
+ * @type {CodeChunk}
101
+ */
102
+ export const chunk_irradiance_clipmap_sample: CodeChunk;
103
+ /**
104
+ * Samples the world-space irradiance clipmap with deterministic `smoothstep` cascade blending and
105
+ * automatic fallback into the scene's cached `far_field_irradiance_sh` (used by particle lighting):
106
+ *
107
+ * - Outside all cascades (`CLIPMAP_LEVEL_NONE`), returns `far_field_irradiance_sh`.
108
+ * - In the interior of cascade `c` (`edge_weight <= 0.0`), performs a 2-tap antithetic Quadratic
109
+ * B-Spline (`B_2 = B_1 * B_0`) read of cascade `c`.
110
+ * - In the outer transition band of cascade `c < count - 1` (`edge_weight > 0.0`), smoothly blends
111
+ * between cascade `c` and parent cascade `c + 1` using `smoothstep(0.0, 1.0, edge_weight)` with
112
+ * hash-rescaled sample reuse across both cascades.
113
+ * - In the outer transition band of the coarsest cascade (`c == count - 1`), smoothly blends between
114
+ * the coarsest cascade and `far_field_irradiance_sh` using `smoothstep(0.0, 1.0, edge_weight)`.
115
+ *
116
+ * @type {CodeChunk}
117
+ */
118
+ export const chunk_irradiance_clipmap_sample_with_far_field: CodeChunk;
119
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
120
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
121
+ //# sourceMappingURL=chunk_irradiance_clipmap_sample.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_irradiance_clipmap_sample.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js"],"names":[],"mappings":"AAsDA;;;;;;;GAOG;AACH,wDALW,OAAO,wDAAwD,EAAE,6BAA6B;IAE5E,iBAAiB,GAAnC,OAAO;IACL,OAAO,wDAAwD,EAAE,6BAA6B,CAc1G;AA3DD;;;GAGG;AACH,kDAFU,wBAAwB,CAKhC;AAEF;;;GAGG;AACH,kDAFU,wBAAwB,CAMhC;AAEF;;;GAGG;AACH,qDAFU,wBAAwB,CAMhC;AAEF;;;GAGG;AACH,kDAFU,wBAAwB,CAMhC;AAwBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,8CAFU,SAAS,CAsKjB;AAOF;;;;;;;;;;;;;;GAcG;AACH,6DAFU,SAAS,CAoCjB;yCAtWuC,mDAAmD;0BADlE,oCAAoC"}
@@ -0,0 +1,370 @@
1
+ import { FAR_FIELD_IRRADIANCE_SH_RESOURCE } from "../../light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.js";
2
+ import { chunk_clipmap_select_finest } from "../../shader/chunk/clipmap/chunk_clipmap_select_finest.js";
3
+ import { chunk_hash_lowbias32 } from "../../shader/chunk/random/chunk_hash_lowbias32.js";
4
+ import { chunk_hash_to_float01 } from "../../shader/chunk/random/chunk_hash_to_float01.js";
5
+ import {
6
+ METRO_L1_IRRADIANCE_STRUCT
7
+ } from "../../shader/chunk/spherical_harmonics/l1i/chunk_convert_to_irradiance_sh.js";
8
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
9
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
10
+ import {
11
+ IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT,
12
+ IRRADIANCE_CLIPMAP_SAMPLER_DESCRIPTOR,
13
+ } from "./IRRADIANCE_CLIPMAP.js";
14
+ import { IRRADIANCE_CLIPMAP_STRUCT } from "./IRRADIANCE_CLIPMAP_STRUCT.js";
15
+
16
+ /**
17
+ * Uniform buffer binding descriptor for `irradiance_clipmap` ({@link IRRADIANCE_CLIPMAP_STRUCT}).
18
+ * @type {ShaderResourceDescriptor}
19
+ */
20
+ export const IRRADIANCE_CLIPMAP_UNIFORM_RESOURCE = ShaderResourceDescriptor.uniform(
21
+ "irradiance_clipmap",
22
+ IRRADIANCE_CLIPMAP_STRUCT
23
+ );
24
+
25
+ /**
26
+ * 3D atlas texture binding descriptor for the luma SH2 (`Y`) texture of the irradiance clipmap.
27
+ * @type {ShaderResourceDescriptor}
28
+ */
29
+ export const IRRADIANCE_CLIPMAP_ATLAS_Y_RESOURCE = ShaderResourceDescriptor.texture(
30
+ "irradiance_clipmap_atlas_y",
31
+ "float",
32
+ "3d"
33
+ );
34
+
35
+ /**
36
+ * 3D atlas texture binding descriptor for the chroma (`CoCg`) texture of the irradiance clipmap.
37
+ * @type {ShaderResourceDescriptor}
38
+ */
39
+ export const IRRADIANCE_CLIPMAP_ATLAS_COCG_RESOURCE = ShaderResourceDescriptor.texture(
40
+ "irradiance_clipmap_atlas_cocg",
41
+ "float",
42
+ "3d"
43
+ );
44
+
45
+ /**
46
+ * Linear clamped sampler binding descriptor for the irradiance clipmap atlas textures.
47
+ * @type {ShaderResourceDescriptor}
48
+ */
49
+ export const IRRADIANCE_CLIPMAP_SAMPLER_RESOURCE = ShaderResourceDescriptor.sampler(
50
+ "irradiance_clipmap_sampler",
51
+ "filtering",
52
+ IRRADIANCE_CLIPMAP_SAMPLER_DESCRIPTOR
53
+ );
54
+
55
+ /**
56
+ * Declares the world-space irradiance clipmap's bindings on a shader resource group.
57
+ *
58
+ * @param {import("../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor} group
59
+ * @param {Object} [options]
60
+ * @param {boolean} [options.include_far_field=false] whether to also declare `far_field_irradiance_sh`
61
+ * @returns {import("../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor}
62
+ */
63
+ export function irradiance_clipmap_add_resources(group, { include_far_field = false } = {}) {
64
+ group
65
+ .add(IRRADIANCE_CLIPMAP_UNIFORM_RESOURCE)
66
+ .add(IRRADIANCE_CLIPMAP_ATLAS_Y_RESOURCE)
67
+ .add(IRRADIANCE_CLIPMAP_ATLAS_COCG_RESOURCE)
68
+ .add(IRRADIANCE_CLIPMAP_SAMPLER_RESOURCE);
69
+
70
+ if (include_far_field) {
71
+ group.add(FAR_FIELD_IRRADIANCE_SH_RESOURCE);
72
+ }
73
+
74
+ return group;
75
+ }
76
+
77
+ /**
78
+ * World-space irradiance clipmap sampling:
79
+ *
80
+ * - `irradiance_clipmap_cascade_read_stochastic(c, position_ws, &u) -> MetroL1Irradiance`
81
+ * Evaluates a 2-tap antithetic Quadratic B-Spline (`B_2 = B_1 * B_0`) read of cascade `c`'s tile
82
+ * in `irradiance_clipmap_atlas_y` and `irradiance_clipmap_atlas_cocg`.
83
+ * - `irradiance_clipmap_cascade_read(c, position_ws) -> MetroL1Irradiance`
84
+ * Deterministic convenience wrapper around `irradiance_clipmap_cascade_read_stochastic`.
85
+ * - `irradiance_clipmap_sample_stochastic(position_ws, random_u) -> MetroL1Irradiance`
86
+ * Selects the finest cascade covering `position_ws` via continuous radial distance from `anchor`,
87
+ * computes a `smoothstep(0.0, 1.0, selection.edge_weight)` transition weight across the outer band
88
+ * (`blend_skirt` cells), and stochastically reads `selection.level` or `selection.level + 1`.
89
+ *
90
+ * ## Why Hardware Trilinear (`B_1`) Shows Visible Grid Lines (`┐`)
91
+ *
92
+ * In coarse clipmap cascades (`h = 0.5 m .. 1.0 m`), a single voxel spans 50-100 screen pixels across
93
+ * translucent smoke billboards, and near a point light the `1 / r^2` falloff is strongly convex
94
+ * (`d^2 I / dy^2 >> 0`, e.g. slope dropping by >4x from one voxel to the next):
95
+ * 1. **Dirac-Delta Curvature / Mach Bands:** Hardware trilinear interpolation (`B_1`) is piecewise
96
+ * linear (`C^0`), so inside each 60-pixel voxel cell its second derivative is identically zero
97
+ * (`d^2 I / dy^2 = 0`), and *all* of the curvature is concentrated into a 1-pixel Dirac delta
98
+ * spike along the voxel-centre plane `y = k + 0.5`:
99
+ * `d^2 I_trilinear / dy^2 = sum_k (I_{k+1} - 2*I_k + I_{k-1}) * delta(y - (k + 0.5))`.
100
+ * Because human vision (lateral inhibition / Mach band illusion) and contrast stretching respond
101
+ * to the Laplacian `nabla^2 I`, concentrating the entire slope transition onto a single plane
102
+ * produces a sharp visible bright/dark ridge line at every voxel centre.
103
+ * 2. **Oblique Billboard Saddle Cross-Terms:** Camera-facing particle billboards slice obliquely
104
+ * through the world-aligned `(x, y, z)` grid. Within each cell, trilinear interpolation is a
105
+ * hyperbolic paraboloid (`a + b*x + c*y + d*x*y + ...`) that curves along diagonals but collapses
106
+ * to straight lines on the axis-aligned planes `x = x_k, y = y_k, z = z_k`, creating visible
107
+ * grid-aligned creases where adjacent saddle patches meet.
108
+ *
109
+ * ## Why `floor(coord)`-Partitioned Sigg & Hadwiger Stochastic WRS Fails
110
+ *
111
+ * Standard 8-tap Sigg & Hadwiger tricubic B-spline (`B_3`) decomposes the 4-texel 1D cubic weights
112
+ * `(w_0, w_1, w_2, w_3)` around `tc = floor(coord)` (`f = coord - tc in [0, 1)`) into two hardware
113
+ * linear taps: tap 0 pairing `(w_0, w_1)` with weight `g_0 = w_0 + w_1`, and tap 1 pairing `(w_2, w_3)`
114
+ * with weight `g_1 = w_2 + w_3`. In deterministic 8-tap evaluation both taps are summed, so the
115
+ * `floor(coord)` partition is invisible. When sub-sampled stochastically via WRS, however:
116
+ * 1. **Tap-Pairing Flip Across `f = 1^- -> 0^+`:** At a voxel-centre plane, the 3 non-zero B-spline
117
+ * weights are `(1/6, 4/6, 1/6)`. Just below the plane (`f = 0.999`), Sigg & Hadwiger pairs the
118
+ * central `4/6` texel with the upper texel (`g_1 = 5/6` at `+0.2` voxels, `g_0 = 1/6` at `-1.0`
119
+ * voxel). Just above the plane (`f = 0.001`), `tc = floor(coord)` increments and switches the
120
+ * central `4/6` texel into the lower pair (`g_0 = 5/6` at `-0.2` voxels, `g_1 = 1/6` at `+1.0`
121
+ * voxel). The 83.3% majority tap therefore jumps backwards by `-0.4` voxels and the variance
122
+ * jumps by 2.8x across every integer coordinate plane.
123
+ * 2. **Double-Weighting Bias (`w_i^2`) in `weight1 / (weight0 + weight1)`:** Because WRS already
124
+ * selects tap `i` with probability `w_i`, blending two WRS taps by `weight1 / (weight0 + weight1)`
125
+ * weights each tap by `w_i` a second time (`w_i^2`), creating a >60% step discontinuity in the
126
+ * expected value across `tc = floor(coord)`.
127
+ *
128
+ * ## Why 2-Tap Antithetic Quadratic B-Spline (`B_2 = B_1 * B_0`) Is the Sweet Spot
129
+ *
130
+ * Hardware `textureSampleLevel` already evaluates the 3D linear tent filter `B_1`. Convolving `B_1`
131
+ * with a uniform unit box filter `B_0` on `[-0.5, +0.5]^3` via two antithetic taps at
132
+ * `center + delta` and `center - delta` (`delta in [-0.5, +0.5]^3`, mixed `0.5 / 0.5`) yields the
133
+ * exact `C^1` Quadratic B-Spline `B_2 = B_1 * B_0`:
134
+ * - **Constant Second Derivative Across Each Cell:** Because the `[-0.5, +0.5]` smoothing window is
135
+ * exactly 1 voxel wide, adjacent voxel-centre smoothing windows meet edge-to-edge and spread the
136
+ * slope change `I_{k+1} - 2*I_k + I_{k-1}` uniformly across all 60 pixels of the cell
137
+ * (`d^2 B_2 / dx^2 = const`), completely eliminating the Mach-band Dirac spike.
138
+ * - **Zero `floor(coord)` Discontinuity:** Neither the tap offsets nor the weights depend on
139
+ * `floor(coord)`, so both the mean and the variance are 100% continuous across all voxel planes.
140
+ * - **First-Order Gradient Cancellation & Compact Support:** Antithetic pairing (`+delta`, `-delta`)
141
+ * cancels all linear gradient noise `+/- dot(nabla I, delta)` on every pixel, while keeping taps
142
+ * within `+/- 0.5` voxels of `center` (half the radius of `B_3 = B_1 * B_1`), avoiding `+/- 1`
143
+ * voxel fire-bleed grain and staying strictly inside the 1-texel cascade border.
144
+ *
145
+ * @type {CodeChunk}
146
+ */
147
+ export const chunk_irradiance_clipmap_sample = CodeChunk.from(
148
+ //language=WGSL
149
+ `
150
+ const IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT: f32 = ${IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT}.0;
151
+
152
+ fn irradiance_clipmap_select_finest(
153
+ position_ws: vec3<f32>,
154
+ band_width: f32,
155
+ ) -> ClipmapSelection {
156
+ let count = irradiance_clipmap.cascade_count;
157
+ let anchor_ws = irradiance_clipmap.anchor;
158
+
159
+ for (var i = 0u; i < 16u; i++) {
160
+ if (i >= count) {
161
+ break;
162
+ }
163
+
164
+ let level = irradiance_clipmap.levels[i];
165
+ let position_cells = position_ws / level.cell_size;
166
+ let half_size = 0.5 * vec3<f32>(level.size);
167
+ let level_center = vec3<f32>(level.corner) + half_size;
168
+ let anchor_cells = anchor_ws / level.cell_size;
169
+
170
+ // Use the continuous camera anchor when within the 1-voxel rounding bound of level.corner,
171
+ // so cascade selection and edge_weight vary C^1-smoothly with camera motion without
172
+ // stair-stepping at integer corner transitions.
173
+ let center_cells = select(
174
+ level_center,
175
+ anchor_cells,
176
+ all(abs(anchor_cells - level_center) <= vec3<f32>(0.501))
177
+ );
178
+
179
+ // Subtract 0.5 cells from half_size so that even when anchor_cells is offset by up to
180
+ // +/-0.5 cells from level_center, the selection sphere stays strictly inside [0, size]^3
181
+ // and the +/-0.5 voxel B_2 jitter taps stay strictly inside the 1-texel border
182
+ // [-0.5, size + 0.5]^3 without hitting the border clamp.
183
+ let radius = max(0.5, min(half_size.x, min(half_size.y, half_size.z)) - 0.5);
184
+ let edge = radius - length(position_cells - center_cells);
185
+
186
+ if (edge <= 0.0) {
187
+ continue;
188
+ }
189
+
190
+ return ClipmapSelection(i, saturate(1.0 - edge / band_width));
191
+ }
192
+
193
+ return ClipmapSelection(CLIPMAP_LEVEL_NONE, 0.0);
194
+ }
195
+
196
+ fn irradiance_clipmap_box_jitter(u: ptr<function, f32>, salt: u32) -> vec3<f32> {
197
+ let h0 = hash_lowbias32(bitcast<u32>(*u) ^ salt);
198
+ let h1 = hash_lowbias32(h0 ^ 0x9e3779b9u);
199
+ let h2 = hash_lowbias32(h1 ^ 0x85ebca6bu);
200
+ *u = hash_to_float01(hash_lowbias32(h2 ^ 0xc2b2ae35u));
201
+
202
+ // Uniform box jitter in [-0.5, +0.5]^3 paired antithetically (center + delta, center - delta):
203
+ // convolving hardware trilinear B_1 with B_0 on [-0.5, +0.5]^3 yields the exact C^1 Quadratic
204
+ // B-Spline B_2 = B_1 * B_0 with constant second derivative across each cell, zero floor/integer
205
+ // discontinuity, and support staying strictly within the 1-texel cascade border.
206
+ return vec3<f32>(
207
+ hash_to_float01(h0) - 0.5,
208
+ hash_to_float01(h1) - 0.5,
209
+ hash_to_float01(h2) - 0.5,
210
+ );
211
+ }
212
+
213
+ fn irradiance_clipmap_cascade_read_stochastic(
214
+ c: u32,
215
+ position_ws: vec3<f32>,
216
+ u: ptr<function, f32>,
217
+ ) -> ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref} {
218
+ let level = irradiance_clipmap.levels[c];
219
+ let cascade = irradiance_clipmap.cascades[c];
220
+ let inv_atlas = irradiance_clipmap.inverse_atlas_size;
221
+
222
+ let local = position_ws / level.cell_size - vec3<f32>(level.corner);
223
+ let center = cascade.content_origin + local;
224
+ let delta = irradiance_clipmap_box_jitter(u, (c + 1u) * 0x27d4eb2du);
225
+
226
+ // Clamp hardware linear tap coordinates to the cascade tile's valid texel centres (including its 1-texel border)
227
+ let t_min = cascade.content_origin - vec3<f32>(0.5);
228
+ let t_max = cascade.content_origin + vec3<f32>(level.size) + vec3<f32>(0.5);
229
+ let uvw0 = clamp(center + delta, t_min, t_max) * inv_atlas;
230
+ let uvw1 = clamp(center - delta, t_min, t_max) * inv_atlas;
231
+
232
+ let sh0 = ${METRO_L1_IRRADIANCE_STRUCT.make({
233
+ CoCg: "textureSampleLevel(irradiance_clipmap_atlas_cocg, irradiance_clipmap_sampler, uvw0, 0.0).xy",
234
+ Y: "textureSampleLevel(irradiance_clipmap_atlas_y, irradiance_clipmap_sampler, uvw0, 0.0)",
235
+ })};
236
+ let sh1 = ${METRO_L1_IRRADIANCE_STRUCT.make({
237
+ CoCg: "textureSampleLevel(irradiance_clipmap_atlas_cocg, irradiance_clipmap_sampler, uvw1, 0.0).xy",
238
+ Y: "textureSampleLevel(irradiance_clipmap_atlas_y, irradiance_clipmap_sampler, uvw1, 0.0)",
239
+ })};
240
+
241
+ return irradiance_clipmap_mix_sh(sh0, sh1, 0.5);
242
+ }
243
+
244
+ fn irradiance_clipmap_cascade_read(c: u32, position_ws: vec3<f32>) -> ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref} {
245
+ let level = irradiance_clipmap.levels[c];
246
+ let cascade = irradiance_clipmap.cascades[c];
247
+ let local = position_ws / level.cell_size - vec3<f32>(level.corner);
248
+ let center = cascade.content_origin + local;
249
+ let t_min = cascade.content_origin - vec3<f32>(0.5);
250
+ let t_max = cascade.content_origin + vec3<f32>(level.size) + vec3<f32>(0.5);
251
+ let uvw = clamp(center, t_min, t_max) * irradiance_clipmap.inverse_atlas_size;
252
+
253
+ return ${METRO_L1_IRRADIANCE_STRUCT.make({
254
+ CoCg: "textureSampleLevel(irradiance_clipmap_atlas_cocg, irradiance_clipmap_sampler, uvw, 0.0).xy",
255
+ Y: "textureSampleLevel(irradiance_clipmap_atlas_y, irradiance_clipmap_sampler, uvw, 0.0)",
256
+ })};
257
+ }
258
+
259
+ fn irradiance_clipmap_mix_sh(
260
+ a: ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref},
261
+ b: ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref},
262
+ t: f32,
263
+ ) -> ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref} {
264
+ return ${METRO_L1_IRRADIANCE_STRUCT.make({
265
+ CoCg: "a.CoCg + (b.CoCg - a.CoCg) * t",
266
+ Y: "a.Y + (b.Y - a.Y) * t",
267
+ })};
268
+ }
269
+
270
+ fn irradiance_clipmap_sample_stochastic(
271
+ position_ws: vec3<f32>,
272
+ random_u: f32,
273
+ ) -> ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref} {
274
+ let count = irradiance_clipmap.cascade_count;
275
+ let blend_skirt = select(IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT, irradiance_clipmap.blend_skirt, irradiance_clipmap.blend_skirt > 0.0);
276
+ let selection = irradiance_clipmap_select_finest(position_ws, blend_skirt);
277
+
278
+ if (selection.level == CLIPMAP_LEVEL_NONE) {
279
+ return ${METRO_L1_IRRADIANCE_STRUCT.make({
280
+ CoCg: "vec2<f32>(0.0)",
281
+ Y: "vec4<f32>(0.0)",
282
+ })};
283
+ }
284
+
285
+ var u = clamp(random_u, 0.0, 0.99999994);
286
+ let parent = selection.level + 1u;
287
+ if (selection.edge_weight <= 0.0 || parent >= count) {
288
+ return irradiance_clipmap_cascade_read_stochastic(selection.level, position_ws, &u);
289
+ }
290
+
291
+ // Non-linear smoothstep transition keeps sampling in the higher-resolution cascade longer,
292
+ // rescaling u via sample reuse so the downstream WRS tricubic tap gets an independent uniform sample.
293
+ let blend = smoothstep(0.0, 1.0, selection.edge_weight);
294
+ var chosen_cascade = selection.level;
295
+ if (u < blend) {
296
+ chosen_cascade = parent;
297
+ u = u / max(blend, 1e-6);
298
+ } else {
299
+ u = (u - blend) / max(1.0 - blend, 1e-6);
300
+ }
301
+
302
+ return irradiance_clipmap_cascade_read_stochastic(chosen_cascade, position_ws, &u);
303
+ }
304
+ `, [
305
+ IRRADIANCE_CLIPMAP_STRUCT.declaration_chunk,
306
+ METRO_L1_IRRADIANCE_STRUCT.declaration_chunk,
307
+ chunk_clipmap_select_finest,
308
+ chunk_hash_lowbias32,
309
+ chunk_hash_to_float01,
310
+ ]
311
+ );
312
+
313
+ chunk_irradiance_clipmap_sample.requireResource(IRRADIANCE_CLIPMAP_UNIFORM_RESOURCE);
314
+ chunk_irradiance_clipmap_sample.requireResource(IRRADIANCE_CLIPMAP_ATLAS_Y_RESOURCE);
315
+ chunk_irradiance_clipmap_sample.requireResource(IRRADIANCE_CLIPMAP_ATLAS_COCG_RESOURCE);
316
+ chunk_irradiance_clipmap_sample.requireResource(IRRADIANCE_CLIPMAP_SAMPLER_RESOURCE);
317
+
318
+ /**
319
+ * Samples the world-space irradiance clipmap with deterministic `smoothstep` cascade blending and
320
+ * automatic fallback into the scene's cached `far_field_irradiance_sh` (used by particle lighting):
321
+ *
322
+ * - Outside all cascades (`CLIPMAP_LEVEL_NONE`), returns `far_field_irradiance_sh`.
323
+ * - In the interior of cascade `c` (`edge_weight <= 0.0`), performs a 2-tap antithetic Quadratic
324
+ * B-Spline (`B_2 = B_1 * B_0`) read of cascade `c`.
325
+ * - In the outer transition band of cascade `c < count - 1` (`edge_weight > 0.0`), smoothly blends
326
+ * between cascade `c` and parent cascade `c + 1` using `smoothstep(0.0, 1.0, edge_weight)` with
327
+ * hash-rescaled sample reuse across both cascades.
328
+ * - In the outer transition band of the coarsest cascade (`c == count - 1`), smoothly blends between
329
+ * the coarsest cascade and `far_field_irradiance_sh` using `smoothstep(0.0, 1.0, edge_weight)`.
330
+ *
331
+ * @type {CodeChunk}
332
+ */
333
+ export const chunk_irradiance_clipmap_sample_with_far_field = CodeChunk.from(
334
+ //language=WGSL
335
+ `
336
+ fn irradiance_clipmap_sample_with_far_field(
337
+ position_ws: vec3<f32>,
338
+ random_u: f32,
339
+ ) -> ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref} {
340
+ let count = irradiance_clipmap.cascade_count;
341
+ let blend_skirt = select(IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT, irradiance_clipmap.blend_skirt, irradiance_clipmap.blend_skirt > 0.0);
342
+ let selection = irradiance_clipmap_select_finest(position_ws, blend_skirt);
343
+
344
+ if (selection.level == CLIPMAP_LEVEL_NONE) {
345
+ return far_field_irradiance_sh;
346
+ }
347
+
348
+ var u = clamp(random_u, 0.0, 0.99999994);
349
+ let inner = irradiance_clipmap_cascade_read_stochastic(selection.level, position_ws, &u);
350
+ if (selection.edge_weight <= 0.0) {
351
+ return inner;
352
+ }
353
+
354
+ let blend = smoothstep(0.0, 1.0, selection.edge_weight);
355
+ let parent = selection.level + 1u;
356
+
357
+ if (parent < count) {
358
+ let outer = irradiance_clipmap_cascade_read_stochastic(parent, position_ws, &u);
359
+ return irradiance_clipmap_mix_sh(inner, outer, blend);
360
+ }
361
+
362
+ return irradiance_clipmap_mix_sh(inner, far_field_irradiance_sh, blend);
363
+ }
364
+ `, [
365
+ chunk_irradiance_clipmap_sample,
366
+ ]
367
+ );
368
+
369
+ chunk_irradiance_clipmap_sample_with_far_field.requireResource(IRRADIANCE_CLIPMAP_UNIFORM_RESOURCE);
370
+ chunk_irradiance_clipmap_sample_with_far_field.requireResource(FAR_FIELD_IRRADIANCE_SH_RESOURCE);
@@ -0,0 +1,16 @@
1
+ export const IRRADIANCE_CLIPMAP_BUILD_GROUP_SIZE: readonly number[];
2
+ export const IRRADIANCE_CLIPMAP_BUILD_STRUCT: WebGPUStruct;
3
+ /**
4
+ * Populates one cascade's tile (including its 1-texel trilinear skirt) in the synchronized `Y` and
5
+ * `CoCg` 3D tile atlases of the world-space irradiance clipmap.
6
+ *
7
+ * Evaluates indirect lighting (`INDIRECT_LIGHTING`), directional lights (`SHADOW_DIRECTIONAL_TECHNIQUE`),
8
+ * and world-space clustered point and spot lights with shadow maps at deterministic world-space
9
+ * voxel centres.
10
+ *
11
+ * @type {ComputeShader}
12
+ */
13
+ export const shader_irradiance_clipmap_build: ComputeShader;
14
+ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
15
+ import { ComputeShader } from "../../shader/ComputeShader.js";
16
+ //# sourceMappingURL=shader_irradiance_clipmap_build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_irradiance_clipmap_build.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.js"],"names":[],"mappings":"AAmCA,oEAA4E;AAE5E,2DAO6B;AAoI7B;;;;;;;;;GASG;AACH,8CAFU,aAAa,CAMpB;6BAvK0B,mCAAmC;8BAJlC,+BAA+B"}