@woosh/meep-engine 3.53.0 → 3.54.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 (194) 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/graphics/texture/atlas/SpriteAtlasFill.d.ts +12 -0
  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/graphics/texture/atlas/sprite_atlas_border.d.ts +52 -0
  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/playground/foliage_wind/foliage_world.d.ts +6 -0
  68. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  69. package/src/shade/playground/foliage_wind/foliage_world.js +602 -593
  70. package/src/shade/playground/foliage_wind/index.html +260 -254
  71. package/src/shade/playground/foliage_wind/main.js +275 -263
  72. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  73. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  74. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  75. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  76. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  77. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +1 -1
  78. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +3 -3
  79. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  80. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +350 -294
  81. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts +0 -2
  82. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts.map +1 -1
  83. package/src/shade/renderer/hiz/generate_downsampler_code.js +99 -100
  84. package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts +15 -0
  85. package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts.map +1 -0
  86. package/src/shade/renderer/hiz/hzb_pick_alignment.js +148 -0
  87. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.d.ts +28 -0
  88. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.d.ts.map +1 -0
  89. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.js +58 -0
  90. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +5 -5
  91. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  92. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +57 -67
  93. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +3 -3
  94. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
  95. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +111 -112
  96. package/src/shade/renderer/hiz/shader_hzb_spd.d.ts +5 -0
  97. package/src/shade/renderer/hiz/shader_hzb_spd.d.ts.map +1 -0
  98. package/src/shade/renderer/hiz/shader_hzb_spd.js +160 -0
  99. package/src/shade/renderer/light/GPULightCollection.d.ts +8 -0
  100. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  101. package/src/shade/renderer/light/GPULightCollection.js +67 -0
  102. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.d.ts +7 -0
  103. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.d.ts.map +1 -0
  104. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.js +13 -0
  105. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.d.ts +10 -0
  106. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.d.ts.map +1 -0
  107. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.js +72 -0
  108. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts +39 -0
  109. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts.map +1 -0
  110. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.js +90 -0
  111. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts +12 -0
  112. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts.map +1 -0
  113. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.js +56 -0
  114. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts +31 -0
  115. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts.map +1 -0
  116. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.js +196 -0
  117. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts +10 -0
  118. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts.map +1 -0
  119. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js +163 -0
  120. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.d.ts +4 -0
  121. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.d.ts.map +1 -0
  122. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.js +137 -0
  123. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  124. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  125. package/src/shade/renderer/particles/GPUParticleSystem.js +4 -3
  126. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +4 -3
  127. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  128. package/src/shade/renderer/particles/graph_particles_avboit.js +28 -11
  129. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +9 -13
  130. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +25 -20
  132. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  133. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +21 -38
  134. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  135. package/src/shade/renderer/shader/chunk/depth/chunk_query_depth_from_screen_space_bb.d.ts.map +1 -1
  136. package/src/shade/renderer/shader/chunk/depth/chunk_query_depth_from_screen_space_bb.js +62 -62
  137. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.d.ts +6 -0
  138. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.d.ts.map +1 -0
  139. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.js +19 -0
  140. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_get_mip_resolution.d.ts.map +1 -1
  141. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_get_mip_resolution.js +16 -10
  142. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.d.ts.map +1 -1
  143. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.js +118 -117
  144. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +41 -7
  145. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -1
  146. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +162 -58
  147. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +1 -1
  148. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +10 -12
  149. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  150. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +583 -606
  151. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts +24 -0
  152. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts.map +1 -0
  153. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +1 -1
  154. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +1 -1
  155. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +640 -640
  156. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +113 -0
  157. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -0
  158. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +484 -0
  159. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts +50 -0
  160. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts.map +1 -0
  161. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.js +60 -0
  162. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts +25 -0
  163. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts.map +1 -0
  164. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.js +47 -0
  165. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.d.ts +74 -0
  166. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.d.ts.map +1 -0
  167. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.js +173 -0
  168. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +26 -0
  169. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -0
  170. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +83 -0
  171. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts +31 -0
  172. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts.map +1 -0
  173. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.js +113 -0
  174. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts +121 -0
  175. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts.map +1 -0
  176. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js +356 -0
  177. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts +16 -0
  178. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts.map +1 -0
  179. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.js +191 -0
  180. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts +16 -0
  181. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts.map +1 -0
  182. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts +23 -0
  183. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts.map +1 -0
  184. package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
  185. package/src/shade/renderer/wind/GPUSceneWind.js +1 -1
  186. package/src/engine/graphics3/decal/DecalAtlasFill.js +0 -32
  187. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +0 -49
  188. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +0 -50
  189. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.js +0 -105
  190. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +0 -80
  191. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.js +0 -51
  192. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +0 -39
  193. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +0 -121
  194. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +0 -237
