@woosh/meep-engine 3.54.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 (78) hide show
  1. package/package.json +1 -1
  2. package/src/shade/RENDERER_CONTRACT.md +5 -2
  3. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts.map +1 -1
  4. package/src/shade/device/SHADE_DEVICE_FLOOR.js +2 -0
  5. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  6. package/src/shade/renderer/Renderer.js +1 -1
  7. package/src/shade/renderer/hiz/generate_downsampler_code.js +1 -1
  8. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +1 -1
  9. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.d.ts.map +1 -1
  10. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +154 -147
  11. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +2 -1
  12. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  13. package/src/shade/renderer/postprocess/gtao/GTAO.js +5 -1
  14. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.d.ts +8 -0
  15. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.d.ts.map +1 -1
  16. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.js +10 -1
  17. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  18. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +5 -0
  19. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.d.ts +22 -0
  20. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.d.ts.map +1 -0
  21. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.js +33 -0
  22. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.d.ts +22 -0
  23. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.d.ts.map +1 -0
  24. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.js +56 -0
  25. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.d.ts +13 -0
  26. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.d.ts.map +1 -0
  27. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.js +42 -0
  28. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts +2 -1
  29. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  30. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +382 -357
  31. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  32. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +414 -410
  33. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -7
  34. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts +10 -5
  35. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts.map +1 -1
  36. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.js +30 -14
  37. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts.map +1 -1
  38. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js +17 -3
  39. package/src/engine/graphics3/decal/DecalAtlas.d.ts +0 -43
  40. package/src/engine/graphics3/decal/DecalAtlas.d.ts.map +0 -1
  41. package/src/engine/graphics3/decal/DecalAtlasFill.d.ts +0 -12
  42. package/src/engine/graphics3/decal/DecalAtlasFill.d.ts.map +0 -1
  43. package/src/engine/graphics3/decal/decal_atlas_border.d.ts +0 -52
  44. package/src/engine/graphics3/decal/decal_atlas_border.d.ts.map +0 -1
  45. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts +0 -26
  46. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts.map +0 -1
  47. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.js +0 -268
  48. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.d.ts +0 -3
  49. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.d.ts.map +0 -1
  50. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.js +0 -32
  51. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts +0 -17
  52. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +0 -1
  53. package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +0 -98
  54. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts +0 -23
  55. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts.map +0 -1
  56. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.js +0 -118
  57. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts +0 -24
  58. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts.map +0 -1
  59. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts +0 -15
  60. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +0 -1
  61. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +0 -17
  62. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +0 -1
  63. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts +0 -35
  64. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +0 -1
  65. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +0 -35
  66. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +0 -1
  67. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts +0 -10
  68. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts.map +0 -1
  69. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +0 -28
  70. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +0 -1
  71. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +0 -48
  72. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +0 -1
  73. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +0 -28
  74. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +0 -1
  75. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts +0 -16
  76. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts.map +0 -1
  77. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts +0 -23
  78. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts.map +0 -1
@@ -37,10 +37,3 @@ It has drifted against the live pipeline in one way that a reader will not notic
37
37
  directory: the à-trous path grew `chunk_ssr_metadata`, and the variance/metadata contract the
38
38
  prefilter expects predates it. Reconcile those before wiring the pass in, rather than after.
39
39
 
40
- ## Sibling trap, same territory
41
-
42
- `graph_build_depth_max_pyramid.js` (also one directory up, also unreferenced) builds a
43
- **single-channel `r32float`** max-depth chain, while the live `HierarchicalZBuffer` the SSR trace
44
- actually reads is **two-channel** — `chunk_ffx_sssr_load_depth` reads its `.y`. The two are not
45
- interchangeable, and swapping one in for the other gives a silently zero `.y` rather than an error.
46
- That file's own header says the same thing.
@@ -18,11 +18,16 @@
18
18
  *
19
19
  * To match brightness across cascades without introducing axis-aligned cubic plateaus or directional
20
20
  * distortion:
21
- * - `result.direction` is always the true Euclidean radial unit vector `L / length(L)`.
22
- * - `irradiance_clipmap_regularize_light_distance(d, cell_size)` depends purely on Euclidean radial
23
- * distance `d = length(L)`, applying a strictly monotonic, radially isotropic `C^1` shift inside
24
- * `d < 1.75 * h` bounded below by `0.35 * h`, and equalling `d` identically in the far field
25
- * (`d >= 1.75 * h`).
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.
26
31
  *
