@woosh/meep-engine 3.54.0 → 3.56.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 (101) hide show
  1. package/package.json +1 -1
  2. package/src/engine/ecs/transform/Transform64.d.ts +21 -0
  3. package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
  4. package/src/engine/ecs/transform/Transform64.js +26 -0
  5. package/src/shade/RENDERER_CONTRACT.md +5 -2
  6. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts.map +1 -1
  7. package/src/shade/device/SHADE_DEVICE_FLOOR.js +2 -0
  8. package/src/shade/renderer/Renderer.d.ts +5 -0
  9. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  10. package/src/shade/renderer/Renderer.js +26 -3
  11. package/src/shade/renderer/hiz/generate_downsampler_code.js +1 -1
  12. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +1 -1
  13. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +2 -1
  14. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  15. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  16. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +2 -2
  17. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  18. package/src/shade/renderer/particles/graph_particles_avboit.js +4 -9
  19. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.d.ts.map +1 -1
  20. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +154 -147
  21. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +2 -1
  22. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  23. package/src/shade/renderer/postprocess/gtao/GTAO.js +5 -1
  24. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.d.ts +8 -0
  25. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.d.ts.map +1 -1
  26. package/src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.js +10 -1
  27. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  28. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +5 -0
  29. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.d.ts +22 -0
  30. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.d.ts.map +1 -0
  31. package/src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.js +33 -0
  32. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.d.ts +22 -0
  33. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.d.ts.map +1 -0
  34. package/src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.js +56 -0
  35. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.d.ts +13 -0
  36. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.d.ts.map +1 -0
  37. package/src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.js +42 -0
  38. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts +2 -1
  39. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  40. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +382 -357
  41. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  42. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +414 -410
  43. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  44. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -7
  45. package/src/shade/renderer/view/GPUViewContext.d.ts +0 -14
  46. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  47. package/src/shade/renderer/view/GPUViewContext.js +0 -29
  48. package/src/shade/renderer/view/ViewManager.d.ts +1 -1
  49. package/src/shade/renderer/view/ViewManager.js +1 -1
  50. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +40 -3
  51. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  52. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +660 -583
  53. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts +10 -5
  54. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts.map +1 -1
  55. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.js +30 -14
  56. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts.map +1 -1
  57. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js +17 -3
  58. package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
  59. package/src/engine/graphics3/decal/DecalAtlas.d.ts +0 -43
  60. package/src/engine/graphics3/decal/DecalAtlas.d.ts.map +0 -1
  61. package/src/engine/graphics3/decal/DecalAtlasFill.d.ts +0 -12
  62. package/src/engine/graphics3/decal/DecalAtlasFill.d.ts.map +0 -1
  63. package/src/engine/graphics3/decal/decal_atlas_border.d.ts +0 -52
  64. package/src/engine/graphics3/decal/decal_atlas_border.d.ts.map +0 -1
  65. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts +0 -26
  66. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts.map +0 -1
  67. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.js +0 -268
  68. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.d.ts +0 -3
  69. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.d.ts.map +0 -1
  70. package/src/shade/renderer/postprocess/ssr/copy_shader_f32.js +0 -32
  71. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts +0 -17
  72. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +0 -1
  73. package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +0 -98
  74. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts +0 -23
  75. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts.map +0 -1
  76. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.js +0 -118
  77. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOLUTION_Z.d.ts +0 -2
  78. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOLUTION_Z.d.ts.map +0 -1
  79. package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOLUTION_Z.js +0 -1
  80. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts +0 -24
  81. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts.map +0 -1
  82. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts +0 -15
  83. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +0 -1
  84. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +0 -17
  85. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +0 -1
  86. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts +0 -35
  87. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +0 -1
  88. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +0 -35
  89. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +0 -1
  90. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts +0 -10
  91. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.d.ts.map +0 -1
  92. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +0 -28
  93. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +0 -1
  94. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +0 -48
  95. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +0 -1
  96. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +0 -28
  97. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +0 -1
  98. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts +0 -16
  99. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts.map +0 -1
  100. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts +0 -23
  101. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts.map +0 -1