@@ -1,294 +1,350 @@
1
- import { assert } from "../../../core/assert.js";
2
- import { max2 } from "../../../core/math/max2.js";
3
- import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
4
- import { TextureViewDescriptor } from "../../descriptor/texture/TextureViewDescriptor.js";
5
- import { texture_mip_level_count } from "../../util/texture_mip_extent.js";
6
- import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
7
- import { shader_hzb_reduce_any, shader_hzb_reduce_mip0 } from "./shader_hzb_reduce_any.js";
8
- import { shader_hzb_reduce_mip0_clip } from "./shader_hzb_reduce_mip0_clip.js";
9
-
10
- /**
11
- * @typedef {import("../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
12
- * @typedef {import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext} ShadeGPUCommandContext
13
- * @typedef {import("../GraphicsContext.js").GraphicsContext} GraphicsContext
14
- * @typedef {import("../texture/GPUTextureContext.js").GPUTextureContext} GPUTextureContext
15
- */
16
-
17
- export class HierarchicalZBuffer {
18
-
19
- /**
20
- * @type {GPUTextureContext}
21
- */
22
- #texture;
23
-
24
- /**
25
- * @type {string|GPUTextureFormat}
26
- */
27
- #format = HZB_TEXTURE_FORMAT
28
-
29
- /**
30
- * Offer the pipelines {@link build} draws with — see {@link PipelineEnquiry}. A viewport that
31
- * clips part of its source draws mip 0 with {@link shader_hzb_reduce_mip0_clip} instead, which
32
- * is left to the frame that does that.
33
- *
34
- * @param {PipelineEnquiry} enquiry
35
- */
36
- static enquirePipelines(enquiry) {
37
- enquiry.render.push(shader_hzb_reduce_mip0.pipeline);
38
- enquiry.render.push(shader_hzb_reduce_any.pipeline);
39
- }
40
-
41
- /**
42
- *
43
- * @returns {GPUTextureContext}
44
- */
45
- get texture() {
46
- return this.#texture;
47
- }
48
-
49
-
50
- /**
51
- * @type {GraphicsContext}
52
- */
53
- #graphics;
54
-
55
- /**
56
- *
57
- * @type {number[]}
58
- */
59
- #viewport_size = [1, 1];
60
-
61
- /**
62
- *
63
- * @param {GraphicsContext} graphics
64
- */
65
- constructor(graphics) {
66
- this.#graphics = graphics;
67
-
68
- this.#texture = graphics.textures.contextFromDescriptor(TextureDescriptor.from({
69
- label: "Hierarchical Z Buffer",
70
- format: this.#format,
71
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT,
72
- mipLevelCount: 1,
73
- size: [1, 1]
74
- }));
75
-
76
-
77
- }
78
-
79
- /**
80
- *
81
- * @param {ShadeGPUCommandContext} encoder
82
- * @param {GPUTextureContext} source
83
- * @param {number[]} [source_offset] [x0,y0]
84
- */
85
- build(
86
- encoder,
87
- source,
88
- source_offset
89
- ) {
90
-
91
- assert.defined(encoder, 'encoder');
92
- assert.notNull(encoder, 'encoder');
93
- assert.equal(encoder.isGPUCommandContext, true, 'encoder is not a GPUCommandContext')
94
-
95
- assert.defined(source, 'source');
96
- assert.notNull(source, 'source');
97
- assert.equal(source.isGPUTextureContext, true, 'source is not a GPUTextureContext')
98
-
99
- // the first pass is special, we need to read from source texture and write to first mip level of hzb
100
-
101
- const texture = this.#texture;
102
-
103
- assert.equal(texture.isDestroyed, false, 'texture is destroyed');
104
-
105
- const mipLevelCount = texture.descriptor.mipLevelCount;
106
-
107
- let source_view = source.obtainView(TextureViewDescriptor.from({
108
- baseMipLevel: 0,
109
- mipLevelCount: 1,
110
- dimension: "2d",
111
- baseArrayLayer: 0,
112
- arrayLayerCount: 1
113
- }));
114
-
115
- const destination_view = texture.obtainView(TextureViewDescriptor.from({
116
- baseMipLevel: 0,
117
- mipLevelCount: 1,
118
- dimension: "2d",
119
- baseArrayLayer: 0,
120
- arrayLayerCount: 1
121
- }));
122
-
123
- const viewport_size = this.#viewport_size;
124
-
125
- const is_clipped_variant = source_offset !== undefined
126
- && (
127
- (
128
- source_offset[0] !== 0
129
- || source_offset[1] !== 0
130
- )
131
- || (
132
- viewport_size[0] !== source.width
133
- || viewport_size[1] !== source.height
134
- )
135
- );
136
-
137
- if (is_clipped_variant) {
138
- // special case for clip region
139
-
140
- shader_hzb_reduce_mip0_clip.draw({
141
- encoder,
142
- bindings: {
143
- tInput: source_view,
144
- settings: {
145
- clip_region: [
146
- source_offset[0], source_offset[1],
147
- viewport_size[0], viewport_size[1],
148
- ],
149
- output_resolution: this.#mip_resolution(0),
150
- },
151
- },
152
- colorAttachments: [{
153
- view: destination_view,
154
- loadOp: 'clear',
155
- storeOp: 'store'
156
- }]
157
- })
158
- } else {
159
-
160
- this.#do_reduction_pass(encoder, shader_hzb_reduce_mip0, source_view, destination_view, 0);
161
- }
162
-
163
- source_view = destination_view;
164
-
165
- for (let i = 1; i < mipLevelCount; i++) {
166
-
167
- const destination_view = texture.obtainView(TextureViewDescriptor.from({
168
- baseMipLevel: i,
169
- mipLevelCount: 1,
170
- dimension: "2d",
171
- baseArrayLayer: 0,
172
- arrayLayerCount: 1
173
- }));
174
-
175
- this.#do_reduction_pass(encoder, shader_hzb_reduce_any, source_view, destination_view, i);
176
-
177
- // swap
178
- source_view = destination_view;
179
- }
180
- }
181
-
182
- /**
183
- *
184
- * @param {ShadeGPUCommandContext} encoder
185
- * @param {ImageShader} shader
186
- * @param {GPUTextureView} source_view
187
- * @param {GPUTextureView} destination_view
188
- * @param {number} index
189
- * @param {number[]} [viewport]
190
- */
191
- #do_reduction_pass(
192
- encoder,
193
- shader,
194
- source_view,
195
- destination_view,
196
- index,
197
- viewport
198
- ) {
199
-
200
- shader.draw({
201
- encoder,
202
- bindings: {
203
- tInput: source_view,
204
- output_resolution: this.#mip_resolution(index),
205
- },
206
- colorAttachments: [
207
- {
208
- view: destination_view,
209
- loadOp: 'clear',
210
- storeOp: 'store'
211
- }
212
- ],
213
- viewport
214
- })
215
-
216
- }
217
-
218
- /**
219
- * Scratch for {@link #mip_resolution}. The value is serialised into the pass's immediate bytes
220
- * before the next call, so one array can serve every mip.
221
- *
222
- * @type {number[]}
223
- */
224
- #mip_resolution_scratch = [1, 1];
225
-
226
- /**
227
- * Size of mip `index` of the HZB, which is what the reduction pass writing into it needs to know.
228
- *
229
- * Each mip halves the one above it, floored at one texel — the same walk that used to be
230
- * precomputed into a uniform buffer of every mip's resolution and bound at a per-mip dynamic
231
- * offset. As immediate data there is nothing to precompute into.
232
- *
233
- * @param {number} index
234
- * @returns {number[]}
235
- */
236
- #mip_resolution(index) {
237
- const size = this.#texture.size;
238
-
239
- const out = this.#mip_resolution_scratch;
240
-
241
- out[0] = max2(1, size[0] >>> index);
242
- out[1] = max2(1, size[1] >>> index);
243
-
244
- return out;
245
- }
246
-
247
- /**
248
- *
249
- * @param {number} x
250
- * @param {number} y
251
- */
252
- setViewportSize(x, y) {
253
- assert.isNonNegativeInteger(x, 'x');
254
- assert.isNonNegativeInteger(y, 'y');
255
-
256
- this.#viewport_size[0] = x;
257
- this.#viewport_size[1] = y;
258
-
259
- const hzb_w = Math.max(x >>> 1, 1);
260
- const hzb_h = Math.max(y >>> 1, 1);
261
-
262
- this.#resize(hzb_w, hzb_h);
263
- }
264
-
265
- /**
266
- *
267
- * @param {number} x
268
- * @param {number} y
269
- */
270
- #resize(
271
- x,
272
- y
273
- ) {
274
-
275
- const texture = this.#texture;
276
- const size = texture.size;
277
-
278
- if (size[0] === x && size[1] === y) {
279
- // no size change
280
- return;
281
- }
282
-
283
- // a screen-space depth pyramid, 2D always
284
- const mip_count = texture_mip_level_count(x, y, 1, "2d");
285
-
286
- texture.descriptor.mipLevelCount = mip_count;
287
-
288
- texture.resize(x, y);
289
- }
290
-
291
- destroy() {
292
- this.#texture.destroy();
293
- }
294
- }
1
+ import { assert } from "../../../core/assert.js";
2
+ import { max2 } from "../../../core/math/max2.js";
3
+ import { round_up } from "../../../core/math/round_up.js";
4
+ import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
5
+ import { TextureViewDescriptor } from "../../descriptor/texture/TextureViewDescriptor.js";
6
+ import { texture_mip_level_count } from "../../util/texture_mip_extent.js";
7
+ import { hzb_pick_alignment } from "./hzb_pick_alignment.js";
8
+ import { hzb_plan_reduction_steps } from "./hzb_plan_reduction_steps.js";
9
+ import { HZB_TEXTURE_FORMAT } from "./HZB_TEXTURE_FORMAT.js";
10
+ import { shader_hzb_reduce_any, shader_hzb_reduce_mip0 } from "./shader_hzb_reduce_any.js";
11
+ import { shader_hzb_reduce_mip0_clip } from "./shader_hzb_reduce_mip0_clip.js";
12
+ import { shader_hzb_spd_2, shader_hzb_spd_3, shader_hzb_spd_4 } from "./shader_hzb_spd.js";
13
+
14
+ /**
15
+ * @typedef {import("../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
16
+ * @typedef {import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext} ShadeGPUCommandContext
17
+ * @typedef {import("../GraphicsContext.js").GraphicsContext} GraphicsContext
18
+ * @typedef {import("../texture/GPUTextureContext.js").GPUTextureContext} GPUTextureContext
19
+ * @typedef {import("./hzb_plan_reduction_steps.js").HZBReductionStep} HZBReductionStep
20
+ */
21
+
22
+ export class HierarchicalZBuffer {
23
+
24
+ /**
25
+ * @type {GPUTextureContext}
26
+ */
27
+ #texture;
28
+
29
+ /**
30
+ * @type {string|GPUTextureFormat}
31
+ */
32
+ #format = HZB_TEXTURE_FORMAT
33
+
34
+ /**
35
+ * Precomputed reduction schedule from mip 0 to the 1x1 tail for the current HZB dimensions.
36
+ * @type {HZBReductionStep[]}
37
+ */
38
+ #steps = [];
39
+
40
+ /**
41
+ * Offer the pipelines {@link build} dispatches — see {@link PipelineEnquiry}.
42
+ *
43
+ * @param {PipelineEnquiry} enquiry
44
+ */
45
+ static enquirePipelines(enquiry) {
46
+ enquiry.compute.push(
47
+ shader_hzb_reduce_mip0.pipeline,
48
+ shader_hzb_reduce_mip0_clip.pipeline,
49
+ shader_hzb_reduce_any.pipeline,
50
+ shader_hzb_spd_2.pipeline,
51
+ shader_hzb_spd_3.pipeline,
52
+ shader_hzb_spd_4.pipeline,
53
+ );
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @returns {GPUTextureContext}
59
+ */
60
+ get texture() {
61
+ return this.#texture;
62
+ }
63
+
64
+
65
+ /**
66
+ * @type {GraphicsContext}
67
+ */
68
+ #graphics;
69
+
70
+ /**
71
+ *
72
+ * @type {number[]}
73
+ */
74
+ #viewport_size = [1, 1];
75
+
76
+ /**
77
+ *
78
+ * @param {GraphicsContext} graphics
79
+ */
80
+ constructor(graphics) {
81
+ this.#graphics = graphics;
82
+
83
+ this.#texture = graphics.textures.contextFromDescriptor(TextureDescriptor.from({
84
+ label: "Hierarchical Z Buffer",
85
+ format: this.#format,
86
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING,
87
+ mipLevelCount: 1,
88
+ size: [1, 1]
89
+ }));
90
+
91
+
92
+ }
93
+
94
+ /**
95
+ * @param {number} mip
96
+ * @returns {GPUTextureView}
97
+ */
98
+ #obtain_mip_view(mip) {
99
+ return this.#texture.obtainView(TextureViewDescriptor.from({
100
+ baseMipLevel: mip,
101
+ mipLevelCount: 1,
102
+ dimension: "2d",
103
+ baseArrayLayer: 0,
104
+ arrayLayerCount: 1
105
+ }));
106
+ }
107
+
108
+ /**
109
+ *
110
+ * @param {ShadeGPUCommandContext} encoder
111
+ * @param {GPUTextureContext} source
112
+ * @param {number[]} [source_offset] [x0,y0]
113
+ */
114
+ build(
115
+ encoder,
116
+ source,
117
+ source_offset
118
+ ) {
119
+
120
+ assert.defined(encoder, 'encoder');
121
+ assert.notNull(encoder, 'encoder');
122
+ assert.equal(encoder.isGPUCommandContext, true, 'encoder is not a GPUCommandContext')
123
+
124
+ assert.defined(source, 'source');
125
+ assert.notNull(source, 'source');
126
+ assert.equal(source.isGPUTextureContext, true, 'source is not a GPUTextureContext')
127
+
128
+ // the first pass is special, we need to read from source texture and write to first mip level of hzb
129
+
130
+ const texture = this.#texture;
131
+
132
+ assert.equal(texture.isDestroyed, false, 'texture is destroyed');
133
+
134
+ let source_view = source.obtainView(TextureViewDescriptor.from({
135
+ baseMipLevel: 0,
136
+ mipLevelCount: 1,
137
+ dimension: "2d",
138
+ baseArrayLayer: 0,
139
+ arrayLayerCount: 1
140
+ }));
141
+
142
+ const destination_view = this.#obtain_mip_view(0);
143
+
144
+ const viewport_size = this.#viewport_size;
145
+
146
+ const is_clipped_variant = source_offset !== undefined
147
+ && (
148
+ (
149
+ source_offset[0] !== 0
150
+ || source_offset[1] !== 0
151
+ )
152
+ || (
153
+ viewport_size[0] !== source.width
154
+ || viewport_size[1] !== source.height
155
+ )
156
+ );
157
+
158
+ if (is_clipped_variant) {
159
+ // special case for clip region
160
+ const mip0_resolution = this.#mip_resolution(0);
161
+
162
+ shader_hzb_reduce_mip0_clip.dispatchThreads({
163
+ encoder,
164
+ bindings: {
165
+ tInput: source_view,
166
+ tOutput: destination_view,
167
+ settings: {
168
+ clip_region: [
169
+ source_offset[0], source_offset[1],
170
+ viewport_size[0], viewport_size[1],
171
+ ],
172
+ output_resolution: mip0_resolution,
173
+ },
174
+ },
175
+ thread_count_x: mip0_resolution[0],
176
+ thread_count_y: mip0_resolution[1],
177
+ });
178
+ } else {
179
+
180
+ this.#do_reduction_pass(encoder, shader_hzb_reduce_mip0, source_view, destination_view, 0);
181
+ }
182
+
183
+ source_view = destination_view;
184
+
185
+ const steps = this.#steps;
186
+ const step_count = steps.length;
187
+
188
+ for (let s = 0; s < step_count; s++) {
189
+ const { base_mip, mip_count } = steps[s];
190
+
191
+ if (mip_count === 1) {
192
+ const target_mip = base_mip + 1;
193
+ const out_view = this.#obtain_mip_view(target_mip);
194
+
195
+ this.#do_reduction_pass(encoder, shader_hzb_reduce_any, source_view, out_view, target_mip);
196
+
197
+ source_view = out_view;
198
+ } else {
199
+ const out1 = this.#obtain_mip_view(base_mip + 1);
200
+ const out2 = this.#obtain_mip_view(base_mip + 2);
201
+ const out1_res = this.#mip_resolution(base_mip + 1);
202
+ const group_count_x = (out1_res[0] + 15) >>> 4;
203
+ const group_count_y = (out1_res[1] + 15) >>> 4;
204
+
205
+ if (mip_count === 2) {
206
+ shader_hzb_spd_2.dispatch({
207
+ encoder,
208
+ bindings: { tInput: source_view, tOut1: out1, tOut2: out2 },
209
+ group_count_x,
210
+ group_count_y,
211
+ });
212
+ source_view = out2;
213
+ } else if (mip_count === 3) {
214
+ const out3 = this.#obtain_mip_view(base_mip + 3);
215
+ shader_hzb_spd_3.dispatch({
216
+ encoder,
217
+ bindings: { tInput: source_view, tOut1: out1, tOut2: out2, tOut3: out3 },
218
+ group_count_x,
219
+ group_count_y,
220
+ });
221
+ source_view = out3;
222
+ } else {
223
+ const out3 = this.#obtain_mip_view(base_mip + 3);
224
+ const out4 = this.#obtain_mip_view(base_mip + 4);
225
+ shader_hzb_spd_4.dispatch({
226
+ encoder,
227
+ bindings: { tInput: source_view, tOut1: out1, tOut2: out2, tOut3: out3, tOut4: out4 },
228
+ group_count_x,
229
+ group_count_y,
230
+ });
231
+ source_view = out4;
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ /**
238
+ *
239
+ * @param {ShadeGPUCommandContext} encoder
240
+ * @param {ComputeShader} shader
241
+ * @param {GPUTextureView} source_view
242
+ * @param {GPUTextureView} destination_view
243
+ * @param {number} index
244
+ */
245
+ #do_reduction_pass(
246
+ encoder,
247
+ shader,
248
+ source_view,
249
+ destination_view,
250
+ index
251
+ ) {
252
+ const output_resolution = this.#mip_resolution(index);
253
+
254
+ shader.dispatchThreads({
255
+ encoder,
256
+ bindings: {
257
+ tInput: source_view,
258
+ tOutput: destination_view,
259
+ output_resolution,
260
+ },
261
+ thread_count_x: output_resolution[0],
262
+ thread_count_y: output_resolution[1],
263
+ });
264
+
265
+ }
266
+
267
+ /**
268
+ * Scratch for {@link #mip_resolution}. The value is serialised into the pass's immediate bytes
269
+ * before the next call, so one array can serve every mip.
270
+ *
271
+ * @type {number[]}
272
+ */
273
+ #mip_resolution_scratch = [1, 1];
274
+
275
+ /**
276
+ * Size of mip `index` of the HZB, which is what the reduction pass writing into it needs to know.
277
+ *
278
+ * Each mip halves the one above it, floored at one texel — the same walk that used to be
279
+ * precomputed into a uniform buffer of every mip's resolution and bound at a per-mip dynamic
280
+ * offset. As immediate data there is nothing to precompute into.
281
+ *
282
+ * @param {number} index
283
+ * @returns {number[]}
284
+ */
285
+ #mip_resolution(index) {
286
+ const size = this.#texture.size;
287
+
288
+ const out = this.#mip_resolution_scratch;
289
+
290
+ out[0] = max2(1, size[0] >>> index);
291
+ out[1] = max2(1, size[1] >>> index);
292
+
293
+ return out;
294
+ }
295
+
296
+ /**
297
+ *
298
+ * @param {number} x
299
+ * @param {number} y
300
+ */
301
+ setViewportSize(x, y) {
302
+ assert.isNonNegativeInteger(x, 'x');
303
+ assert.isNonNegativeInteger(y, 'y');
304
+
305
+ this.#viewport_size[0] = x;
306
+ this.#viewport_size[1] = y;
307
+
308
+ const base_w = Math.max(x >>> 1, 1);
309
+ const base_h = Math.max(y >>> 1, 1);
310
+
311
+ const [align_w, align_h] = hzb_pick_alignment(x, y, 1.05);
312
+
313
+ const hzb_w = round_up(base_w, align_w);
314
+ const hzb_h = round_up(base_h, align_h);
315
+
316
+ this.#resize(hzb_w, hzb_h);
317
+ }
318
+
319
+ /**
320
+ *
321
+ * @param {number} x
322
+ * @param {number} y
323
+ */
324
+ #resize(
325
+ x,
326
+ y
327
+ ) {
328
+
329
+ const texture = this.#texture;
330
+ const size = texture.size;
331
+
332
+ if (size[0] === x && size[1] === y) {
333
+ // no size change
334
+ return;
335
+ }
336
+
337
+ // a screen-space depth pyramid, 2D always
338
+ const mip_count = texture_mip_level_count(x, y, 1, "2d");
339
+
340
+ texture.descriptor.mipLevelCount = mip_count;
341
+
342
+ texture.resize(x, y);
343
+
344
+ this.#steps = hzb_plan_reduction_steps(x, y);
345
+ }
346
+
347
+ destroy() {
348
+ this.#texture.destroy();
349
+ }
350
+ }
@@ -1,7 +1,5 @@
1
1
  /**
2
2
  * Idea is to down-sample any kind of texture.
3
- * Somewhat inspired by AMD's FSR single-pass-downsampler.
4
- * At present, it is impossible to implement a single-pass downsampler in WebGPU, because you can't bind multiple mips of a storage texture in compute shader.
5
3
  *
6
4
  * @example
7
5
  * const min = generate_downsampler_code({
@@ -1 +1 @@
1
- {"version":3,"file":"generate_downsampler_code.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/generate_downsampler_code.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAN+B,IAAI;IACR,cAAc,EAA9B,MAAM;IACU,aAAa,EAA7B,MAAM;IACgB,YAAY,GAAlC,SAAS,EAAE;IACV,SAAS,CA+EpB;0BAlGyB,iCAAiC"}
1
+ {"version":3,"file":"generate_downsampler_code.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/hiz/generate_downsampler_code.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH;IAN+B,IAAI;IACR,cAAc,EAA9B,MAAM;IACU,aAAa,EAA7B,MAAM;IACgB,YAAY,GAAlC,SAAS,EAAE;IACV,SAAS,CAgFpB;0BAjGyB,iCAAiC"}