@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
@@ -56,19 +56,19 @@ export class GPUTileAtlas3D {
56
56
  #device;
57
57
 
58
58
  /**
59
- * @type {GPUTextureContext}
59
+ * @type {readonly GPUTextureContext[]}
60
60
  */
61
- #texture;
61
+ #textures;
62
62
 
63
63
  /**
64
- * @type {GPUTextureFormat}
64
+ * @type {readonly GPUTextureFormat[]}
65
65
  */
66
- #format;
66
+ #formats;
67
67
 
68
68
  /**
69
- * @type {number}
69
+ * @type {readonly number[]}
70
70
  */
71
- #bytes_per_texel;
71
+ #bytes_per_texel_list;
72
72
 
73
73
  /**
74
74
  * Texels of content along x, y and z.
@@ -142,12 +142,15 @@ export class GPUTileAtlas3D {
142
142
  #label;
143
143
 
144
144
  /**
145
- * Every argument is required: an atlas is declared, not configured.
145
+ * Every argument is required: an atlas is declared, not configured. Either `format` (one texture)
146
+ * or `formats` (one or more synchronized textures sharing the same slot grid) must be given.
146
147
  *
147
148
  * @param {object} options
148
149
  * @param {GPUDevice} options.device
149
- * @param {GPUTextureFormat} options.format an uncompressed, copyable format — what a 3-D texture
150
- * allows, and what {@link write} sizes its block by
150
+ * @param {GPUTextureFormat} [options.format] an uncompressed, copyable format — what a 3-D texture
151
+ * allows, and what {@link write} sizes its block by (mutually exclusive with `formats`)
152
+ * @param {GPUTextureFormat[]} [options.formats] one or more uncompressed, copyable formats for a
153
+ * multi-texture atlas (mutually exclusive with `format`)
151
154
  * @param {number[]} options.content_size texels of content along x, y and z of a tile, three
152
155
  * positive integers; a cubic tile is `[n, n, n]`. Copied: the array stays the caller's
153
156
  * @param {number} options.border texels of skirt on each side of the content, at least 1 for a
@@ -164,9 +167,19 @@ export class GPUTileAtlas3D {
164
167
  * are copies
165
168
  * @param {string} options.label the texture's label
166
169
  */
167
- constructor({ device, format, content_size, border, slots_x, slots_y, capacity, usage, label }) {
170
+ constructor({ device, formats, content_size, border, slots_x, slots_y, capacity, usage, label }) {
168
171
  assert.defined(device, 'device');
169
- assert.isString(format, 'format');
172
+ const format_list = formats;
173
+
174
+
175
+
176
+ assert.isArrayLike(format_list, 'formats');
177
+ assert.greaterThan(format_list.length, 0, 'formats must not be empty');
178
+
179
+ for (let i = 0; i < format_list.length; i++) {
180
+ assert.isString(format_list[i], `formats[${i}]`);
181
+ }
182
+
170
183
  assert.isArrayLike(content_size, 'content_size');
171
184
  assert.equal(content_size.length, 3, 'content_size is texels along x, y and z');
172
185
  assert.isPositiveInteger(content_size[0], 'content_size[0]');
@@ -184,14 +197,21 @@ export class GPUTileAtlas3D {
184
197
  assert.greaterThan(usage, 0, 'usage: a texture no shader binds is not an atlas anyone reads');
185
198
  assert.isString(label, 'label');
186
199
 
187
- const info = gpu_texture_format_info(format);
200
+ const bytes_per_texel_list = [];
201
+
202
+ for (let i = 0; i < format_list.length; i++) {
203
+ const fmt = format_list[i];
204
+ const info = gpu_texture_format_info(fmt);
205
+
206
+ assert.equal(info.block_width, 1, `${fmt} is block-compressed; a 3-D texture cannot be`);
207
+ assert.equal(info.copyable, true, `${fmt} cannot be copied into, and a tile is written by copy`);
188
208
 
189
- assert.equal(info.block_width, 1, `${format} is block-compressed; a 3-D texture cannot be`);
190
- assert.equal(info.copyable, true, `${format} cannot be copied into, and a tile is written by copy`);
209
+ bytes_per_texel_list.push(info.bytes_per_block);
210
+ }
191
211
 
192
212
  this.#device = device;
193
- this.#format = format;
194
- this.#bytes_per_texel = info.bytes_per_block;
213
+ this.#formats = Object.freeze([...format_list]);
214
+ this.#bytes_per_texel_list = Object.freeze(bytes_per_texel_list);
195
215
  this.#content_size = Object.freeze([content_size[0], content_size[1], content_size[2]]);
196
216
  this.#border = border;
197
217
 
@@ -212,20 +232,26 @@ export class GPUTileAtlas3D {
212
232
  this.#slots_y = slots_y;
213
233
  this.#label = label;
214
234
 
215
- const texture = new GPUTextureContext(device);
216
- const td = texture.descriptor;
235
+ const textures = [];
236
+
237
+ for (let i = 0; i < format_list.length; i++) {
238
+ const texture = new GPUTextureContext(device);
239
+ const td = texture.descriptor;
240
+
241
+ td.label = format_list.length === 1 ? label : `${label}[${i}]`;
242
+ td.format = format_list[i];
243
+ td.dimension = "3d";
244
+ td.mipLevelCount = 1;
245
+ // bound however the clients said, written by host writes and device copies, and copied out
246
+ // of itself when it grows
247
+ td.usage = usage
248
+ | GPUTextureUsage.COPY_DST
249
+ | GPUTextureUsage.COPY_SRC;
217
250
 
218
- td.label = label;
219
- td.format = format;
220
- td.dimension = "3d";
221
- td.mipLevelCount = 1;
222
- // bound however the clients said, written by host writes and device copies, and copied out
223
- // of itself when it grows
224
- td.usage = usage
225
- | GPUTextureUsage.COPY_DST
226
- | GPUTextureUsage.COPY_SRC;
251
+ textures.push(texture);
252
+ }
227
253
 
228
- this.#texture = texture;
254
+ this.#textures = Object.freeze(textures);
229
255
 
230
256
  assert.lessThanOrEqual(slots_x, this.#limit_x, `slots_x ${slots_x} of ${tile_x} texels exceed maxTextureDimension3D ${max_dimension}`);
231
257
  assert.lessThanOrEqual(slots_y, this.#limit_y, `slots_y ${slots_y} of ${tile_y} texels exceed maxTextureDimension3D ${max_dimension}`);
@@ -242,21 +268,76 @@ export class GPUTileAtlas3D {
242
268
  * @returns {GPUTextureContext}
243
269
  */
244
270
  get texture() {
245
- return this.#texture;
271
+ return this.#textures[0];
272
+ }
273
+
274
+ /**
275
+ * All synchronized textures of the atlas.
276
+ * @returns {readonly GPUTextureContext[]}
277
+ */
278
+ get textures() {
279
+ return this.#textures;
280
+ }
281
+
282
+ /**
283
+ * @returns {number}
284
+ */
285
+ get texture_count() {
286
+ return this.#textures.length;
287
+ }
288
+
289
+ /**
290
+ * @param {number} index
291
+ * @returns {GPUTextureContext}
292
+ */
293
+ texture_at(index) {
294
+ assert.isNonNegativeInteger(index, 'index');
295
+ assert.lessThan(index, this.#textures.length, 'index');
296
+
297
+ return this.#textures[index];
246
298
  }
247
299
 
248
300
  /**
249
301
  * @returns {GPUTextureFormat}
250
302
  */
251
303
  get format() {
252
- return this.#format;
304
+ return this.#formats[0];
305
+ }
306
+
307
+ /**
308
+ * @returns {readonly GPUTextureFormat[]}
309
+ */
310
+ get formats() {
311
+ return this.#formats;
312
+ }
313
+
314
+ /**
315
+ * @param {number} index
316
+ * @returns {GPUTextureFormat}
317
+ */
318
+ format_at(index) {
319
+ assert.isNonNegativeInteger(index, 'index');
320
+ assert.lessThan(index, this.#formats.length, 'index');
321
+
322
+ return this.#formats[index];
253
323
  }
254
324
 
255
325
  /**
256
326
  * @returns {number}
257
327
  */
258
328
  get bytes_per_texel() {
259
- return this.#bytes_per_texel;
329
+ return this.#bytes_per_texel_list[0];
330
+ }
331
+
332
+ /**
333
+ * @param {number} index
334
+ * @returns {number}
335
+ */
336
+ bytes_per_texel_at(index) {
337
+ assert.isNonNegativeInteger(index, 'index');
338
+ assert.lessThan(index, this.#bytes_per_texel_list.length, 'index');
339
+
340
+ return this.#bytes_per_texel_list[index];
260
341
  }
261
342
 
262
343
  /**
@@ -407,13 +488,16 @@ export class GPUTileAtlas3D {
407
488
  * @param {number} slot a live slot
408
489
  * @param {Uint8Array} content `content_size[0] · content_size[1] · content_size[2] ·
409
490
  * bytes_per_texel` bytes, x fastest, then y, then z
491
+ * @param {number} [texture_index=0] which texture of the atlas to write into
410
492
  */
411
- write(slot, content) {
493
+ write(slot, content, texture_index = 0) {
412
494
  assert.ok(this.is_live(slot), `slot ${slot} is not allocated`);
413
495
  assert.isInstanceOf(content, Uint8Array, 'content');
496
+ assert.isNonNegativeInteger(texture_index, 'texture_index');
497
+ assert.lessThan(texture_index, this.#textures.length, 'texture_index');
414
498
 
415
499
  const n = this.#content_size;
416
- const bpt = this.#bytes_per_texel;
500
+ const bpt = this.#bytes_per_texel_list[texture_index];
417
501
 
418
502
  assert.equal(content.length, n[0] * n[1] * n[2] * bpt, `content holds ${content.length} bytes; a tile's content is ${n[0]}×${n[1]}×${n[2]} texels of ${bpt} bytes`);
419
503
 
@@ -426,7 +510,7 @@ export class GPUTileAtlas3D {
426
510
 
427
511
  this.#device.queue.writeTexture(
428
512
  {
429
- texture: this.#texture.gpu_texture,
513
+ texture: this.#textures[texture_index].gpu_texture,
430
514
  mipLevel: 0,
431
515
  origin: this.slot_origin(slot, [0, 0, 0]),
432
516
  },
@@ -451,20 +535,23 @@ export class GPUTileAtlas3D {
451
535
  * @param {number} byte_offset where the block starts in the buffer
452
536
  * @param {number} bytes_per_row stride of a row of `tile_size[0]` texels, a multiple of
453
537
  * `COPY_BYTES_PER_ROW_ALIGNMENT`; rows per image is `tile_size[1]`
538
+ * @param {number} [texture_index=0] which texture of the atlas to copy into
454
539
  */
455
- copy_from_buffer(encoder, slot, buffer, byte_offset, bytes_per_row) {
540
+ copy_from_buffer(encoder, slot, buffer, byte_offset, bytes_per_row, texture_index = 0) {
456
541
  assert.defined(encoder, 'encoder');
457
542
  assert.ok(this.is_live(slot), `slot ${slot} is not allocated`);
458
543
  assert.defined(buffer, 'buffer');
459
544
  assert.isNonNegativeInteger(byte_offset, 'byte_offset');
460
545
  assert.isNonNegativeInteger(bytes_per_row, 'bytes_per_row');
546
+ assert.isNonNegativeInteger(texture_index, 'texture_index');
547
+ assert.lessThan(texture_index, this.#textures.length, 'texture_index');
461
548
 
462
549
  const tile = this.#tile_size;
463
550
  const tx = tile[0];
464
551
  const ty = tile[1];
465
552
  const tz = tile[2];
466
553
 
467
- assert.greaterThanOrEqual(bytes_per_row, tx * this.#bytes_per_texel, 'bytes_per_row is shorter than a row of the tile');
554
+ assert.greaterThanOrEqual(bytes_per_row, tx * this.#bytes_per_texel_list[texture_index], 'bytes_per_row is shorter than a row of the tile');
468
555
 
469
556
  encoder.copyBufferToTexture(
470
557
  {
@@ -474,7 +561,7 @@ export class GPUTileAtlas3D {
474
561
  rowsPerImage: ty,
475
562
  },
476
563
  {
477
- texture: this.#texture.gpu_texture,
564
+ texture: this.#textures[texture_index].gpu_texture,
478
565
  mipLevel: 0,
479
566
  origin: this.slot_origin(slot, [0, 0, 0]),
480
567
  },
@@ -483,7 +570,9 @@ export class GPUTileAtlas3D {
483
570
  }
484
571
 
485
572
  destroy() {
486
- this.#texture.destroy();
573
+ for (let i = 0; i < this.#textures.length; i++) {
574
+ this.#textures[i].destroy();
575
+ }
487
576
  }
488
577
 
489
578
  /**
@@ -508,8 +597,14 @@ export class GPUTileAtlas3D {
508
597
  this.#slots_z = layers;
509
598
  this.#resize_live();
510
599
 
600
+ const width = this.#slots_x * tile[0];
601
+ const height = this.#slots_y * tile[1];
602
+ const depth = layers * tile[2];
603
+
511
604
  // preserve: a new layer keeps every tile where it was, because x and y do not change
512
- this.#texture.resize(this.#slots_x * tile[0], this.#slots_y * tile[1], layers * tile[2], true);
605
+ for (let i = 0; i < this.#textures.length; i++) {
606
+ this.#textures[i].resize(width, height, depth, true);
607
+ }
513
608
  }
514
609
 
515
610
  /**
@@ -538,13 +633,18 @@ export class GPUTileAtlas3D {
538
633
  const layers = Math.ceil((this.capacity + 1) / (nx * ny));
539
634
 
540
635
  const device = this.#device;
541
- const texture = this.#texture;
542
-
543
- const source = texture.gpu_texture;
636
+ const textures = this.#textures;
637
+ const texture_count = textures.length;
544
638
 
545
- texture.descriptor.size = [nx * tx, ny * ty, layers * tz];
639
+ const sources = new Array(texture_count);
640
+ const destinations = new Array(texture_count);
546
641
 
547
- const destination = device.createTexture(texture.descriptor);
642
+ for (let i = 0; i < texture_count; i++) {
643
+ const texture = textures[i];
644
+ sources[i] = texture.gpu_texture;
645
+ texture.descriptor.size = [nx * tx, ny * ty, layers * tz];
646
+ destinations[i] = device.createTexture(texture.descriptor);
647
+ }
548
648
 
549
649
  const encoder = device.createCommandEncoder({
550
650
  label: `${this.#label} / widen`
@@ -562,19 +662,21 @@ export class GPUTileAtlas3D {
562
662
 
563
663
  const run = Math.min(sx - from[0], nx - to[0], count - slot);
564
664
 
565
- encoder.copyTextureToTexture(
566
- {
567
- texture: source,
568
- mipLevel: 0,
569
- origin: [from[0] * tx, from[1] * ty, from[2] * tz],
570
- },
571
- {
572
- texture: destination,
573
- mipLevel: 0,
574
- origin: [to[0] * tx, to[1] * ty, to[2] * tz],
575
- },
576
- [run * tx, ty, tz]
577
- );
665
+ for (let i = 0; i < texture_count; i++) {
666
+ encoder.copyTextureToTexture(
667
+ {
668
+ texture: sources[i],
669
+ mipLevel: 0,
670
+ origin: [from[0] * tx, from[1] * ty, from[2] * tz],
671
+ },
672
+ {
673
+ texture: destinations[i],
674
+ mipLevel: 0,
675
+ origin: [to[0] * tx, to[1] * ty, to[2] * tz],
676
+ },
677
+ [run * tx, ty, tz]
678
+ );
679
+ }
578
680
 
579
681
  slot += run;
580
682
  }
@@ -582,7 +684,9 @@ export class GPUTileAtlas3D {
582
684
  device.queue.submit([encoder.finish()]);
583
685
 
584
686
  // destroys the old texture; the copies out of it were submitted first
585
- texture.replace(destination);
687
+ for (let i = 0; i < texture_count; i++) {
688
+ textures[i].replace(destinations[i]);
689
+ }
586
690
 
587
691
  this.#slots_x = nx;
588
692
  this.#slots_y = ny;
@@ -137,7 +137,7 @@ export class GPUSceneVolumetrics {
137
137
 
138
138
  this.#noise_atlas = new GPUTileAtlas3D({
139
139
  device,
140
- format: PARTICIPATING_MEDIA_NOISE_TILE_FORMAT,
140
+ formats: [PARTICIPATING_MEDIA_NOISE_TILE_FORMAT],
141
141
  // a cube: the bake makes the same number of features along every edge
142
142
  content_size: [PARTICIPATING_MEDIA_NOISE_TILE_CONTENT_SIZE, PARTICIPATING_MEDIA_NOISE_TILE_CONTENT_SIZE, PARTICIPATING_MEDIA_NOISE_TILE_CONTENT_SIZE],
143
143
  border: PARTICIPATING_MEDIA_NOISE_TILE_BORDER,
@@ -21,6 +21,10 @@ export class GPUViewVolumetrics {
21
21
  * @returns {number}
22
22
  */
23
23
  get froxel_far(): number;
24
+ /**
25
+ * @returns {GPUIrradianceClipmap}
26
+ */
27
+ get irradiance_clipmap(): GPUIrradianceClipmap;
24
28
  destroy(): void;
25
29
  /**
26
30
  *
@@ -30,18 +34,10 @@ export class GPUViewVolumetrics {
30
34
  * @param {number} options.light_cluster_lookup
31
35
  * @param {number} options.light_cluster_parameters
32
36
  * @param {number} options.shadowmap_atlas
33
- * @param {ShaderSwitchSet} [options.shader_switches] the renderer's; the passes that light froxels are built
34
- * for them, the froxel GI that starts the froxel irradiance volume among them
35
- * @param {import("../global_illumination/brick4/Brick4LightMap.js").Brick4LightMap} [options.brick4] the scene's,
36
- * while Brick4 runs
37
- * @param {import("../global_illumination/lpv/GPULightProbeVolume.js").GPULightProbeVolume} [options.lpv] the
38
- * scene's, while LPV runs
39
- * @returns {{resolved: number, metadata: number, irradiance: {Y: number, CoCg: number}}} the
40
- * integrated aerial LUT, the metadata buffer, and the froxel irradiance volume
41
- * (chunk_volumetrics_irradiance_sh) that lit particles are lit by. The two do not depend on
42
- * each other, and a pass building only one of them is culled when nothing reads it. A scene
43
- * with no participating-media volume records no fog at all, and `resolved` is then a constant:
44
- * no in-scatter, full transmittance.
37
+ * @param {ShaderSwitchSet} [options.shader_switches]
38
+ * @param {import("../global_illumination/brick4/Brick4LightMap.js").Brick4LightMap} [options.brick4]
39
+ * @param {import("../global_illumination/lpv/GPULightProbeVolume.js").GPULightProbeVolume} [options.lpv]
40
+ * @returns {{resolved: number, metadata: number, irradiance: {Y: number, CoCg: number, uniform: number}}}
45
41
  */
46
42
  graph_update({ graph, light_cluster_data, light_cluster_lookup, light_cluster_parameters, shadowmap_atlas, shader_switches, brick4, lpv, }: {
47
43
  graph: FrameGraph;
@@ -58,11 +54,13 @@ export class GPUViewVolumetrics {
58
54
  irradiance: {
59
55
  Y: number;
60
56
  CoCg: number;
57
+ uniform: number;
61
58
  };
62
59
  };
63
60
  #private;
64
61
  }
65
62
  export type FrameGraph = import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
66
63
  export type GPUViewContext = import("../view/GPUViewContext.js").GPUViewContext;
64
+ import { GPUIrradianceClipmap } from "./irradiance_clipmap/GPUIrradianceClipmap.js";
67
65
  import { ShaderSwitchSet } from "../shader/compiler/ShaderSwitchSet.js";
68
66
  //# sourceMappingURL=GPUViewVolumetrics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GPUViewVolumetrics.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/GPUViewVolumetrics.js"],"names":[],"mappings":"AAmCA;IA2II;;;;OAIG;IACH,kBAHW,cAAc,qBAyCxB;IAlJD;;OAEG;IACH,4BAOC;IAjBD;;OAEG;IACH,2BAEC;IAsCD;;OAEG;IACH,0BAEC;IAZD;;OAEG;IACH,yBAEC;IAkHD,gBAaC;IA6ND;;;;;;;;;;;;;;;;;;;;OAoBG;IACH;QAlB+B,KAAK,EAAzB,UAAU;QACM,kBAAkB,EAAlC,MAAM;QACU,oBAAoB,EAApC,MAAM;QACU,wBAAwB,EAAxC,MAAM;QACU,eAAe,EAA/B,MAAM;QACoB,eAAe,GAAzC,eAAe;QAEoE,MAAM,GAAzF,OAAO,iDAAiD,EAAE,cAAc;QAEkB,GAAG,GAA7F,OAAO,mDAAmD,EAAE,mBAAmB;QAE7E;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAC,CAAA;KAAC,CAwIvF;;CAEJ;yBAnkBY,OAAO,2DAA2D,EAAE,UAAU;6BAC9E,OAAO,2BAA2B,EAAE,cAAc;gCAf/B,uCAAuC"}
1
+ {"version":3,"file":"GPUViewVolumetrics.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/GPUViewVolumetrics.js"],"names":[],"mappings":"AAiCA;IAiJI;;;;OAIG;IACH,kBAHW,cAAc,qBA2CxB;IA1JD;;OAEG;IACH,4BAOC;IAjBD;;OAEG;IACH,2BAEC;IAsCD;;OAEG;IACH,0BAEC;IAZD;;OAEG;IACH,yBAEC;IA0HD;;OAEG;IACH,+CAEC;IAED,gBAcC;IA6ND;;;;;;;;;;;;OAYG;IACH;QAV+B,KAAK,EAAzB,UAAU;QACM,kBAAkB,EAAlC,MAAM;QACU,oBAAoB,EAApC,MAAM;QACU,wBAAwB,EAAxC,MAAM;QACU,eAAe,EAA/B,MAAM;QACoB,eAAe,GAAzC,eAAe;QACoE,MAAM,GAAzF,OAAO,iDAAiD,EAAE,cAAc;QACkB,GAAG,GAA7F,OAAO,mDAAmD,EAAE,mBAAmB;QAC7E;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAC,CAAA;KAAC,CAsGxG;;CAEJ;yBA9iBY,OAAO,2DAA2D,EAAE,UAAU;6BAC9E,OAAO,2BAA2B,EAAE,cAAc;qCAZ1B,8CAA8C;gCAXnD,uCAAuC"}