27
32
  * @type {CodeChunk}
28
33
  */
@@ -1 +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;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,mDAFU,SAAS,CAyEjB;0BA/GwB,oCAAoC"}
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"}
@@ -31,11 +31,16 @@ const SPOT_DESCRIPTOR = LIGHT_DATABASE_SPEC.get("light_spot");
31
31
  *
32
32
  * To match brightness across cascades without introducing axis-aligned cubic plateaus or directional
33
33
  * distortion:
34
- * - `result.direction` is always the true Euclidean radial unit vector `L / length(L)`.
35
- * - `irradiance_clipmap_regularize_light_distance(d, cell_size)` depends purely on Euclidean radial
36
- * distance `d = length(L)`, applying a strictly monotonic, radially isotropic `C^1` shift inside
37
- * `d < 1.75 * h` bounded below by `0.35 * h`, and equalling `d` identically in the far field
38
- * (`d >= 1.75 * h`).
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.
39
44
  *
40
45
  * @type {CodeChunk}
41
46
  */
@@ -43,14 +48,18 @@ export const chunk_irradiance_clipmap_local_light = CodeChunk.from(
43
48
  //language=WGSL
44
49
  `
45
50
  const IRRADIANCE_CLIPMAP_VOXEL_FOOTPRINT_RADIUS: f32 = 0.35;
46
- const IRRADIANCE_CLIPMAP_VOXEL_RADIAL_SHIFT: f32 = 0.45;
47
51
  const IRRADIANCE_CLIPMAP_VOXEL_RADIAL_SUPPORT: f32 = 1.75;
48
52
 
49
53
  fn irradiance_clipmap_regularize_light_distance(distance: f32, cell_size: f32) -> f32 {
50
54
  let h = max(cell_size, 1e-5);
51
- let s = smoothstep(0.0, IRRADIANCE_CLIPMAP_VOXEL_RADIAL_SUPPORT * h, distance);
52
- let shifted = distance - IRRADIANCE_CLIPMAP_VOXEL_RADIAL_SHIFT * h * (1.0 - s);
53
- return max(shifted, IRRADIANCE_CLIPMAP_VOXEL_FOOTPRINT_RADIUS * h);
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)));
54
63
  }
55
64
 
56
65
  fn irradiance_clipmap_get_point_light_info_by_index(
@@ -62,10 +71,13 @@ fn irradiance_clipmap_get_point_light_info_by_index(
62
71
  let light = ${POINT_DESCRIPTOR.marshalling_method_read}(database, index);
63
72
  let L = light.position.xyz - position_ws;
64
73
  let d_center = max(length(L), 1e-5);
65
- let d_eval = irradiance_clipmap_regularize_light_distance(d_center, cell_size);
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);
66
77
 
67
78
  var result: ${INCIDENT_LIGHT_STRUCT.wgsl_ref};
68
- result.direction = L / d_center;
79
+ let dir_radius = max(max(light.radius, 0.5 * cell_size), 1e-5);
80
+ result.direction = L / max(d_center, dir_radius);
69
81
 
70
82
  let attenuation = light_sphere_distance_attenuation(d_eval, light.radius, light.distance);
71
83
  result.color = light.color * attenuation;
@@ -84,14 +96,18 @@ fn irradiance_clipmap_get_spot_light_info_by_index(
84
96
  let light = ${SPOT_DESCRIPTOR.marshalling_method_read}(database, index);
85
97
  let L = light.position - position_ws;
86
98
  let d_center = max(length(L), 1e-5);
87
- let d_eval = irradiance_clipmap_regularize_light_distance(d_center, cell_size);
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;
88
103
 
89
104
  var result: ${INCIDENT_LIGHT_STRUCT.wgsl_ref};
90
- result.direction = L / d_center;
105
+ let dir_radius = max(max(light.radius, 0.5 * cell_size), 1e-5);
106
+ result.direction = L / max(d_center, dir_radius);
91
107
  result.distance = max(0.0, d_center - light.radius);
92
108
  result.radius = light.radius / d_center;
93
109
 
94
- let angle_cos = dot(result.direction, -light.direction);
110
+ let angle_cos = dot(unit_dir, -light.direction);
95
111
  let spot_attenuation = light_get_spot_attenuation(light.coneCos, light.penumbraCos, angle_cos);
96
112
 
97
113
  if (spot_attenuation > 0.0) {
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_irradiance_clipmap_sample.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js"],"names":[],"mappings":"AAsDA;;;;;;;GAOG;AACH,wDALW,OAAO,wDAAwD,EAAE,6BAA6B;IAE5E,iBAAiB,GAAnC,OAAO;IACL,OAAO,wDAAwD,EAAE,6BAA6B,CAc1G;AA3DD;;;GAGG;AACH,kDAFU,wBAAwB,CAKhC;AAEF;;;GAGG;AACH,kDAFU,wBAAwB,CAMhC;AAEF;;;GAGG;AACH,qDAFU,wBAAwB,CAMhC;AAEF;;;GAGG;AACH,kDAFU,wBAAwB,CAMhC;AAwBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,8CAFU,SAAS,CAwJjB;AAOF;;;;;;;;;;;;;;GAcG;AACH,6DAFU,SAAS,CAoCjB;yCAxVuC,mDAAmD;0BADlE,oCAAoC"}
1
+ {"version":3,"file":"chunk_irradiance_clipmap_sample.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js"],"names":[],"mappings":"AAsDA;;;;;;;GAOG;AACH,wDALW,OAAO,wDAAwD,EAAE,6BAA6B;IAE5E,iBAAiB,GAAnC,OAAO;IACL,OAAO,wDAAwD,EAAE,6BAA6B,CAc1G;AA3DD;;;GAGG;AACH,kDAFU,wBAAwB,CAKhC;AAEF;;;GAGG;AACH,kDAFU,wBAAwB,CAMhC;AAEF;;;GAGG;AACH,qDAFU,wBAAwB,CAMhC;AAEF;;;GAGG;AACH,kDAFU,wBAAwB,CAMhC;AAwBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,8CAFU,SAAS,CAsKjB;AAOF;;;;;;;;;;;;;;GAcG;AACH,6DAFU,SAAS,CAoCjB;yCAtWuC,mDAAmD;0BADlE,oCAAoC"}
@@ -176,7 +176,11 @@ fn irradiance_clipmap_select_finest(
176
176
  all(abs(anchor_cells - level_center) <= vec3<f32>(0.501))
177
177
  );
178
178
 
179
- let radius = min(half_size.x, min(half_size.y, half_size.z));
179
+ // Subtract 0.5 cells from half_size so that even when anchor_cells is offset by up to
180
+ // +/-0.5 cells from level_center, the selection sphere stays strictly inside [0, size]^3
181
+ // and the +/-0.5 voxel B_2 jitter taps stay strictly inside the 1-texel border
182
+ // [-0.5, size + 0.5]^3 without hitting the border clamp.
183
+ let radius = max(0.5, min(half_size.x, min(half_size.y, half_size.z)) - 0.5);
180
184
  let edge = radius - length(position_cells - center_cells);
181
185
 
182
186
  if (edge <= 0.0) {
@@ -238,8 +242,18 @@ fn irradiance_clipmap_cascade_read_stochastic(
238
242
  }
239
243
 
240
244
  fn irradiance_clipmap_cascade_read(c: u32, position_ws: vec3<f32>) -> ${METRO_L1_IRRADIANCE_STRUCT.wgsl_ref} {
241
- var u = 0.5;
242
- return irradiance_clipmap_cascade_read_stochastic(c, position_ws, &u);
245
+ let level = irradiance_clipmap.levels[c];
246
+ let cascade = irradiance_clipmap.cascades[c];
247
+ let local = position_ws / level.cell_size - vec3<f32>(level.corner);
248
+ let center = cascade.content_origin + local;
249
+ let t_min = cascade.content_origin - vec3<f32>(0.5);
250
+ let t_max = cascade.content_origin + vec3<f32>(level.size) + vec3<f32>(0.5);
251
+ let uvw = clamp(center, t_min, t_max) * irradiance_clipmap.inverse_atlas_size;
252
+
253
+ return ${METRO_L1_IRRADIANCE_STRUCT.make({
254
+ CoCg: "textureSampleLevel(irradiance_clipmap_atlas_cocg, irradiance_clipmap_sampler, uvw, 0.0).xy",
255
+ Y: "textureSampleLevel(irradiance_clipmap_atlas_y, irradiance_clipmap_sampler, uvw, 0.0)",
256
+ })};
243
257
  }
244
258
 
245
259
  fn irradiance_clipmap_mix_sh(
@@ -1,43 +0,0 @@
1
- /**
2
- * A texture atlas whose patches can be **mipmapped without bleeding into each other**.
3
- *
4
- * The atlas this replaces generates mipmaps and reserves padding, and still bleeds: nothing ever
5
- * fills the padding, so the gutter is zeros and every level past the first averages a patch against
6
- * whatever lies beyond it. The workarounds are visible in the shader that reads it — a negative LOD
7
- * bias, and a switch to turn mipmapping off when a scene has many overlapping decals.
8
- *
9
- * Three things fix it, and all three are here: a border sized in proportion to the patch
10
- * ({@link decal_atlas_border}), a border that is actually **filled**, by a rule that suits what the
11
- * channel means ({@link DecalAtlasFill}), and a per-patch bound on how deep the mip chain may be
12
- * sampled ({@link decal_atlas_max_lod}), because no finite border protects every level.
13
- *
14
- * Packing, growth, repacking and uv bookkeeping are the base class's and are untouched — it already
15
- * places content at `packing + padding`, which is the whole geometry of a bordered patch.
16
- */
17
- export class DecalAtlas extends TextureAtlas {
18
- /**
19
- * @param {DecalAtlasFill} fill
20
- * @param {number} [size] initial edge length; the atlas grows on demand
21
- */
22
- constructor(fill: DecalAtlasFill, size?: number);
23
- /**
24
- * @returns {DecalAtlasFill}
25
- */
26
- get fill(): number;
27
- /**
28
- * The border is the patch's own size, not the caller's choice — every patch in one atlas has to
29
- * obey the same rule for {@link decal_atlas_max_lod}'s "+1 from the neighbour" to hold.
30
- *
31
- * @param {Sampler2D} sampler
32
- * @returns {AtlasPatch}
33
- */
34
- add(sampler: Sampler2D): AtlasPatch;
35
- /**
36
- * @param {AtlasPatch} patch
37
- */
38
- paintPatch(patch: AtlasPatch): void;
39
- #private;
40
- }
41
- import { TextureAtlas } from "../../graphics/texture/atlas/TextureAtlas.js";
42
- import { DecalAtlasFill } from "./DecalAtlasFill.js";
43
- //# sourceMappingURL=DecalAtlas.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DecalAtlas.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/DecalAtlas.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;GAeG;AACH;IAMI;;;OAGG;IACH,kBAHW,cAAc,SACd,MAAM,EAQhB;IAED;;OAEG;IACH,mBAEC;IAED;;;;;;OAMG;IACH,oCAIC;IAED;;OAEG;IACH,oCAoDC;;CA6EJ;6BA/L4B,8CAA8C;+BAG5C,qBAAqB"}
@@ -1,12 +0,0 @@
1
- /**
2
- * How a decal atlas fills the border around a patch.
3
- *
4
- * Two rules rather than one, because the correct fill depends on what the channel means and getting
5
- * it wrong shows up only once the mip chain is built.
6
- */
7
- export type DecalAtlasFill = number;
8
- export namespace DecalAtlasFill {
9
- let PremultipliedCoverage: number;
10
- let EdgeExtend: number;
11
- }
12
- //# sourceMappingURL=DecalAtlasFill.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DecalAtlasFill.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/DecalAtlasFill.js"],"names":[],"mappings":";;;;;;6BAMU,MAAM"}
@@ -1,52 +0,0 @@
1
- /**
2
- * Border, in texels, for a patch of this size.
3
- *
4
- * Driven by the longer side, because one border value protects both axes and the atlas halves both
5
- * together when it builds its mip chain.
6
- *
7
- * @param {number} width
8
- * @param {number} height
9
- * @returns {number}
10
- */
11
- export function decal_atlas_border(width: number, height: number): number;
12
- /**
13
- * The deepest mip level a patch with this border can be sampled at without reading a neighbour.
14
- *
15
- * **A patch's own border is not the whole guard.** Every patch in the atlas has a border of at least
16
- * {@link DECAL_ATLAS_BORDER_MINIMUM}, so whatever sits next to this one contributes at least one
17
- * more texel of separation: content is `border + 1` texels apart at worst. At mip level `L` that
18
- * separation is `(border + 1) / 2^L` texels, and it has to survive down to one — which is also what
19
- * pays for patches not landing on power-of-two boundaries, so alignment is not claimed on top of it.
20
- *
21
- * Past this level the sampler is clamped rather than allowed to keep minifying, so a decal seen from
22
- * very far away aliases instead of bleeding. That is the trade, and it is the right way round: a
23
- * shimmering decal is a decal, a bleeding one is somebody else's texture.
24
- *
25
- * @param {number} border
26
- * @returns {number}
27
- */
28
- export function decal_atlas_max_lod(border: number): number;
29
- /**
30
- * How much of a patch's own size is spent on its border.
31
- *
32
- * A **proportional** border rather than a fixed one, and that is the point of it: the border is what
33
- * decides how far a patch can be minified before its neighbours bleed into it, so sizing it in
34
- * proportion makes that limit the same for every decal whatever its resolution. At 1/64 every patch
35
- * stops minifying at roughly the same ~64 px screen footprint, for a flat ~6.3% of atlas area.
36
- *
37
- * A fixed border does the opposite: generous for small patches and useless for large ones.
38
- *
39
- * @type {number}
40
- */
41
- export const DECAL_ATLAS_BORDER_RATIO: number;
42
- /**
43
- * The smallest border a patch may have, in texels.
44
- *
45
- * One, not more. A 64x64 decal is common and needs four texels at the very most; eight would spend a
46
- * tenth of the texture on gutter to protect mip levels at which the decal is a handful of pixels on
47
- * screen. One texel is also not really one — see {@link decal_atlas_max_lod}.
48
- *
49
- * @type {number}
50
- */
51
- export const DECAL_ATLAS_BORDER_MINIMUM: number;
52
- //# sourceMappingURL=decal_atlas_border.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"decal_atlas_border.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/decal_atlas_border.js"],"names":[],"mappings":"AA2BA;;;;;;;;;GASG;AACH,0CAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,4CAHW,MAAM,GACJ,MAAM,CAOlB;AAlED;;;;;;;;;;;GAWG;AACH,uCAFU,MAAM,CAE+B;AAE/C;;;;;;;;GAQG;AACH,yCAFU,MAAM,CAE4B"}
@@ -1,26 +0,0 @@
1
- /**
2
- * @param {GraphicsContext} graphics
3
- * @param {GPUCommandEncoder} encoder
4
- * @param {GPUTextureContext} output_depth
5
- * @param {GPUTextureView} source_view
6
- * @param {GPUBuffer} camera
7
- */
8
- export function render_mip0(graphics: GraphicsContext, encoder: GPUCommandEncoder, output_depth: GPUTextureContext, source_view: GPUTextureView, camera: GPUBuffer): any;
9
- /**
10
- * NOTE: was written for GTAO, currently not being used
11
- * @param {Object} options
12
- * @param {FrameGraph} options.graph
13
- * @param {number} options.depth
14
- * @param {number[]} options.resolution
15
- * @param {number} [options.max_mips]
16
- * @param {number} options.camera camera buffer
17
- * @returns {number} mip-mapped linear z-buffer
18
- */
19
- export function graph_build_depth_mipmap({ graph, depth, resolution, max_mips, camera }: {
20
- graph: FrameGraph;
21
- depth: number;
22
- resolution: number[];
23
- max_mips?: number;
24
- camera: number;
25
- }): number;
26
- //# sourceMappingURL=graph_build_depth_mipmap.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph_build_depth_mipmap.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.js"],"names":[],"mappings":"AA0HA;;;;;;GAMG;AACH,yKAoCC;AAED;;;;;;;;;GASG;AACH;IAP+B,KAAK;IACT,KAAK,EAArB,MAAM;IACY,UAAU,EAA5B,MAAM,EAAE;IACS,QAAQ,GAAzB,MAAM;IACU,MAAM,EAAtB,MAAM;IACJ,MAAM,CA4FlB"}
@@ -1,268 +0,0 @@
1
- import { BufferBindingLayout } from "../../../descriptor/binding/BufferBindingLayout.js";
2
- import { TextureBindingLayout } from "../../../descriptor/binding/TextureBindingLayout.js";
3
- import { PipelineLayoutDescriptor } from "../../../descriptor/pipeline/PipelineLayoutDescriptor.js";
4
- import { TextureViewDescriptor } from "../../../descriptor/texture/TextureViewDescriptor.js";
5
- import { TextureResourceDescriptor } from "../../../device/graph/TextureResourceDescriptor.js";
6
- import { BindGroupDescriptor } from "../../binding/BindGroupDescriptor.js";
7
- import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
8
- import { create_full_quad_pipeline_descriptor } from "../../shader/fullscreen/create_full_quad_pipeline_descriptor.js";
9
- import { chunk_linearize_depth } from "../../shader/chunk/depth/chunk_linearize_depth.js";
10
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
11
- import { GTAO_EFFECT_FALLOFF_RANGE, GTAO_EFFECT_RADIUS } from "./fragment_shader_gtao.js";
12
-
13
- //
14
-
15
- //language=WGSL
16
- const shader_reduce = `
17
-
18
- @group(0) @binding(0) var source : texture_2d<f32>;
19
-
20
- const EffectRadius = ${GTAO_EFFECT_RADIUS};
21
- const EffectFalloffRange = ${GTAO_EFFECT_FALLOFF_RANGE};
22
-
23
- fn DepthMIPFilter( depth0:f32, depth1:f32, depth2:f32, depth3:f32 ) -> f32
24
- {
25
- let maxDepth = max( max( depth0, depth1 ), max( depth2, depth3 ) );
26
-
27
- const depthRangeScaleFactor = 0.75; // found empirically :)
28
-
29
- const effectRadius = depthRangeScaleFactor * EffectRadius;
30
- const falloffRange = EffectFalloffRange * effectRadius;
31
-
32
- const falloffFrom = effectRadius * (1-EffectFalloffRange);
33
-
34
- // fadeout precompute optimisation
35
- const falloffMul = -1.0 / ( falloffRange );
36
- const falloffAdd = falloffFrom / ( falloffRange ) + 1.0;
37
-
38
- let weight0 = saturate( (maxDepth-depth0) * falloffMul + falloffAdd );
39
- let weight1 = saturate( (maxDepth-depth1) * falloffMul + falloffAdd );
40
- let weight2 = saturate( (maxDepth-depth2) * falloffMul + falloffAdd );
41
- let weight3 = saturate( (maxDepth-depth3) * falloffMul + falloffAdd );
42
-
43
- let weightSum = weight0 + weight1 + weight2 + weight3;
44
-
45
- return (weight0 * depth0 + weight1 * depth1 + weight2 * depth2 + weight3 * depth3) / weightSum;
46
- }
47
-
48
- @fragment
49
- fn main(@builtin(position) coord : vec4<f32>) -> @location(0) f32 {
50
-
51
-
52
- let source_size = textureDimensions(source, 0);
53
- let limit = vec2u(source_size - 1u);
54
-
55
- let p0 = min( vec2u( u32(coord.x) << 1, u32(coord.y) << 1), limit);
56
- let p1 = min( p0 + vec2u(1,0), limit );
57
- let p2 = min( p0 + vec2u(0,1), limit );
58
- let p3 = min( p0 + vec2u(1,1), limit );
59
-
60
- let depth0 = textureLoad(source, p0, 0).r;
61
- let depth1 = textureLoad(source, p1, 0).r;
62
- let depth2 = textureLoad(source, p2, 0).r;
63
- let depth3 = textureLoad(source, p3, 0).r;
64
-
65
- let depth = DepthMIPFilter(depth0, depth1, depth2, depth3);
66
-
67
- return depth;
68
- }
69
- `;
70
-
71
- const render_pipeline_descriptor_reduce = create_full_quad_pipeline_descriptor({
72
- fragment_code: shader_reduce,
73
- layout: PipelineLayoutDescriptor.forStage(GPUShaderStage.FRAGMENT, [
74
- [
75
- TextureBindingLayout.unfilterableFloat
76
- ]
77
- ]),
78
- targets: [
79
- {
80
- format: "r32float",
81
- }
82
- ]
83
- });
84
-
85
-
86
- //language=WGSL
87
- const shader_mip0 = CodeChunk.from(`
88
-
89
- @group(0) @binding(0) var source : texture_2d<f32>;
90
- @group(0) @binding(1) var<uniform> camera: ${CAMERA_UNIFORM_STRUCT.wgsl_ref};
91
-
92
- @fragment
93
- fn main(@builtin(position) coord : vec4<f32>) -> @location(0) f32 {
94
-
95
- let depth_raw = textureLoad(source,vec2u(coord.xy), 0).r;
96
-
97
- let depth = linearize_depth(camera.projection_matrix, depth_raw);
98
-
99
- return depth;
100
- }
101
-
102
- `,[
103
- CAMERA_UNIFORM_STRUCT.declaration_chunk,
104
- chunk_linearize_depth,
105
- ]).compile().text;
106
-
107
- const render_pipeline_descriptor_mip0 = create_full_quad_pipeline_descriptor({
108
- fragment_code: shader_mip0,
109
- layout: PipelineLayoutDescriptor.forStage(GPUShaderStage.FRAGMENT, [
110
- [
111
- TextureBindingLayout.unfilterableFloat,
112
- BufferBindingLayout.uniform
113
- ]
114
- ]),
115
- targets: [
116
- {
117
- format: "r32float",
118
- }
119
- ]
120
- });
121
-
122
-
123
- /**
124
- * @param {GraphicsContext} graphics
125
- * @param {GPUCommandEncoder} encoder
126
- * @param {GPUTextureContext} output_depth
127
- * @param {GPUTextureView} source_view
128
- * @param {GPUBuffer} camera
129
- */
130
- export function render_mip0(
131
- graphics,
132
- encoder,
133
- output_depth,
134
- source_view,
135
- camera
136
- ) {
137
- const pipeline = graphics.render_pipelines.obtain(render_pipeline_descriptor_mip0);
138
-
139
- const output_view = output_depth.obtainView(TextureViewDescriptor.from({
140
- baseMipLevel: 0,
141
- mipLevelCount: 1
142
- }));
143
-
144
- const pass = encoder.beginRenderPass({
145
- colorAttachments: [
146
- {
147
- view: output_view,
148
- loadOp: "clear",
149
- storeOp: "store"
150
- }
151
- ]
152
- });
153
-
154
-
155
- const bind_group = graphics.bind_groups.obtain(BindGroupDescriptor.from(render_pipeline_descriptor_mip0.layout.bindGroupLayouts[0], [
156
- source_view,
157
- { buffer: camera }
158
- ]));
159
-
160
- pass.setPipeline(pipeline);
161
- pass.setBindGroup(0, bind_group);
162
- pass.draw(3);
163
- pass.end();
164
-
165
- return output_view;
166
- }
167
-
168
- /**
169
- * NOTE: was written for GTAO, currently not being used
170
- * @param {Object} options
171
- * @param {FrameGraph} options.graph
172
- * @param {number} options.depth
173
- * @param {number[]} options.resolution
174
- * @param {number} [options.max_mips]
175
- * @param {number} options.camera camera buffer
176
- * @returns {number} mip-mapped linear z-buffer
177
- */
178
- export function graph_build_depth_mipmap(
179
- {
180
- graph,
181
- depth,
182
- resolution,
183
- max_mips = Number.POSITIVE_INFINITY,
184
- camera
185
- }
186
- ) {
187
- const data = {};
188
-
189
-
190
- /**
191
- *
192
- * @param data
193
- * @param {FramePassResources} resources
194
- * @param {GraphicsExecutionContext} context
195
- */
196
- function execute(data, resources, context) {
197
- /**
198
- * @type {GPUTextureContext}
199
- */
200
- const input_depth = resources.get(data.input_depth);
201
- const output_depth = resources.get(data.output_depth);
202
- const camera = resources.get(data.camera);
203
-
204
- const graphics = context.graphics;
205
-
206
- const reduction_pipeline = graphics.render_pipelines.obtain(render_pipeline_descriptor_reduce);
207
-
208
- const mip_limit = Math.min(max_mips, output_depth.gpu_texture.mipLevelCount);
209
-
210
-
211
- const encoder = context.encoder;
212
-
213
- // mip 0
214
- let source_view = input_depth.obtainView();
215
-
216
- source_view = render_mip0(graphics, encoder, output_depth, source_view, camera);
217
-
218
- // inspect_gpu_buffer_typed({
219
- // buffer: camera,
220
- // device: graphics.device,
221
- // type: CAMERA_UNIFORM_STRUCT,
222
- // count:1
223
- // }).then(console.warn);
224
-
225
-
226
- for (let i = 1; i < mip_limit; i++) {
227
- const destination_view = output_depth.obtainView(TextureViewDescriptor.from({
228
- baseMipLevel: i,
229
- mipLevelCount: 1,
230
- }));
231
-
232
- const pass = encoder.beginRenderPass({
233
- colorAttachments: [
234
- {
235
- view: destination_view,
236
- loadOp: "clear",
237
- storeOp: "store"
238
- }
239
- ]
240
- });
241
-
242
- const bind_group = graphics.bind_groups.obtain(BindGroupDescriptor.from(render_pipeline_descriptor_reduce.layout.bindGroupLayouts[0], [
243
- source_view
244
- ]));
245
-
246
- pass.setPipeline(reduction_pipeline);
247
- pass.setBindGroup(0, bind_group);
248
- pass.draw(3);
249
- pass.end();
250
-
251
- source_view = destination_view;
252
- }
253
-
254
- }
255
-
256
- const builder = graph.add('depth mipmap', data, execute);
257
-
258
- data.input_depth = builder.read(depth);
259
- data.camera = builder.read(camera);
260
- data.output_depth = builder.create("mipmap", TextureResourceDescriptor.from({
261
- resolution: resolution,
262
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST,
263
- format: "r32float",
264
- enableMips: true
265
- }));
266
-
267
- return data.output_depth;
268
- }
@@ -1,3 +0,0 @@
1
- export const copy_shader_f32: ImageShader;
2
- import { ImageShader } from "../../shader/ImageShader.js";
3
- //# sourceMappingURL=copy_shader_f32.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"copy_shader_f32.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/copy_shader_f32.js"],"names":[],"mappings":"AAsBA,0CASE;4BA9B0B,6BAA6B"}
@@ -1,32 +0,0 @@
1
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
2
- import { ImageShader } from "../../shader/ImageShader.js";
3
- import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
4
- import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
5
-
6
- const resources = new ShaderResourceSetDescriptor();
7
- resources.createGroup()
8
- .addTexture("tInput");
9
-
10
- const body = CodeChunk.from(
11
- //language=WGSL
12
- `
13
- @fragment
14
- fn main(
15
- @builtin(position) coord : vec4<f32>,
16
- @location(0) uv: vec2<f32>,
17
- ) -> @location(0) f32 {
18
- return textureLoad(tInput, vec2<i32>(coord.xy), 0).r;
19
- }
20
- `
21
- )
22
-
23
- export const copy_shader_f32 = new ImageShader({
24
- descriptor: ShaderDescriptor.from({
25
- label: "Copy r32",
26
- resources,
27
- body
28
- }),
29
- targets: [
30
- { format: "r32float" }
31
- ]
32
- })
@@ -1,17 +0,0 @@
1
- /**
2
- * Inclusive source-texel window one output texel of the reduction reads: `(min.xy, max.xy)`.
3
- *
4
- * The windows of one step tile the source exactly — every source texel belongs to one output texel,
5
- * none twice and none missed — which is what makes the result a max over the whole level rather than a
6
- * max over an arbitrary stencil. Pinned by `depth_max_source_bounds.spec`.
7
- *
8
- * The stride is `ceil(source / output)`, not a hardcoded 2, and the upper bound is
9
- * `min + stride - 1` because the loops that read it are inclusive. It used to be `target * 2` for the
10
- * origin and `min + stride` for the bound, which at a halving step is three texels per axis: nine
11
- * reads for a 2x2 footprint, overlapping its neighbours on both sides.
12
- */
13
- export const chunk_depth_max_source_bounds: CodeChunk;
14
- export const depth_max_shader: ImageShader;
15
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
16
- import { ImageShader } from "../../shader/ImageShader.js";
17
- //# sourceMappingURL=depth_max_shader.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"depth_max_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/depth_max_shader.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;GAWG;AACH,sDAyBE;AAkCF,2CAWG;0BAhGuB,oCAAoC;4BAClC,6BAA6B"}