@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,60 @@
1
+ import { CLIPMAP_LEVEL_LIMIT } from "../../shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js";
2
+ import { SAMPLER_LINEAR_UPSCALE } from "../../texture/SAMPLER_LINEAR_UPSCALE.js";
3
+
4
+ /**
5
+ * Default number of cascades in the world-space irradiance clipmap (Decision 6.3).
6
+ * Covers 8 m, 16 m, 32 m, 64 m, 128 m, 256 m at 32³ and h0 = 0.25 m.
7
+ * @type {number}
8
+ */
9
+ export const IRRADIANCE_CLIPMAP_DEFAULT_CASCADE_COUNT = 6;
10
+
11
+ /**
12
+ * Maximum number of cascades supported by the irradiance clipmap table.
13
+ * @type {number}
14
+ */
15
+ export const IRRADIANCE_CLIPMAP_CASCADE_LIMIT = CLIPMAP_LEVEL_LIMIT;
16
+
17
+ /**
18
+ * Default resolution (cells per axis) of each irradiance clipmap cascade (Decision 6.3).
19
+ * @type {number}
20
+ */
21
+ export const IRRADIANCE_CLIPMAP_DEFAULT_RESOLUTION = 32;
22
+
23
+ /**
24
+ * Default finest cascade cell size h0 in metres (25 cm, Decision 6.3).
25
+ * @type {number}
26
+ */
27
+ export const IRRADIANCE_CLIPMAP_DEFAULT_CELL_SIZE = 0.25;
28
+
29
+ /**
30
+ * Texels of skirt on each side of a cascade's tile in the 3D atlas: 1 texel for hardware trilinear
31
+ * filtering (`tile_size = resolution + 2`).
32
+ * @type {number}
33
+ */
34
+ export const IRRADIANCE_CLIPMAP_TILE_BORDER = 1;
35
+
36
+ /**
37
+ * Default blend-skirt width in voxels (cells of that cascade) at the outer faces of each cascade
38
+ * window where blending takes place. At the very outer edge of the border voxel (`edge = 0`), the
39
+ * finer cascade's weight is `0.0` (`edge_weight = 1.0`); `blend_skirt` voxels inward, the finer
40
+ * cascade's weight is `1.0` (`edge_weight = 0.0`).
41
+ * @type {number}
42
+ */
43
+ export const IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT = 4;
44
+
45
+ /**
46
+ * Format of the two synchronized 3D atlas textures (`Y` and `CoCg`).
47
+ * @type {GPUTextureFormat}
48
+ */
49
+ export const IRRADIANCE_CLIPMAP_TILE_FORMAT = "rgba16float";
50
+
51
+ /**
52
+ * Sampler used for trilinear taps of the irradiance clipmap atlas textures.
53
+ */
54
+ export const IRRADIANCE_CLIPMAP_SAMPLER_DESCRIPTOR = SAMPLER_LINEAR_UPSCALE;
55
+
56
+ /**
57
+ * Maximum number of point or spot lights evaluated per voxel in the irradiance clipmap build pass.
58
+ * @type {number}
59
+ */
60
+ export const IRRADIANCE_CLIPMAP_LIGHT_BUDGET = 32;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Per-cascade atlas placement metadata for the world-space irradiance clipmap. 16 bytes.
3
+ * @type {WebGPUStruct}
4
+ */
5
+ export const IRRADIANCE_CASCADE_STRUCT: WebGPUStruct;
6
+ /**
7
+ * @type {WebGPUArray}
8
+ */
9
+ export const IRRADIANCE_CASCADE_ARRAY: WebGPUArray;
10
+ /**
11
+ * Uniform buffer layout for the world-space irradiance clipmap (`irradiance_clipmap`).
12
+ * Mirrors {@link WIND_FIELD_STRUCT} so `clipmap_select_finest` operates directly on `levels`.
13
+ *
14
+ * - `anchor`: continuous world-space camera/placement anchor (`[x, y, z]` in metres), used for
15
+ * continuous spherical cascade selection so blend weights never stair-step when integer cascade
16
+ * corners step by 1 voxel.
17
+ * - `blend_skirt`: number of voxels at each cascade window's outer boundary where blending toward
18
+ * the parent cascade (or far field) takes place.
19
+ *
20
+ * @type {WebGPUStruct}
21
+ */
22
+ export const IRRADIANCE_CLIPMAP_STRUCT: WebGPUStruct;
23
+ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
24
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
25
+ //# sourceMappingURL=IRRADIANCE_CLIPMAP_STRUCT.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IRRADIANCE_CLIPMAP_STRUCT.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.js"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wCAFU,YAAY,CASE;AAExB;;GAEG;AACH,uCAFU,WAAW,CAKnB;AAEF;;;;;;;;;;;GAWG;AACH,wCAFU,YAAY,CASE;6BA3CK,mCAAmC;4BADpC,kCAAkC"}
@@ -0,0 +1,47 @@
1
+ import { CLIPMAP_LEVEL_ARRAY } from "../../shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js";
2
+ import { f32, u32, vec3f } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
3
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
4
+ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
5
+ import { IRRADIANCE_CLIPMAP_CASCADE_LIMIT } from "./IRRADIANCE_CLIPMAP.js";
6
+
7
+ /**
8
+ * Per-cascade atlas placement metadata for the world-space irradiance clipmap. 16 bytes.
9
+ * @type {WebGPUStruct}
10
+ */
11
+ export const IRRADIANCE_CASCADE_STRUCT = WebGPUStruct.from({
12
+ /**
13
+ * The atlas texel coordinate of window-local cell 0 (`slot_origin + border`). Window-local
14
+ * cell `c` has its centre at `content_origin + c + 0.5`.
15
+ */
16
+ content_origin: vec3f,
17
+ pad0: f32,
18
+ }, "IrradianceCascade");
19
+
20
+ /**
21
+ * @type {WebGPUArray}
22
+ */
23
+ export const IRRADIANCE_CASCADE_ARRAY = WebGPUArray.from(
24
+ IRRADIANCE_CASCADE_STRUCT,
25
+ IRRADIANCE_CLIPMAP_CASCADE_LIMIT
26
+ );
27
+
28
+ /**
29
+ * Uniform buffer layout for the world-space irradiance clipmap (`irradiance_clipmap`).
30
+ * Mirrors {@link WIND_FIELD_STRUCT} so `clipmap_select_finest` operates directly on `levels`.
31
+ *
32
+ * - `anchor`: continuous world-space camera/placement anchor (`[x, y, z]` in metres), used for
33
+ * continuous spherical cascade selection so blend weights never stair-step when integer cascade
34
+ * corners step by 1 voxel.
35
+ * - `blend_skirt`: number of voxels at each cascade window's outer boundary where blending toward
36
+ * the parent cascade (or far field) takes place.
37
+ *
38
+ * @type {WebGPUStruct}
39
+ */
40
+ export const IRRADIANCE_CLIPMAP_STRUCT = WebGPUStruct.from({
41
+ levels: CLIPMAP_LEVEL_ARRAY,
42
+ cascades: IRRADIANCE_CASCADE_ARRAY,
43
+ inverse_atlas_size: vec3f,
44
+ cascade_count: u32,
45
+ anchor: vec3f,
46
+ blend_skirt: f32,
47
+ }, "IrradianceClipmap");
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Stateless, hysteresis-free 1-voxel-step window placement for {@link GPUIrradianceClipmap}.
3
+ *
4
+ * Cascade `c` has voxel size `cell_size * 2^c` and resolution `N = resolution[axis]`; its window is
5
+ * `[corner, corner + N)` in its own cells, covering `[corner * h_c, (corner + N) * h_c)` in world
6
+ * space.
7
+ *
8
+ * Unlike `FluidCascadePlacement` (which steps in 4-cell bricks with a 2.1-cell hysteretic deadband
9
+ * for persistent Eulerian fluid grids), the irradiance clipmap is rebuilt directly from scene lights
10
+ * and GI probes whenever a cascade shifts. Placement therefore uses a pure, stateless 1-voxel
11
+ * rounding rule (`Math.round(anchor / h_c - N * 0.5)`) with zero hysteresis:
12
+ * - Any given camera position `(x, y, z)` produces identical cascade windows regardless of the
13
+ * camera's prior trajectory (zooming in vs. zooming out).
14
+ * - Each cascade shifts by 1 voxel at a time, which is smaller than `blend_skirt`, so world-space
15
+ * positions always transition smoothly through the outer blend skirt rather than jumping past it.
16
+ */
17
+ export class IrradianceCascadePlacement {
18
+ /**
19
+ * @param {object} options
20
+ * @param {number} options.cascade_count 1 to {@link IRRADIANCE_CLIPMAP_CASCADE_LIMIT}
21
+ * @param {ArrayLike<number>} options.resolution cells on each axis, powers of two
22
+ * @param {number} options.cell_size metres, cascade 0's voxel size
23
+ */
24
+ constructor({ cascade_count, resolution, cell_size }: {
25
+ cascade_count: number;
26
+ resolution: ArrayLike<number>;
27
+ cell_size: number;
28
+ });
29
+ /** @returns {number} */
30
+ get cascade_count(): number;
31
+ /** @returns {Readonly<Int32Array>} */
32
+ get resolution(): Readonly<Int32Array>;
33
+ /** @returns {boolean} */
34
+ get placed(): boolean;
35
+ /**
36
+ * Cascade `c`'s voxel size in metres (`cell_size * 2^c`).
37
+ * @param {number} cascade
38
+ * @returns {number}
39
+ */
40
+ cell_size(cascade: number): number;
41
+ /**
42
+ * @param {number} cascade
43
+ * @param {number} axis 0, 1, or 2
44
+ * @returns {number} the cascade's corner on `axis`, in its own cells
45
+ */
46
+ corner(cascade: number, axis: number): number;
47
+ /**
48
+ * @param {number} cascade
49
+ * @param {number} axis 0, 1, or 2
50
+ * @returns {number} the corner recorded at the last {@link begin}
51
+ */
52
+ previous_corner(cascade: number, axis: number): number;
53
+ /**
54
+ * @param {number} cascade
55
+ * @returns {boolean} whether the cascade's corner changed since the last {@link begin}
56
+ */
57
+ moved(cascade: number): boolean;
58
+ /**
59
+ * Snapshot every cascade's current corner before a {@link place_all} call so {@link moved} can
60
+ * report which cascades shifted.
61
+ */
62
+ begin(): void;
63
+ /**
64
+ * Place every cascade around `(x, y, z)` in world metres, coarsest first, using a stateless
65
+ * 1-voxel rounding rule with zero hysteresis.
66
+ *
67
+ * @param {number} x
68
+ * @param {number} y
69
+ * @param {number} z
70
+ */
71
+ place_all(x: number, y: number, z: number): void;
72
+ #private;
73
+ }
74
+ //# sourceMappingURL=IrradianceCascadePlacement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IrradianceCascadePlacement.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH;IAmBI;;;;;OAKG;IACH;QAJ2B,aAAa,EAA7B,MAAM;QACqB,UAAU,EAArC,UAAU,MAAM,CAAC;QACD,SAAS,EAAzB,MAAM;OAkBhB;IAED,wBAAwB;IACxB,4BAEC;IAED,sCAAsC;IACtC,uCAEC;IAED,yBAAyB;IACzB,sBAEC;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;OAIG;IACH,gBAJW,MAAM,QACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;OAIG;IACH,yBAJW,MAAM,QACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,eAHW,MAAM,GACJ,OAAO,CAQnB;IAED;;;OAGG;IACH,cAOC;IAED;;;;;;;OAOG;IACH,aAJW,MAAM,KACN,MAAM,KACN,MAAM,QAmChB;;CACJ"}
@@ -0,0 +1,173 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { isPowerOfTwo } from "../../../../core/math/isPowerOfTwo.js";
3
+ import { IRRADIANCE_CLIPMAP_CASCADE_LIMIT } from "./IRRADIANCE_CLIPMAP.js";
4
+
5
+ /**
6
+ * Stateless, hysteresis-free 1-voxel-step window placement for {@link GPUIrradianceClipmap}.
7
+ *
8
+ * Cascade `c` has voxel size `cell_size * 2^c` and resolution `N = resolution[axis]`; its window is
9
+ * `[corner, corner + N)` in its own cells, covering `[corner * h_c, (corner + N) * h_c)` in world
10
+ * space.
11
+ *
12
+ * Unlike `FluidCascadePlacement` (which steps in 4-cell bricks with a 2.1-cell hysteretic deadband
13
+ * for persistent Eulerian fluid grids), the irradiance clipmap is rebuilt directly from scene lights
14
+ * and GI probes whenever a cascade shifts. Placement therefore uses a pure, stateless 1-voxel
15
+ * rounding rule (`Math.round(anchor / h_c - N * 0.5)`) with zero hysteresis:
16
+ * - Any given camera position `(x, y, z)` produces identical cascade windows regardless of the
17
+ * camera's prior trajectory (zooming in vs. zooming out).
18
+ * - Each cascade shifts by 1 voxel at a time, which is smaller than `blend_skirt`, so world-space
19
+ * positions always transition smoothly through the outer blend skirt rather than jumping past it.
20
+ */
21
+ export class IrradianceCascadePlacement {
22
+ /** @type {Int32Array} */
23
+ #resolution = new Int32Array(3);
24
+
25
+ /** @type {number} */
26
+ #cell_size;
27
+
28
+ /** @type {number} */
29
+ #cascade_count;
30
+
31
+ /** @type {Int32Array} */
32
+ #corner;
33
+
34
+ /** @type {Int32Array} */
35
+ #previous;
36
+
37
+ /** @type {boolean} */
38
+ #placed = false;
39
+
40
+ /**
41
+ * @param {object} options
42
+ * @param {number} options.cascade_count 1 to {@link IRRADIANCE_CLIPMAP_CASCADE_LIMIT}
43
+ * @param {ArrayLike<number>} options.resolution cells on each axis, powers of two
44
+ * @param {number} options.cell_size metres, cascade 0's voxel size
45
+ */
46
+ constructor({ cascade_count, resolution, cell_size }) {
47
+ assert.isPositiveInteger(cascade_count, "cascade_count");
48
+ assert.lessThanOrEqual(cascade_count, IRRADIANCE_CLIPMAP_CASCADE_LIMIT, "cascade_count");
49
+ assert.isFinite(cell_size, "cell_size");
50
+ assert.greaterThan(cell_size, 0, "cell_size");
51
+
52
+ for (let axis = 0; axis < 3; axis++) {
53
+ assert.isPositiveInteger(resolution[axis], "resolution");
54
+ assert.ok(isPowerOfTwo(resolution[axis]), "resolution is a power of two on each axis");
55
+ this.#resolution[axis] = resolution[axis];
56
+ }
57
+
58
+ this.#cascade_count = cascade_count;
59
+ this.#cell_size = cell_size;
60
+ this.#corner = new Int32Array(3 * cascade_count);
61
+ this.#previous = new Int32Array(3 * cascade_count);
62
+ }
63
+
64
+ /** @returns {number} */
65
+ get cascade_count() {
66
+ return this.#cascade_count;
67
+ }
68
+
69
+ /** @returns {Readonly<Int32Array>} */
70
+ get resolution() {
71
+ return this.#resolution;
72
+ }
73
+
74
+ /** @returns {boolean} */
75
+ get placed() {
76
+ return this.#placed;
77
+ }
78
+
79
+ /**
80
+ * Cascade `c`'s voxel size in metres (`cell_size * 2^c`).
81
+ * @param {number} cascade
82
+ * @returns {number}
83
+ */
84
+ cell_size(cascade) {
85
+ return this.#cell_size * 2 ** cascade;
86
+ }
87
+
88
+ /**
89
+ * @param {number} cascade
90
+ * @param {number} axis 0, 1, or 2
91
+ * @returns {number} the cascade's corner on `axis`, in its own cells
92
+ */
93
+ corner(cascade, axis) {
94
+ return this.#corner[3 * cascade + axis];
95
+ }
96
+
97
+ /**
98
+ * @param {number} cascade
99
+ * @param {number} axis 0, 1, or 2
100
+ * @returns {number} the corner recorded at the last {@link begin}
101
+ */
102
+ previous_corner(cascade, axis) {
103
+ return this.#previous[3 * cascade + axis];
104
+ }
105
+
106
+ /**
107
+ * @param {number} cascade
108
+ * @returns {boolean} whether the cascade's corner changed since the last {@link begin}
109
+ */
110
+ moved(cascade) {
111
+ const base = 3 * cascade;
112
+
113
+ return this.#previous[base] !== this.#corner[base]
114
+ || this.#previous[base + 1] !== this.#corner[base + 1]
115
+ || this.#previous[base + 2] !== this.#corner[base + 2];
116
+ }
117
+
118
+ /**
119
+ * Snapshot every cascade's current corner before a {@link place_all} call so {@link moved} can
120
+ * report which cascades shifted.
121
+ */
122
+ begin() {
123
+ if (!this.#placed) {
124
+ this.#previous.fill(0x7fffffff);
125
+ return;
126
+ }
127
+
128
+ this.#previous.set(this.#corner);
129
+ }
130
+
131
+ /**
132
+ * Place every cascade around `(x, y, z)` in world metres, coarsest first, using a stateless
133
+ * 1-voxel rounding rule with zero hysteresis.
134
+ *
135
+ * @param {number} x
136
+ * @param {number} y
137
+ * @param {number} z
138
+ */
139
+ place_all(x, y, z) {
140
+ assert.isFinite(x, "x");
141
+ assert.isFinite(y, "y");
142
+ assert.isFinite(z, "z");
143
+
144
+ const res = this.#resolution;
145
+ const corner = this.#corner;
146
+
147
+ for (let c = this.#cascade_count - 1; c >= 0; c--) {
148
+ const h = this.cell_size(c);
149
+ const base = 3 * c;
150
+
151
+ let cx = Math.round(x / h - res[0] * 0.5) | 0;
152
+ let cy = Math.round(y / h - res[1] * 0.5) | 0;
153
+ let cz = Math.round(z / h - res[2] * 0.5) | 0;
154
+
155
+ if (c + 1 < this.#cascade_count) {
156
+ const p_base = 3 * (c + 1);
157
+ const px = 2 * corner[p_base];
158
+ const py = 2 * corner[p_base + 1];
159
+ const pz = 2 * corner[p_base + 2];
160
+
161
+ cx = Math.min(px + res[0], Math.max(px, cx));
162
+ cy = Math.min(py + res[1], Math.max(py, cy));
163
+ cz = Math.min(pz + res[2], Math.max(pz, cz));
164
+ }
165
+
166
+ corner[base] = cx;
167
+ corner[base + 1] = cy;
168
+ corner[base + 2] = cz;
169
+ }
170
+
171
+ this.#placed = true;
172
+ }
173
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * {@link chunk_irradiance_clipmap_gi_sample} under IBL: the environment SH (`environment_sh`).
3
+ * @type {CodeChunk}
4
+ */
5
+ export const chunk_irradiance_clipmap_gi_sample_ibl: CodeChunk;
6
+ /**
7
+ * {@link chunk_irradiance_clipmap_gi_sample} under Brick4: the sparse volumetric light map's probes
8
+ * interpolated at `position_ws` with a zero normal (open-space omnidirectional weighting).
9
+ * @type {CodeChunk}
10
+ */
11
+ export const chunk_irradiance_clipmap_gi_sample_brick4: CodeChunk;
12
+ /**
13
+ * {@link chunk_irradiance_clipmap_gi_sample} under LPV: tetrahedral probe interpolation at `position_ws`.
14
+ * @type {CodeChunk}
15
+ */
16
+ export const chunk_irradiance_clipmap_gi_sample_lpv: CodeChunk;
17
+ /**
18
+ * Evaluates indirect radiance SH2 (`array<vec3<f32>, 4>`) at a world position `position_ws` according
19
+ * to the renderer's active {@link INDIRECT_LIGHTING} switch.
20
+ *
21
+ * @type {CodeChunkChoice}
22
+ */
23
+ export const chunk_irradiance_clipmap_gi_sample: CodeChunkChoice;
24
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
25
+ import { CodeChunkChoice } from "../../shader/compiler/CodeChunkChoice.js";
26
+ //# sourceMappingURL=chunk_irradiance_clipmap_gi_sample.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_irradiance_clipmap_gi_sample.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js"],"names":[],"mappings":"AAUA;;;GAGG;AACH,qDAFU,SAAS,CAcjB;AAIF;;;;GAIG;AACH,wDAFU,SAAS,CAYjB;AAEF;;;GAGG;AACH,qDAFU,SAAS,CAqBjB;AAEF;;;;;GAKG;AACH,iDAFU,eAAe,CAEiE;0BAvEhE,oCAAoC;gCAC9B,0CAA0C"}
@@ -0,0 +1,83 @@
1
+ import { chunk_brick4_sample_sh } from "../../global_illumination/brick4/gpu/draw/chunk_brick4_sample_sh.js";
2
+ import { INDIRECT_LIGHTING } from "../../INDIRECT_LIGHTING.js";
3
+ import { ENVIRONMENT_SH_RESOURCE } from "../../light/environment/ENVIRONMENT_SH_RESOURCE.js";
4
+ import { ShadeIndirectLightingMode } from "../../ShadeIndirectLightingMode.js";
5
+ import { chunk_lpv_mesh_interpolation_probe_sh } from "../../shader/chunk/light/lpv/chunk_lpv_mesh_interpolation_probe_sh.js";
6
+ import { chunk_lpv_mesh_lookup_nearest_cell } from "../../shader/chunk/light/lpv/chunk_lpv_mesh_lookup_nearest_cell.js";
7
+ import { INVALID_TET_DECLARATION } from "../../shader/chunk/light/lpv/INVALID_TET_DECLARATION.js";
8
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
9
+ import { CodeChunkChoice } from "../../shader/compiler/CodeChunkChoice.js";
10
+
11
+ /**
12
+ * {@link chunk_irradiance_clipmap_gi_sample} under IBL: the environment SH (`environment_sh`).
13
+ * @type {CodeChunk}
14
+ */
15
+ export const chunk_irradiance_clipmap_gi_sample_ibl = CodeChunk.from(
16
+ //language=WGSL
17
+ `
18
+ fn irradiance_clipmap_gi_sample(position_ws: vec3<f32>) -> array<vec3<f32>, 4> {
19
+ return array<vec3<f32>, 4>(
20
+ environment_sh[0].xyz,
21
+ environment_sh[1].xyz,
22
+ environment_sh[2].xyz,
23
+ environment_sh[3].xyz,
24
+ );
25
+ }
26
+ `, []
27
+ );
28
+
29
+ chunk_irradiance_clipmap_gi_sample_ibl.requireResource(ENVIRONMENT_SH_RESOURCE);
30
+
31
+ /**
32
+ * {@link chunk_irradiance_clipmap_gi_sample} under Brick4: the sparse volumetric light map's probes
33
+ * interpolated at `position_ws` with a zero normal (open-space omnidirectional weighting).
34
+ * @type {CodeChunk}
35
+ */
36
+ export const chunk_irradiance_clipmap_gi_sample_brick4 = CodeChunk.from(
37
+ //language=WGSL
38
+ `
39
+ fn irradiance_clipmap_gi_sample(position_ws: vec3<f32>) -> array<vec3<f32>, 4> {
40
+ let sh = brick4_sample_sh(position_ws, vec3<f32>(0.0));
41
+ return array<vec3<f32>, 4>(sh[0], sh[1], sh[2], sh[3]);
42
+ }
43
+ `, [
44
+ chunk_brick4_sample_sh,
45
+ ]
46
+ );
47
+
48
+ /**
49
+ * {@link chunk_irradiance_clipmap_gi_sample} under LPV: tetrahedral probe interpolation at `position_ws`.
50
+ * @type {CodeChunk}
51
+ */
52
+ export const chunk_irradiance_clipmap_gi_sample_lpv = CodeChunk.from(
53
+ //language=WGSL
54
+ `
55
+ fn irradiance_clipmap_gi_sample(position_ws: vec3<f32>) -> array<vec3<f32>, 4> {
56
+ var weights: vec4<f32>;
57
+ let tet = lpv_mesh_lookup_nearest_cell(position_ws, &weights);
58
+
59
+ var radiance = array<vec3<f32>, 4>();
60
+ if (tet != INVALID_TET) {
61
+ radiance = lpv_mesh_interpolation_probe_sh(weights, tet);
62
+ }
63
+
64
+ return radiance;
65
+ }
66
+ `, [
67
+ chunk_lpv_mesh_lookup_nearest_cell,
68
+ chunk_lpv_mesh_interpolation_probe_sh,
69
+ INVALID_TET_DECLARATION,
70
+ ]
71
+ );
72
+
73
+ /**
74
+ * Evaluates indirect radiance SH2 (`array<vec3<f32>, 4>`) at a world position `position_ws` according
75
+ * to the renderer's active {@link INDIRECT_LIGHTING} switch.
76
+ *
77
+ * @type {CodeChunkChoice}
78
+ */
79
+ export const chunk_irradiance_clipmap_gi_sample = CodeChunkChoice.from(INDIRECT_LIGHTING);
80
+
81
+ chunk_irradiance_clipmap_gi_sample.add(ShadeIndirectLightingMode.IBL, chunk_irradiance_clipmap_gi_sample_ibl);
82
+ chunk_irradiance_clipmap_gi_sample.add(ShadeIndirectLightingMode.Brick4, chunk_irradiance_clipmap_gi_sample_brick4);
83
+ chunk_irradiance_clipmap_gi_sample.add(ShadeIndirectLightingMode.LPV, chunk_irradiance_clipmap_gi_sample_lpv);
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Radially symmetric (isotropic) voxel-footprint-aware point and spot light evaluation for
3
+ * {@link shader_irradiance_clipmap_build}.
4
+ *
5
+ * When a local light of small physical radius `r` sits inside a coarse clipmap voxel grid of spacing
6
+ * `h` (`h > r`), the 8 surrounding voxel centres are displaced radially from the light by up to
7
+ * `sqrt(3)/2 * h ≈ 0.866 * h` (and ~`0.71 * h` across a shared corner/edge). Without radial distance
8
+ * regularization, coarse cascades under-sample the near-light `1 / d^2` peak relative to finer cascades.
9
+ *
10
+ * ## Why Axis-Aligned Box Clamping (`max(abs(L) - 0.5*h, 0)`) Must Not Be Used
11
+ *
12
+ * Clamping each axis independently via `d_box = length(max(abs(L) - vec3(0.5 * h), vec3(0.0)))`
13
+ * zeroes out any coordinate axis within `+/- 0.5 * h` of the light source:
14
+ * - Every voxel inside the central `[-0.5*h, +0.5*h]^3` cube gets `d_box = 0` (a flat-topped cube).
15
+ * - Outside that cube, along the coordinate slabs `|L_x| <= 0.5*h` or `|L_y| <= 0.5*h`, the level
16
+ * sets of `d_box` are flat axis-aligned planes meeting at 90-degree corners (`┐`) instead of
17
+ * spheres, baking rectilinear box boundaries directly into the 3D irradiance texture.
18
+ *
19
+ * To match brightness across cascades without introducing axis-aligned cubic plateaus or directional
20
+ * distortion:
21
+ * - `result.direction` is `L / max(d_center, max(light.radius, 0.5 * cell_size))`: exact Euclidean
22
+ * radial unit vector outside the half-voxel / source sphere, and decaying smoothly (`C^1`) through
23
+ * `0` as `L -> 0` so L1 directional SH coefficients never flip sign across `180°` when a light
24
+ * crosses a voxel centre.
25
+ * - `irradiance_clipmap_regularize_light_distance(d, cell_size)` evaluates a `C^1`-smooth, strictly
26
+ * monotonic quartic polynomial on `t = d / (1.75 * h) in [0, 1]` with `f(0) = 0.35 * h`,
27
+ * `f'(0) = 0` (differentiable across `L = 0`), `f(1) = 1.75 * h`, and `f'(1) = 1.0`, equalling `d`
28
+ * identically in the far field (`d >= 1.75 * h`) with zero `max()` slope kink.
29
+ * - When `light.radius > cell_size` (fine cascades already resolving a large area sphere), the
30
+ * sub-voxel pull blends smoothly toward `d_center` so the sphere cap is not artificially widened.
31
+ *
32
+ * @type {CodeChunk}
33
+ */
34
+ export const chunk_irradiance_clipmap_local_light: CodeChunk;
35
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
36
+ //# sourceMappingURL=chunk_irradiance_clipmap_local_light.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_irradiance_clipmap_local_light.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,mDAFU,SAAS,CAoFjB;0BA/HwB,oCAAoC"}
@@ -0,0 +1,129 @@
1
+ import { LIGHT_DATABASE_SPEC } from "../../light/LIGHT_DATABASE_SPEC.js";
2
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
3
+ import { INCIDENT_LIGHT_STRUCT } from "../../shader/chunk/light/INCIDENT_LIGHT_STRUCT.js";
4
+ import {
5
+ chunk_light_get_spot_attenuation
6
+ } from "../../shader/chunk/light/io/chunk_light_get_spot_attenuation.js";
7
+ import {
8
+ chunk_light_sphere_distance_attenuation
9
+ } from "../../shader/chunk/light/io/chunk_light_sphere_distance_attenuation.js";
10
+
11
+ const POINT_DESCRIPTOR = LIGHT_DATABASE_SPEC.get("light_point");
12
+ const SPOT_DESCRIPTOR = LIGHT_DATABASE_SPEC.get("light_spot");
13
+
14
+ /**
15
+ * Radially symmetric (isotropic) voxel-footprint-aware point and spot light evaluation for
16
+ * {@link shader_irradiance_clipmap_build}.
17
+ *
18
+ * When a local light of small physical radius `r` sits inside a coarse clipmap voxel grid of spacing
19
+ * `h` (`h > r`), the 8 surrounding voxel centres are displaced radially from the light by up to
20
+ * `sqrt(3)/2 * h ≈ 0.866 * h` (and ~`0.71 * h` across a shared corner/edge). Without radial distance
21
+ * regularization, coarse cascades under-sample the near-light `1 / d^2` peak relative to finer cascades.
22
+ *
23
+ * ## Why Axis-Aligned Box Clamping (`max(abs(L) - 0.5*h, 0)`) Must Not Be Used
24
+ *
25
+ * Clamping each axis independently via `d_box = length(max(abs(L) - vec3(0.5 * h), vec3(0.0)))`
26
+ * zeroes out any coordinate axis within `+/- 0.5 * h` of the light source:
27
+ * - Every voxel inside the central `[-0.5*h, +0.5*h]^3` cube gets `d_box = 0` (a flat-topped cube).
28
+ * - Outside that cube, along the coordinate slabs `|L_x| <= 0.5*h` or `|L_y| <= 0.5*h`, the level
29
+ * sets of `d_box` are flat axis-aligned planes meeting at 90-degree corners (`┐`) instead of
30
+ * spheres, baking rectilinear box boundaries directly into the 3D irradiance texture.
31
+ *
32
+ * To match brightness across cascades without introducing axis-aligned cubic plateaus or directional
33
+ * distortion:
34
+ * - `result.direction` is `L / max(d_center, max(light.radius, 0.5 * cell_size))`: exact Euclidean
35
+ * radial unit vector outside the half-voxel / source sphere, and decaying smoothly (`C^1`) through
36
+ * `0` as `L -> 0` so L1 directional SH coefficients never flip sign across `180°` when a light
37
+ * crosses a voxel centre.
38
+ * - `irradiance_clipmap_regularize_light_distance(d, cell_size)` evaluates a `C^1`-smooth, strictly
39
+ * monotonic quartic polynomial on `t = d / (1.75 * h) in [0, 1]` with `f(0) = 0.35 * h`,
40
+ * `f'(0) = 0` (differentiable across `L = 0`), `f(1) = 1.75 * h`, and `f'(1) = 1.0`, equalling `d`
41
+ * identically in the far field (`d >= 1.75 * h`) with zero `max()` slope kink.
42
+ * - When `light.radius > cell_size` (fine cascades already resolving a large area sphere), the
43
+ * sub-voxel pull blends smoothly toward `d_center` so the sphere cap is not artificially widened.
44
+ *
45
+ * @type {CodeChunk}
46
+ */
47
+ export const chunk_irradiance_clipmap_local_light = CodeChunk.from(
48
+ //language=WGSL
49
+ `
50
+ const IRRADIANCE_CLIPMAP_VOXEL_FOOTPRINT_RADIUS: f32 = 0.35;
51
+ const IRRADIANCE_CLIPMAP_VOXEL_RADIAL_SUPPORT: f32 = 1.75;
52
+
53
+ fn irradiance_clipmap_regularize_light_distance(distance: f32, cell_size: f32) -> f32 {
54
+ let h = max(cell_size, 1e-5);
55
+ let support = IRRADIANCE_CLIPMAP_VOXEL_RADIAL_SUPPORT * h;
56
+ if (distance >= support) {
57
+ return distance;
58
+ }
59
+
60
+ let t = max(0.0, distance / support);
61
+ let t2 = t * t;
62
+ return h * (IRRADIANCE_CLIPMAP_VOXEL_FOOTPRINT_RADIUS + t2 * (0.45 + t * (2.95 - 2.00 * t)));
63
+ }
64
+
65
+ fn irradiance_clipmap_get_point_light_info_by_index(
66
+ database: ptr<storage, array<u32>>,
67
+ index: u32,
68
+ position_ws: vec3<f32>,
69
+ cell_size: f32,
70
+ ) -> ${INCIDENT_LIGHT_STRUCT.wgsl_ref} {
71
+ let light = ${POINT_DESCRIPTOR.marshalling_method_read}(database, index);
72
+ let L = light.position.xyz - position_ws;
73
+ let d_center = max(length(L), 1e-5);
74
+ let d_reg = irradiance_clipmap_regularize_light_distance(d_center, cell_size);
75
+ let resolved_blend = saturate(light.radius / max(cell_size, 1e-5) - 1.0);
76
+ let d_eval = mix(d_reg, d_center, resolved_blend);
77
+
78
+ var result: ${INCIDENT_LIGHT_STRUCT.wgsl_ref};
79
+ let dir_radius = max(max(light.radius, 0.5 * cell_size), 1e-5);
80
+ result.direction = L / max(d_center, dir_radius);
81
+
82
+ let attenuation = light_sphere_distance_attenuation(d_eval, light.radius, light.distance);
83
+ result.color = light.color * attenuation;
84
+ result.radius = light.radius / d_center;
85
+ result.distance = max(0.0, d_center - light.radius);
86
+
87
+ return result;
88
+ }
89
+
90
+ fn irradiance_clipmap_get_spot_light_info_by_index(
91
+ database: ptr<storage, array<u32>>,
92
+ index: u32,
93
+ position_ws: vec3<f32>,
94
+ cell_size: f32,
95
+ ) -> ${INCIDENT_LIGHT_STRUCT.wgsl_ref} {
96
+ let light = ${SPOT_DESCRIPTOR.marshalling_method_read}(database, index);
97
+ let L = light.position - position_ws;
98
+ let d_center = max(length(L), 1e-5);
99
+ let d_reg = irradiance_clipmap_regularize_light_distance(d_center, cell_size);
100
+ let resolved_blend = saturate(light.radius / max(cell_size, 1e-5) - 1.0);
101
+ let d_eval = mix(d_reg, d_center, resolved_blend);
102
+ let unit_dir = L / d_center;
103
+
104
+ var result: ${INCIDENT_LIGHT_STRUCT.wgsl_ref};
105
+ let dir_radius = max(max(light.radius, 0.5 * cell_size), 1e-5);
106
+ result.direction = L / max(d_center, dir_radius);
107
+ result.distance = max(0.0, d_center - light.radius);
108
+ result.radius = light.radius / d_center;
109
+
110
+ let angle_cos = dot(unit_dir, -light.direction);
111
+ let spot_attenuation = light_get_spot_attenuation(light.coneCos, light.penumbraCos, angle_cos);
112
+
113
+ if (spot_attenuation > 0.0) {
114
+ result.color = light.color * spot_attenuation;
115
+ result.color *= light_sphere_distance_attenuation(d_eval, light.radius, light.distance);
116
+ } else {
117
+ result.color = vec3<f32>(0.0);
118
+ }
119
+
120
+ return result;
121
+ }
122
+ `, [
123
+ POINT_DESCRIPTOR.chunk_read,
124
+ SPOT_DESCRIPTOR.chunk_read,
125
+ INCIDENT_LIGHT_STRUCT.declaration_chunk,
126
+ chunk_light_get_spot_attenuation,
127
+ chunk_light_sphere_distance_attenuation,
128
+ ]
129
+ );