@@ -1,148 +1,155 @@
1
- import { i32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
- import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
3
- import { chunk_decode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_decode_g_buffer_normal.js";
4
- import {
5
- chunk_texture_channel_compute_variance_center
6
- } from "../../shader/chunk/texture/chunk_texture_channel_compute_variance_center.js";
7
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
8
- import { ImageShader } from "../../shader/ImageShader.js";
9
- import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
10
- import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
11
- import { chunk_compute_edge_stopping_weight } from "../../shader/chunk/filter/chunk_compute_edge_stopping_weight.js";
12
-
13
- export const ATORUS_UNIFORMS_STRUCT = WebGPUStruct.from({
14
- step_size: i32
15
- });
16
-
17
- const resources = new ShaderResourceSetDescriptor();
18
-
19
- // per-pass, four bytes, read-only: immediate data rather than a uniform buffer
20
- resources.setImmediate("settings", ATORUS_UNIFORMS_STRUCT);
21
-
22
- resources.createGroup()
23
- .addTexture("tInput")
24
- .addTexture("tDepth")
25
- .addTexture("tNormal", "uint");
26
-
27
- const body = CodeChunk.from(
28
- //language=WGSL
29
- `
30
- const phi_visibility = 4.0;
31
- const phi_normal = 128.0;
32
- const sigma_depth = 1.0;
33
-
34
- @fragment
35
- fn main(
36
- @builtin(position) coord: vec4<f32>,
37
- ) -> @location(0) vec2<f32>{
38
- let ipos = vec2<i32>(coord.xy);
39
- let screen_size = vec2<i32>(textureDimensions(tInput));
40
-
41
- const eps_variance = 1e-10;
42
- const kernel_weights = array<f32,3>( 1.0, 2.0 / 3.0, 1.0 / 6.0 );
43
-
44
- // constant samplers to prevent the compiler from generating code which
45
- // fetches the sampler descriptor from memory for each texture access
46
- let center_visibility = textureLoad(tInput, ipos, 0).rg;
47
-
48
- // variance estimate from per-pixel moments, filtered using 3x3 gaussian blur
49
- let variance = texture_channel_compute_variance_center( ipos, tInput);
50
-
51
- let std_dev = sqrt(max(0.0, eps_variance + variance));
52
-
53
- let phi_visibility = phi_visibility * std_dev;
54
-
55
- // explicitly store/accumulate center pixel with weight 1 to prevent issues
56
- // with the edge-stopping functions
57
- var sum_w_visibility = 1.0;
58
- var sum_visibility = center_visibility;
59
-
60
-
61
- let current_normal = decode_g_buffer_normal(textureLoad(tNormal, ipos, 0).xy);
62
- let center_depth = textureLoad(tDepth, ipos, 0).r;
63
-
64
- const offsets = array< vec2<i32>,8>(
65
- vec2( -1, -1 ),
66
- vec2( 0, -1 ) ,
67
- vec2( 1, -1 ),
68
- vec2( -1, 0 ),
69
- vec2( 1, 0 ),
70
- vec2( -1, 1 ),
71
- vec2( 0, 1 ),
72
- vec2( 1, 1 ),
73
- );
74
-
75
- const num_samples = 8;
76
-
77
- for(var i=0; i< num_samples; i++){
78
- let offset = offsets[i];
79
-
80
- let xx = offset.x;
81
- let yy = offset.y;
82
-
83
- let p = ipos + offset * settings.step_size;
84
- let inside = all(p >= vec2(0, 0)) && all(p < screen_size);
85
-
86
- if(!inside){
87
- continue;
88
- }
89
-
90
- let kernel = kernel_weights[ abs(xx) ] * kernel_weights[ abs(yy) ];
91
-
92
- let sample_visibility = textureLoad(tInput, p, 0).rg;
93
-
94
- let sample_normal = decode_g_buffer_normal(textureLoad(tNormal, p, 0).xy);
95
- let sample_depth = textureLoad(tDepth, p, 0).r;
96
-
97
- // compute the edge-stopping functions
98
- let w = compute_edge_stopping_weight(
99
- center_depth,
100
- sample_depth,
101
- sigma_depth,
102
-
103
- current_normal,
104
- sample_normal,
105
- phi_normal,
106
-
107
- center_visibility.r,
108
- sample_visibility.r,
109
- phi_visibility
110
- );
111
-
112
- let w_visibility = w * kernel;
113
-
114
- // both channels carry moments (E[X], E[X²]) - average linearly so the
115
- // pair remains a valid moment estimate that downstream get_std_dev can interpret.
116
- sum_w_visibility += w_visibility;
117
- sum_visibility += w_visibility * sample_visibility;
118
- }
119
-
120
- // output first two moments
121
- let out_visibility = sum_visibility / sum_w_visibility;
122
-
123
- return out_visibility;
124
- }
125
- `,
126
- [
127
- ATORUS_UNIFORMS_STRUCT.declaration_chunk,
128
- chunk_texture_channel_compute_variance_center,
129
- chunk_decode_g_buffer_normal,
130
- chunk_compute_edge_stopping_weight,
131
- ]);
132
-
133
- /**
134
- * Based on REBLUR paper, a type of Gaussian blur with edge-stopping
135
- * @type {ShaderDescriptor}
136
- */
137
- export const fragment_shader_denoise_ao = ShaderDescriptor.from({
138
- label: "A-torus Denoise",
139
- resources,
140
- body
141
- });
142
-
143
- export const shader_denoise_luminance_spatial = ImageShader.from({
144
- descriptor: fragment_shader_denoise_ao,
145
- targets: [
146
- { format: "rg16float" }
147
- ]
1
+ import { DEPTH_STENCIL_FOREGROUND_ONLY } from "../../depth/DEPTH_STENCIL_FOREGROUND_ONLY.js";
2
+ import { i32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
3
+ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
4
+ import { chunk_decode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_decode_g_buffer_normal.js";
5
+ import {
6
+ chunk_texture_channel_compute_variance_center
7
+ } from "../../shader/chunk/texture/chunk_texture_channel_compute_variance_center.js";
8
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
9
+ import { ImageShader } from "../../shader/ImageShader.js";
10
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
11
+ import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
12
+ import { chunk_compute_edge_stopping_weight } from "../../shader/chunk/filter/chunk_compute_edge_stopping_weight.js";
13
+
14
+ export const ATORUS_UNIFORMS_STRUCT = WebGPUStruct.from({
15
+ step_size: i32
16
+ });
17
+
18
+ const resources = new ShaderResourceSetDescriptor();
19
+
20
+ // per-pass, four bytes, read-only: immediate data rather than a uniform buffer
21
+ resources.setImmediate("settings", ATORUS_UNIFORMS_STRUCT);
22
+
23
+ resources.createGroup()
24
+ .addTexture("tInput")
25
+ .addTexture("tDepth")
26
+ .addTexture("tNormal", "uint");
27
+
28
+ const body = CodeChunk.from(
29
+ //language=WGSL
30
+ `
31
+ const phi_visibility = 4.0;
32
+ const phi_normal = 128.0;
33
+ const sigma_depth = 1.0;
34
+
35
+ @fragment
36
+ fn main(
37
+ @builtin(position) coord: vec4<f32>,
38
+ ) -> @location(0) vec2<f32>{
39
+ let ipos = vec2<i32>(coord.xy);
40
+ let screen_size = vec2<i32>(textureDimensions(tInput));
41
+
42
+ const eps_variance = 1e-10;
43
+ const kernel_weights = array<f32,3>( 1.0, 2.0 / 3.0, 1.0 / 6.0 );
44
+
45
+ // constant samplers to prevent the compiler from generating code which
46
+ // fetches the sampler descriptor from memory for each texture access
47
+ let center_visibility = textureLoad(tInput, ipos, 0).rg;
48
+
49
+ // variance estimate from per-pixel moments, filtered using 3x3 gaussian blur
50
+ let variance = texture_channel_compute_variance_center( ipos, tInput);
51
+
52
+ let std_dev = sqrt(max(0.0, eps_variance + variance));
53
+
54
+ let phi_visibility = phi_visibility * std_dev;
55
+
56
+ // explicitly store/accumulate center pixel with weight 1 to prevent issues
57
+ // with the edge-stopping functions
58
+ var sum_w_visibility = 1.0;
59
+ var sum_visibility = center_visibility;
60
+
61
+
62
+ let current_normal = decode_g_buffer_normal(textureLoad(tNormal, ipos, 0).xy);
63
+ let center_depth = textureLoad(tDepth, ipos, 0).r;
64
+
65
+ const offsets = array< vec2<i32>,8>(
66
+ vec2( -1, -1 ),
67
+ vec2( 0, -1 ) ,
68
+ vec2( 1, -1 ),
69
+ vec2( -1, 0 ),
70
+ vec2( 1, 0 ),
71
+ vec2( -1, 1 ),
72
+ vec2( 0, 1 ),
73
+ vec2( 1, 1 ),
74
+ );
75
+
76
+ const num_samples = 8;
77
+
78
+ for(var i=0; i< num_samples; i++){
79
+ let offset = offsets[i];
80
+
81
+ let xx = offset.x;
82
+ let yy = offset.y;
83
+
84
+ let p = ipos + offset * settings.step_size;
85
+ let inside = all(p >= vec2(0, 0)) && all(p < screen_size);
86
+
87
+ if(!inside){
88
+ continue;
89
+ }
90
+
91
+ let kernel = kernel_weights[ abs(xx) ] * kernel_weights[ abs(yy) ];
92
+
93
+ let sample_visibility = textureLoad(tInput, p, 0).rg;
94
+
95
+ let sample_normal = decode_g_buffer_normal(textureLoad(tNormal, p, 0).xy);
96
+ let sample_depth = textureLoad(tDepth, p, 0).r;
97
+
98
+ // compute the edge-stopping functions
99
+ let w = compute_edge_stopping_weight(
100
+ center_depth,
101
+ sample_depth,
102
+ sigma_depth,
103
+
104
+ current_normal,
105
+ sample_normal,
106
+ phi_normal,
107
+
108
+ center_visibility.r,
109
+ sample_visibility.r,
110
+ phi_visibility
111
+ );
112
+
113
+ let w_visibility = w * kernel;
114
+
115
+ // both channels carry moments (E[X], E[X²]) - average linearly so the
116
+ // pair remains a valid moment estimate that downstream get_std_dev can interpret.
117
+ sum_w_visibility += w_visibility;
118
+ sum_visibility += w_visibility * sample_visibility;
119
+ }
120
+
121
+ // output first two moments
122
+ let out_visibility = sum_visibility / sum_w_visibility;
123
+
124
+ return out_visibility;
125
+ }
126
+ `,
127
+ [
128
+ ATORUS_UNIFORMS_STRUCT.declaration_chunk,
129
+ chunk_texture_channel_compute_variance_center,
130
+ chunk_decode_g_buffer_normal,
131
+ chunk_compute_edge_stopping_weight,
132
+ ]);
133
+
134
+ /**
135
+ * Based on REBLUR paper, a type of Gaussian blur with edge-stopping
136
+ * @type {ShaderDescriptor}
137
+ */
138
+ export const fragment_shader_denoise_ao = ShaderDescriptor.from({
139
+ label: "A-torus Denoise",
140
+ resources,
141
+ body
142
+ });
143
+
144
+ export const shader_denoise_luminance_spatial = ImageShader.from({
145
+ descriptor: fragment_shader_denoise_ao,
146
+ depthStencil: DEPTH_STENCIL_FOREGROUND_ONLY,
147
+ targets: [
148
+ {
149
+ format: "rg16float",
150
+ // Background is skipped, so it keeps the clear: moments of visibility 1 (not occluded), zero variance.
151
+ // Downstream neighbourhoods read across silhouettes and must see background as unoccluded.
152
+ clearValue: [1, 1],
153
+ }
154
+ ]
148
155
  })
@@ -24,6 +24,7 @@ export class GTAO {
24
24
  * @param {FrameGraph} graph
25
25
  * @param {number} camera
26
26
  * @param {number} input_depth
27
+ * @param {number} input_hzb
27
28
  * @param {number} input_color
28
29
  * @param {number} input_depth_previous
29
30
  * @param {number} input_normal
@@ -34,7 +35,7 @@ export class GTAO {
34
35
  * @param {number[]} resolution
35
36
  * @returns {{occlusion:number, bent_normals:number, diffuse_indirect:number}}
36
37
  */
37
- graph_pass({ graph, camera, input_depth, input_depth_previous, input_normal, input_velocity, input_occlusion, frame_index, output, resolution }: FrameGraph): {
38
+ graph_pass({ graph, camera, input_depth, input_hzb, input_depth_previous, input_normal, input_velocity, input_occlusion, frame_index, output, resolution }: FrameGraph): {
38
39
  occlusion: number;
39
40
  bent_normals: number;
40
41
  diffuse_indirect: number;
@@ -1 +1 @@
1
- {"version":3,"file":"GTAO.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/GTAO.js"],"names":[],"mappings":"AAQA;;GAEG;AAEH;IAQI;;;OAGG;IACH,uCAUC;IAED;;;;OAIG;IACH,UAHW,MAAM,KACN,MAAM,QAKhB;IAED;;;;OAIG;IACH,0BAFW,eAAe,QAOzB;IAED;;;;;;;;;;;;;;OAcG;IACH,8JAFa;QAAC,SAAS,EAAC,MAAM,CAAC;QAAC,YAAY,EAAC,MAAM,CAAC;QAAC,gBAAgB,EAAC,MAAM,CAAA;KAAC,CA6F5E;;CACJ;8BA5JY,OAAO,6CAA6C,EAAE,eAAe"}
1
+ {"version":3,"file":"GTAO.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/GTAO.js"],"names":[],"mappings":"AAQA;;GAEG;AAEH;IAQI;;;OAGG;IACH,uCAUC;IAED;;;;OAIG;IACH,UAHW,MAAM,KACN,MAAM,QAKhB;IAED;;;;OAIG;IACH,0BAFW,eAAe,QAOzB;IAED;;;;;;;;;;;;;;;OAeG;IACH,yKAFa;QAAC,SAAS,EAAC,MAAM,CAAC;QAAC,YAAY,EAAC,MAAM,CAAC;QAAC,gBAAgB,EAAC,MAAM,CAAA;KAAC,CAiG5E;;CACJ;8BAjKY,OAAO,6CAA6C,EAAE,eAAe"}
@@ -61,6 +61,7 @@ export class GTAO {
61
61
  * @param {FrameGraph} graph
62
62
  * @param {number} camera
63
63
  * @param {number} input_depth
64
+ * @param {number} input_hzb
64
65
  * @param {number} input_color
65
66
  * @param {number} input_depth_previous
66
67
  * @param {number} input_normal
@@ -75,6 +76,7 @@ export class GTAO {
75
76
  graph,
76
77
  camera,
77
78
  input_depth,
79
+ input_hzb,
78
80
  input_depth_previous,
79
81
  input_normal,
80
82
  input_velocity,
@@ -102,6 +104,7 @@ export class GTAO {
102
104
  input_depth,
103
105
  inputs: {
104
106
  tDepth: input_depth,
107
+ tHZB: input_hzb,
105
108
  tNormal: input_normal,
106
109
  camera,
107
110
  settings: {
@@ -119,6 +122,7 @@ export class GTAO {
119
122
  graph,
120
123
  shader: shader_denoise_luminance_spatial,
121
124
  output_resolution: resolution,
125
+ input_depth,
122
126
  inputs: {
123
127
  tInput: moments,
124
128
  tDepth: input_depth,
@@ -134,6 +138,7 @@ export class GTAO {
134
138
  graph,
135
139
  shader: ao_reproject_shader,
136
140
  output: [moments_output],
141
+ input_depth,
137
142
  inputs: {
138
143
  tInput: moments,
139
144
  tHistory: moments_history,
@@ -164,4 +169,3 @@ export class GTAO {
164
169
  };
165
170
  }
166
171
  }
167
-
@@ -15,6 +15,14 @@ export const GTAO_QUALITY_PROFILES: any;
15
15
  * @type {number}
16
16
  */
17
17
  export const GTAO_DEPTH_MIP_LEVELS: number;
18
+ /**
19
+ * Log2 offset applied to the screen-space step distance (in pixels) when selecting a depth pyramid mip level.
20
+ * Higher values stay on finer mips further out; lower values drop to coarser mips sooner.
21
+ *
22
+ * @see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.h#L71
23
+ * @type {number}
24
+ */
25
+ export const GTAO_DEPTH_MIP_SAMPLING_OFFSET: number;
18
26
  /**
19
27
  * distant samples contribute less
20
28
  * must be in [0, 1] range
@@ -1 +1 @@
1
- {"version":3,"file":"GTAO_CONSTANTS.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.js"],"names":[],"mappings":"gCAmBU,MAAM;;;;;;;AAShB;;;GAGG;AACH,wCAiBE;AAEF;;;GAGG;AACH,oCAFU,MAAM,CAEuB;AAEvC;;;GAGG;AACH,8CAA+C;AAE/C;;;;GAIG;AACH,iCAFU,MAAM,CAEoB"}
1
+ {"version":3,"file":"GTAO_CONSTANTS.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/GTAO_CONSTANTS.js"],"names":[],"mappings":"gCAmBU,MAAM;;;;;;;AAShB;;;GAGG;AACH,wCAiBE;AAEF;;;GAGG;AACH,oCAFU,MAAM,CAEuB;AAEvC;;;;;;GAMG;AACH,6CAFU,MAAM,CAEmC;AAEnD;;;GAGG;AACH,8CAA+C;AAE/C;;;;GAIG;AACH,iCAFU,MAAM,CAEoB"}
@@ -53,7 +53,16 @@ export const GTAO_QUALITY_PROFILES = {
53
53
  * see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.h#L55
54
54
  * @type {number}
55
55
  */
56
- export const GTAO_DEPTH_MIP_LEVELS = 0;
56
+ export const GTAO_DEPTH_MIP_LEVELS = 5;
57
+
58
+ /**
59
+ * Log2 offset applied to the screen-space step distance (in pixels) when selecting a depth pyramid mip level.
60
+ * Higher values stay on finer mips further out; lower values drop to coarser mips sooner.
61
+ *
62
+ * @see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.h#L71
63
+ * @type {number}
64
+ */
65
+ export const GTAO_DEPTH_MIP_SAMPLING_OFFSET = 3.30;
57
66
 
58
67
  /**
59
68
  * distant samples contribute less
@@ -1 +1 @@
1
- {"version":3,"file":"ao_reproject_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/ao_reproject_shader.js"],"names":[],"mappings":"AA+JA,8CASE;4BAnK0B,6BAA6B"}
1
+ {"version":3,"file":"ao_reproject_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/ao_reproject_shader.js"],"names":[],"mappings":"AAgKA,8CAaE;4BAvK0B,6BAA6B"}
@@ -1,3 +1,4 @@
1
+ import { DEPTH_STENCIL_FOREGROUND_ONLY } from "../../depth/DEPTH_STENCIL_FOREGROUND_ONLY.js";
1
2
  import { chunk_get_std_dev } from "../../shader/chunk/math/statistics/chunk_get_std_dev.js";
2
3
  import {
3
4
  chunk_texture_sample_catmullrom_hardware_5tap_uv
@@ -163,7 +164,11 @@ export const ao_reproject_shader = new ImageShader({
163
164
  body,
164
165
  resources,
165
166
  }),
167
+ depthStencil: DEPTH_STENCIL_FOREGROUND_ONLY,
166
168
  targets: [{
167
169
  format: "rg16float",
170
+ // Background is skipped, so it keeps the clear: moments of visibility 1 (not occluded), zero variance.
171
+ // This is also next frame's history, whose filtered fetch reaches across silhouettes.
172
+ clearValue: [1, 1],
168
173
  }]
169
174
  })
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Selects the depth pyramid mip level for a GTAO horizon step at `sample_offset_length` screen pixels
3
+ * from the center pixel.
4
+ *
5
+ * Follows Intel XeGTAO's `clamp(log2(sampleOffsetLength) - DepthMIPSamplingOffset, 0, GTAO_DEPTH_MIP_LEVELS - 1)`
6
+ * paired with a `MIP_POINT` sampler (`round` to nearest integer mip). Because Mip 0 lives in `tDepth`
7
+ * while Mips 1..4 live in `tHZB`, rounding here keeps the Mip 0 -> Mip 1 handoff at `lod = 0.5`
8
+ * (`~13.9 px`) rather than `lod > 0.0` (`~9.8 px`). With `GTAO_DEPTH_MIP_SAMPLING_OFFSET = 3.30`:
9
+ * - Mip 0 (`< ~13.9 px`): full-resolution `tDepth`
10
+ * - Mip 1 (`~13.9 .. 27.9 px`): HZB mip 0 (half-res)
11
+ * - Mip 2 (`~27.9 .. 55.7 px`): HZB mip 1 (quarter-res)
12
+ * - Mip 3 (`~55.7 .. 111.4 px`): HZB mip 2 (1/8-res)
13
+ * - Mip 4 (`>= ~111.4 px`): HZB mip 3 (1/16-res)
14
+ *
15
+ * Every mip transition occurs when the tap is at least ~7 texels away at the target mip resolution.
16
+ *
17
+ * @see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.hlsli#L244
18
+ * @type {CodeChunk}
19
+ */
20
+ export const chunk_gtao_compute_mip_level: CodeChunk;
21
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
22
+ //# sourceMappingURL=chunk_gtao_compute_mip_level.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_gtao_compute_mip_level.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/chunk_gtao_compute_mip_level.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;GAkBG;AACH,2CAFU,SAAS,CAUjB;0BAhCwB,oCAAoC"}
@@ -0,0 +1,33 @@
1
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
2
+ import { GTAO_DEPTH_MIP_LEVELS, GTAO_DEPTH_MIP_SAMPLING_OFFSET } from "./GTAO_CONSTANTS.js";
3
+
4
+ const MAX_MIP_LEVEL = Math.max(0, GTAO_DEPTH_MIP_LEVELS - 1);
5
+
6
+ /**
7
+ * Selects the depth pyramid mip level for a GTAO horizon step at `sample_offset_length` screen pixels
8
+ * from the center pixel.
9
+ *
10
+ * Follows Intel XeGTAO's `clamp(log2(sampleOffsetLength) - DepthMIPSamplingOffset, 0, GTAO_DEPTH_MIP_LEVELS - 1)`
11
+ * paired with a `MIP_POINT` sampler (`round` to nearest integer mip). Because Mip 0 lives in `tDepth`
12
+ * while Mips 1..4 live in `tHZB`, rounding here keeps the Mip 0 -> Mip 1 handoff at `lod = 0.5`
13
+ * (`~13.9 px`) rather than `lod > 0.0` (`~9.8 px`). With `GTAO_DEPTH_MIP_SAMPLING_OFFSET = 3.30`:
14
+ * - Mip 0 (`< ~13.9 px`): full-resolution `tDepth`
15
+ * - Mip 1 (`~13.9 .. 27.9 px`): HZB mip 0 (half-res)
16
+ * - Mip 2 (`~27.9 .. 55.7 px`): HZB mip 1 (quarter-res)
17
+ * - Mip 3 (`~55.7 .. 111.4 px`): HZB mip 2 (1/8-res)
18
+ * - Mip 4 (`>= ~111.4 px`): HZB mip 3 (1/16-res)
19
+ *
20
+ * Every mip transition occurs when the tap is at least ~7 texels away at the target mip resolution.
21
+ *
22
+ * @see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.hlsli#L244
23
+ * @type {CodeChunk}
24
+ */
25
+ export const chunk_gtao_compute_mip_level = CodeChunk.from(
26
+ //language=WGSL
27
+ `
28
+ fn gtao_compute_mip_level(sample_offset_length: f32) -> f32 {
29
+ let mip_f = round(log2(max(1.0, sample_offset_length)) - ${GTAO_DEPTH_MIP_SAMPLING_OFFSET});
30
+ return clamp(mip_f, 0.0, f32(${MAX_MIP_LEVEL}));
31
+ }
32
+ `
33
+ );
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Resolves a single reverse-Z device depth from an HZB `(d_min, d_max)` pair (`hzb.x` = farthest,
3
+ * `hzb.y` = closest in the $2^m \times 2^m$ footprint) using a discontinuity-aware slope filter.
4
+ *
5
+ * Why neither pure `hzb.y` (closest) nor pure `0.5 * (hzb.x + hzb.y)` (average) suffices alone
6
+ * (cf. Intel XeGTAO `DepthMIPFilter` and Tomasz Stachowiak / h3r2tic's Tiny Glade linear + point
7
+ * depth-sampling analysis):
8
+ * - On a continuous sloped surface, reverse-Z device depth $1 / (-z_{\text{view}})$ is affine in
9
+ * screen space. Taking only `hzb.y` treats each coarse $2^m \times 2^m$ texel as a flat "Duplo
10
+ * brick" protruding toward the camera, causing false self-occlusion on slopes; averaging
11
+ * `0.5 * (hzb.x + hzb.y)` reconstructs the smooth plane across the footprint.
12
+ * - Across a silhouette edge (depth discontinuity), averaging `hzb.x` and `hzb.y` creates a
13
+ * mid-air "shrink-wrap" phantom surface between foreground and background (or erodes silhouettes
14
+ * against the sky). Weighting `hzb.x` down to zero when `depth_far - depth_near` exceeds the
15
+ * effect falloff collapses the filter to `hzb.y` (the foreground surface).
16
+ *
17
+ * @see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.hlsli#L622
18
+ * @type {CodeChunk}
19
+ */
20
+ export const chunk_gtao_resolve_hzb_depth: CodeChunk;
21
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
22
+ //# sourceMappingURL=chunk_gtao_resolve_hzb_depth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_gtao_resolve_hzb_depth.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/chunk_gtao_resolve_hzb_depth.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;GAkBG;AACH,2CAFU,SAAS,CAiCjB;0BArDwB,oCAAoC"}
@@ -0,0 +1,56 @@
1
+ import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
2
+ import { chunk_get_view_space_depth } from "../../shader/chunk/depth/chunk_get_view_space_depth.js";
3
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
4
+ import { GTAO_EFFECT_FALLOFF_RANGE, GTAO_EFFECT_RADIUS } from "./GTAO_CONSTANTS.js";
5
+
6
+ /**
7
+ * Resolves a single reverse-Z device depth from an HZB `(d_min, d_max)` pair (`hzb.x` = farthest,
8
+ * `hzb.y` = closest in the $2^m \times 2^m$ footprint) using a discontinuity-aware slope filter.
9
+ *
10
+ * Why neither pure `hzb.y` (closest) nor pure `0.5 * (hzb.x + hzb.y)` (average) suffices alone
11
+ * (cf. Intel XeGTAO `DepthMIPFilter` and Tomasz Stachowiak / h3r2tic's Tiny Glade linear + point
12
+ * depth-sampling analysis):
13
+ * - On a continuous sloped surface, reverse-Z device depth $1 / (-z_{\text{view}})$ is affine in
14
+ * screen space. Taking only `hzb.y` treats each coarse $2^m \times 2^m$ texel as a flat "Duplo
15
+ * brick" protruding toward the camera, causing false self-occlusion on slopes; averaging
16
+ * `0.5 * (hzb.x + hzb.y)` reconstructs the smooth plane across the footprint.
17
+ * - Across a silhouette edge (depth discontinuity), averaging `hzb.x` and `hzb.y` creates a
18
+ * mid-air "shrink-wrap" phantom surface between foreground and background (or erodes silhouettes
19
+ * against the sky). Weighting `hzb.x` down to zero when `depth_far - depth_near` exceeds the
20
+ * effect falloff collapses the filter to `hzb.y` (the foreground surface).
21
+ *
22
+ * @see https://github.com/GameTechDev/XeGTAO/blob/a5b1686c7ea37788eeb3576b5be47f7c03db532c/Source/Rendering/Shaders/XeGTAO.hlsli#L622
23
+ * @type {CodeChunk}
24
+ */
25
+ export const chunk_gtao_resolve_hzb_depth = CodeChunk.from(
26
+ //language=WGSL
27
+ `
28
+ fn gtao_resolve_hzb_depth(
29
+ hzb: vec2<f32>,
30
+ camera: ${CAMERA_UNIFORM_STRUCT.wgsl_ref},
31
+ ) -> f32 {
32
+ // If any texel in the footprint is background/sky (reverse-Z depth <= 0), do not blend across
33
+ // the silhouette into the sky (which also avoids 0 / 0 or inf - inf under an infinite far plane).
34
+ if (hzb.x <= 0.0) {
35
+ return hzb.y;
36
+ }
37
+
38
+ // XeGTAO DepthMIPFilter falloff: empirically 0.75 * effectRadius works well across mips.
39
+ const effect_radius = 0.75 * ${GTAO_EFFECT_RADIUS};
40
+ const falloff_range = ${GTAO_EFFECT_FALLOFF_RANGE} * effect_radius;
41
+ const falloff_from = effect_radius * (1.0 - ${GTAO_EFFECT_FALLOFF_RANGE});
42
+ const falloff_mul = -1.0 / falloff_range;
43
+ const falloff_add = falloff_from / falloff_range + 1.0;
44
+
45
+ let depth_far = get_view_space_depth(hzb.x, camera);
46
+ let depth_near = get_view_space_depth(hzb.y, camera);
47
+
48
+ let w = saturate(fma(depth_far - depth_near, falloff_mul, falloff_add));
49
+
50
+ return mix(hzb.y, hzb.x, w / (1.0 + w));
51
+ }
52
+ `,
53
+ [
54
+ chunk_get_view_space_depth,
55
+ ]
56
+ );
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Samples reverse-Z device depth for a GTAO horizon tap at `uv` and `mip_level`.
3
+ *
4
+ * - `mip_level <= 0.0` reads full-resolution `tDepth` (mip 0).
5
+ * - `mip_level > 0.0` reads `tHZB` at `mip_level - 1.0` (since `tHZB` mip 0 is half-resolution, i.e.
6
+ * screen mip 1) in normalized UV space (matching `HierarchicalZBuffer`'s alignment-padded reduction)
7
+ * and resolves the `(min, max)` depth pair through {@link chunk_gtao_resolve_hzb_depth}.
8
+ *
9
+ * @type {CodeChunk}
10
+ */
11
+ export const chunk_gtao_sample_depth: CodeChunk;
12
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
13
+ //# sourceMappingURL=chunk_gtao_sample_depth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_gtao_sample_depth.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/gtao/chunk_gtao_sample_depth.js"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH,sCAFU,SAAS,CAqBjB;0BAnCwB,oCAAoC"}
@@ -0,0 +1,42 @@
1
+ import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
2
+ import { SCREEN_DEPTH_RESOURCE, SCREEN_HZB_RESOURCE } from "../../shader/chunk/screen_space/SCREEN_SPACE_RESOURCES.js";
3
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
4
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
5
+ import { chunk_gtao_resolve_hzb_depth } from "./chunk_gtao_resolve_hzb_depth.js";
6
+
7
+ const POINT_SAMPLER_RESOURCE = ShaderResourceDescriptor.sampler("sPoint", "non-filtering");
8
+
9
+ /**
10
+ * Samples reverse-Z device depth for a GTAO horizon tap at `uv` and `mip_level`.
11
+ *
12
+ * - `mip_level <= 0.0` reads full-resolution `tDepth` (mip 0).
13
+ * - `mip_level > 0.0` reads `tHZB` at `mip_level - 1.0` (since `tHZB` mip 0 is half-resolution, i.e.
14
+ * screen mip 1) in normalized UV space (matching `HierarchicalZBuffer`'s alignment-padded reduction)
15
+ * and resolves the `(min, max)` depth pair through {@link chunk_gtao_resolve_hzb_depth}.
16
+ *
17
+ * @type {CodeChunk}
18
+ */
19
+ export const chunk_gtao_sample_depth = CodeChunk.from(
20
+ //language=WGSL
21
+ `
22
+ fn gtao_sample_depth(
23
+ uv: vec2<f32>,
24
+ mip_level: f32,
25
+ camera: ${CAMERA_UNIFORM_STRUCT.wgsl_ref},
26
+ ) -> f32 {
27
+ if (mip_level <= 0.0) {
28
+ return textureSampleLevel(tDepth, sPoint, uv, 0.0).x;
29
+ }
30
+
31
+ let hzb = textureSampleLevel(tHZB, sPoint, uv, mip_level - 1.0).xy;
32
+ return gtao_resolve_hzb_depth(hzb, camera);
33
+ }
34
+ `,
35
+ [
36
+ chunk_gtao_resolve_hzb_depth,
37
+ ]
38
+ );
39
+
40
+ chunk_gtao_sample_depth.requireResource(SCREEN_DEPTH_RESOURCE);
41
+ chunk_gtao_sample_depth.requireResource(SCREEN_HZB_RESOURCE);
42
+ chunk_gtao_sample_depth.requireResource(POINT_SAMPLER_RESOURCE);