@woosh/meep-engine 3.60.2 → 3.60.4
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.
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +3 -0
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
- package/editor/ecs/component/editors/ecs/Trail3DEditor.js +6 -0
- package/package.json +1 -1
- package/src/engine/ecs/ik/PLAN.md +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +1 -2
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts +14 -0
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts.map +1 -0
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.js +22 -0
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +19 -3
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.js +31 -4
- package/src/engine/graphics/ecs/trail3d/advance_trail.js +1 -1
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +5 -5
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +1 -1
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +6 -6
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +10 -0
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +1 -1
- package/src/engine/graphics3/trail/trail_tube_write_geometry.js +13 -1
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +2 -2
- package/src/engine/physics/cloth/ecs/cloth_geodesic.js +2 -2
- package/src/shade/playground/probe_clipmap/README.md +1 -0
- package/src/shade/playground/probe_clipmap/index.html +5 -0
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +16 -2
- package/src/shade/playground/vgeo_scene/README.md +1 -1
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +4 -6
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +34 -36
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +162 -163
- package/src/shade/renderer/atmosphere/compute_mie_absorption.d.ts +1 -1
- package/src/shade/renderer/atmosphere/compute_mie_absorption.js +1 -1
- package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_EARTH.js +1 -1
- package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_PARAMETERS_STRUCT.js +1 -1
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +164 -164
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
- package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +2 -2
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.d.ts +1 -1
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.js +1 -1
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts +4 -5
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.js +6 -7
- package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +1 -1
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +2 -4
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +3 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +119 -38
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +22 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +4 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +50 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +6 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +7 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts +13 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.js +13 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +20 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts +18 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.js +42 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +5 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +4 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +13 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts +52 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.js +250 -0
- package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +7 -7
- package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +2 -2
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts +39 -0
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.js +119 -0
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +15 -7
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/execute_filter_environment_map.js +66 -83
- package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/graph_filter_environment_map.js +15 -6
- package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts +3 -0
- package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/shader_blur_environment_map.js +111 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts +3 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/{shader_convolve_reflection_map_from_averages.js → shader_convolve_reflection_map_from_blurred.js} +25 -66
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +0 -1
- package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +1 -4
- package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +2 -2
- package/src/shade/renderer/postprocess/nss/NOTES.md +14 -21
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -3
- package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.js +1 -3
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts +5 -6
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.js +9 -10
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +48 -49
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +12 -16
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +246 -246
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +1 -2
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +34 -35
- package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.d.ts +2 -2
- package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.js +2 -2
- package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/chunk_compute_extinction.js +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.js +1 -1
- package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +4 -7
- package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts +3 -3
- package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js +3 -3
- package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +12 -19
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts +9 -10
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.js +9 -10
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts +4 -4
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js +5 -5
- package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +1 -1
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts +1 -2
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.js +1 -2
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts +14 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.js +19 -6
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts +10 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.js +14 -6
- package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.js +1 -1
- package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +9 -14
- package/src/shade/renderer/shadow/contact/FINDINGS.md +5 -5
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts +2 -3
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.js +7 -8
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.d.ts +1 -1
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.js +12 -12
- package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +2 -2
- package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/VSMPageManager.js +3 -4
- package/src/shade/renderer/texture/mipmaps/NOTES.md +1 -2
- package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +1 -1
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts +0 -13
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts.map +0 -1
|
@@ -23,65 +23,42 @@ import { chunk_reflection_sample_weight } from "./chunk_reflection_sample_weight
|
|
|
23
23
|
import { chunk_sphere_probe_lod_to_roughness } from "./chunk_sphere_probe_lod_to_roughness.js";
|
|
24
24
|
import { BSDF_ROUGHNESS_MINIMUM } from "./DEFINES.js";
|
|
25
25
|
import { ENVIRONMENT_MAP_SAMPLER_RESOURCE } from "./ENVIRONMENT_MAP_SAMPLER_RESOURCE.js";
|
|
26
|
+
import { LEVEL_1_SAMPLE_COUNT } from "./environment_level_1_blur_plan.js";
|
|
26
27
|
|
|
27
28
|
const resources = new ShaderResourceSetDescriptor();
|
|
28
29
|
|
|
30
|
+
// the lobe's roughness once narrowed by the blur it reads through, see environment_level_1_blur_plan
|
|
31
|
+
resources.setImmediate("lobe_roughness", "f32");
|
|
32
|
+
|
|
29
33
|
resources.createGroup()
|
|
30
|
-
//
|
|
31
|
-
.addTexture("
|
|
32
|
-
.addTexture("averages", "float")
|
|
34
|
+
// level 0 blurred by a Gaussian, see shader_blur_environment_map
|
|
35
|
+
.addTexture("blurred", "float")
|
|
33
36
|
.addStorageTexture("output", "rgba16float")
|
|
34
37
|
.add(ENVIRONMENT_MAP_SAMPLER_RESOURCE)
|
|
35
38
|
;
|
|
36
39
|
|
|
37
40
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Level 1 of the prefilter, by filtered importance sampling: each sample reads the plain average of
|
|
50
|
-
* level 0 whose texel is the solid angle the sample stands for, so a texel brighter than its
|
|
51
|
-
* neighbours is averaged into the coarser texel the sample reads instead of being hit or missed by
|
|
52
|
-
* the sample pattern. Point taps into level 0 — 196 of them over a cone of 639 level-0 texels — put
|
|
53
|
-
* one bright texel's share of level 1 anywhere from 0.79 to 1.21 of its energy, and an HDR sun
|
|
54
|
-
* came out 0.66% brighter than it went in.
|
|
41
|
+
* Level 1 of the prefilter, from a copy of level 0 blurred by a Gaussian.
|
|
42
|
+
*
|
|
43
|
+
* Point taps into level 0 — 196 of them over a cone of 639 level-0 texels on a 1024 map — put one
|
|
44
|
+
* bright texel's share of level 1 anywhere from 0.79 to 1.21 of its energy, and an HDR sun came out
|
|
45
|
+
* 0.66% brighter than it went in. Read from a copy blurred wider than the samples are apart, every
|
|
46
|
+
* texel lands in level 1 once, whatever the sample pattern. The blur and the lobe are both Gaussians,
|
|
47
|
+
* so the lobe narrows by the blur's variance and level 1 comes out the lobe it is asked for.
|
|
48
|
+
*
|
|
49
|
+
* Samples are uniform in the cone, so each stands for the same solid angle. UE importance-samples
|
|
50
|
+
* and reads a coarser average in the lobe's tail than in its core; here the sun came out in blocks.
|
|
55
51
|
*
|
|
56
52
|
* Level 1 only. The levels after it read the level above, already smooth at their sample spacing
|
|
57
|
-
* (see shader_convolve_reflection_map).
|
|
58
|
-
* 8 to 16 texels a side, too coarse an octahedral grid to keep a bright texel's energy: ±11% at
|
|
59
|
-
* level 4, and a sky 11% brighter.
|
|
53
|
+
* (see shader_convolve_reflection_map).
|
|
60
54
|
*
|
|
61
55
|
* @see https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
|
|
62
|
-
* @see https://github.com/EpicGames/UnrealEngine/blob/5.4/Engine/Shaders/Private/ReflectionEnvironmentShaders.usf FilterPS
|
|
63
56
|
* @see https://projects.blender.org/blender/blender/src/commit/866ef5b468589587395b1ee7480ea75b4c0fbc26/source/blender/draw/engines/eevee_next/shaders/eevee_lightprobe_sphere_convolve_comp.glsl for the lobe
|
|
64
57
|
* @type {CodeChunk}
|
|
65
58
|
*/
|
|
66
59
|
const body = CodeChunk.from(
|
|
67
60
|
//language=WGSL
|
|
68
61
|
`
|
|
69
|
-
/// level 0 is the map's own, the levels below it are the averages
|
|
70
|
-
fn sample_source_level(direction: vec3<f32>, level: u32) -> vec4<f32> {
|
|
71
|
-
let uv = uv_octahedral_unit_encode(direction);
|
|
72
|
-
|
|
73
|
-
if (level == 0u) {
|
|
74
|
-
let size = f32(textureDimensions(level_0).x);
|
|
75
|
-
|
|
76
|
-
return textureSampleLevel(level_0, sEnvironment, texture_octahedral_skirt_uv(uv, size), 0.0);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
let average_level = level - 1u;
|
|
80
|
-
let size = f32(textureDimensions(averages, average_level).x);
|
|
81
|
-
|
|
82
|
-
return textureSampleLevel(averages, sEnvironment, texture_octahedral_skirt_uv(uv, size), f32(average_level));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
62
|
@compute @workgroup_size(16,16,1)
|
|
86
63
|
fn main(
|
|
87
64
|
@builtin(global_invocation_id) global_invocation_id : vec3<u32>,
|
|
@@ -94,7 +71,7 @@ fn main(
|
|
|
94
71
|
return;
|
|
95
72
|
}
|
|
96
73
|
|
|
97
|
-
|
|
74
|
+
// the cone is the lobe's as asked for; only its weights narrow
|
|
98
75
|
let roughness = max(sphere_probe_lod_to_roughness(1.0), ${BSDF_ROUGHNESS_MINIMUM});
|
|
99
76
|
let cone_cos = cone_cosine_from_roughness(roughness);
|
|
100
77
|
|
|
@@ -107,37 +84,19 @@ fn main(
|
|
|
107
84
|
var weight_accum = 0.0;
|
|
108
85
|
var radiance_accum = vec4(0.0);
|
|
109
86
|
|
|
110
|
-
const sample_count = ${
|
|
87
|
+
const sample_count = ${LEVEL_1_SAMPLE_COUNT};
|
|
111
88
|
|
|
112
|
-
|
|
113
|
-
let sample_solid_angle = 2.0 * PI * (1.0 - cone_cos) / f32(sample_count);
|
|
114
|
-
|
|
115
|
-
// level 0's octahedral square, n texels a side, spans 2 in octahedron coordinates; a texel there
|
|
116
|
-
// covers (2/n)^2 of it, and the octahedron's solid angle per unit area is |d|_1^3 along unit d
|
|
117
|
-
let level_0_interior = f32(textureDimensions(level_0).x) - 2.0;
|
|
118
|
-
let level_0_texel_area = 4.0 / (level_0_interior * level_0_interior);
|
|
119
|
-
|
|
120
|
-
let last_level = f32(textureNumLevels(averages));
|
|
89
|
+
let blurred_size = f32(textureDimensions(blurred).x);
|
|
121
90
|
|
|
122
91
|
for (var i = 0u; i < sample_count; i++) {
|
|
123
92
|
let rand = hammersley_2d(i, sample_count);
|
|
124
93
|
|
|
125
94
|
let in_direction = normalize(basis * uniform_sample_cone(rand, cone_cos));
|
|
126
95
|
|
|
127
|
-
let
|
|
128
|
-
let
|
|
129
|
-
|
|
130
|
-
let lod = clamp(0.5 * log2(sample_solid_angle / texel_solid_angle), 0.0, last_level);
|
|
131
|
-
let lod_floor = floor(lod);
|
|
132
|
-
let level = u32(lod_floor);
|
|
133
|
-
|
|
134
|
-
let radiance = mix(
|
|
135
|
-
sample_source_level(in_direction, level),
|
|
136
|
-
sample_source_level(in_direction, min(level + 1u, u32(last_level))),
|
|
137
|
-
lod - lod_floor
|
|
138
|
-
);
|
|
96
|
+
let in_uv = texture_octahedral_skirt_uv(uv_octahedral_unit_encode(in_direction), blurred_size);
|
|
97
|
+
let radiance = textureSampleLevel(blurred, sEnvironment, in_uv, 0.0);
|
|
139
98
|
|
|
140
|
-
let weight = reflection_sample_weight(out_direction, in_direction,
|
|
99
|
+
let weight = reflection_sample_weight(out_direction, in_direction, lobe_roughness);
|
|
141
100
|
|
|
142
101
|
radiance_accum += radiance * weight;
|
|
143
102
|
weight_accum += weight;
|
|
@@ -162,8 +121,8 @@ fn main(
|
|
|
162
121
|
]
|
|
163
122
|
);
|
|
164
123
|
|
|
165
|
-
export const
|
|
166
|
-
label: 'Convolve reflection map from
|
|
124
|
+
export const shader_convolve_reflection_map_from_blurred = new ComputeShader(ShaderDescriptor.from({
|
|
125
|
+
label: 'Convolve reflection map from blurred',
|
|
167
126
|
body,
|
|
168
127
|
resources
|
|
169
128
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_downsample_environment_map.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/shader_downsample_environment_map.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_downsample_environment_map.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/shader_downsample_environment_map.js"],"names":[],"mappings":"AAmGA,8DAII;8BAhG0B,+BAA+B"}
|
|
@@ -29,7 +29,6 @@ resources.createGroup()
|
|
|
29
29
|
* (chunk_octahedral_solid_angle): a texel the octahedral fold crosses is no pair of spherical
|
|
30
30
|
* triangles, and a bright one came out 4.7% dim.
|
|
31
31
|
*
|
|
32
|
-
* @see https://github.com/EpicGames/UnrealEngine/blob/5.4/Engine/Shaders/Private/ReflectionEnvironmentShaders.usf DownsamplePS
|
|
33
32
|
* @type {CodeChunk}
|
|
34
33
|
*/
|
|
35
34
|
const body = CodeChunk.from(
|
|
@@ -274,10 +274,7 @@ machine. Every VM pass and the bind pass compile and build pipelines under Tint
|
|
|
274
274
|
|
|
275
275
|
## Sources
|
|
276
276
|
|
|
277
|
-
-
|
|
278
|
-
(`FNiagaraEmitterParameters` and `FNiagaraSystemParameters` are the engine's members of each scope,
|
|
279
|
-
with User values beside them), `Classes/NiagaraGPUSystemTick.h`,
|
|
280
|
-
`Classes/NiagaraParameterCollection.h` (globals bound by name).
|
|
277
|
+
- Niagara Emitter and System parameter namespaces (with User values beside them) and Parameter Collections (globals bound by name).
|
|
281
278
|
- [Niagara key concepts (namespace read/write table)](https://dev.epicgames.com/documentation/unreal-engine/key-concepts-in-niagara-effects-for-unreal-engine)
|
|
282
279
|
- [VFX Graph instancing](https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@17.2/manual/Instancing.html)
|
|
283
280
|
— instances share code and load their properties per instance.
|
|
@@ -359,8 +359,8 @@ Register peaks are pinned in `particle_group_library.spec.js`, all far under 48.
|
|
|
359
359
|
- **An emitter-local frame** (Shuriken "Local"). It needs the scene database in the draw.
|
|
360
360
|
`emitterRotation` does the same in INIT.
|
|
361
361
|
|
|
362
|
-
Precedent
|
|
363
|
-
compose the particle's rotation inside the facing frame. The mesh paths (Niagara
|
|
362
|
+
Precedent: Niagara meshes, Niagara sprites, Unity VFX Graph and PopcornFX all
|
|
363
|
+
compose the particle's rotation inside the facing frame. The mesh paths (Niagara mesh orientation,
|
|
364
364
|
PopcornFX `Orientation`, Houdini `orient`) store a quaternion.
|
|
365
365
|
|
|
366
366
|
## Touch list
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Neural Super Sampling (NSS)
|
|
2
2
|
|
|
3
|
-
Port of
|
|
3
|
+
Port of ARM's Neural Super Sampling
|
|
4
4
|
reference design onto the engine's FrameGraph. Same role as TAA — temporal
|
|
5
5
|
anti-aliasing + upscale — but the spatial reconstruction kernel is predicted
|
|
6
6
|
per-pixel by a small CNN (Kernel-Prediction Network) instead of a fixed
|
|
@@ -116,8 +116,7 @@ automatically; the renderer only needs to flip
|
|
|
116
116
|
|
|
117
117
|
### Source
|
|
118
118
|
|
|
119
|
-
Extracted from `nss_v0_1_1_int8.vgf` in the ARM Neural Graphics
|
|
120
|
-
Unreal SDK in two passes:
|
|
119
|
+
Extracted from `nss_v0_1_1_int8.vgf` in the ARM Neural Graphics SDK in two passes:
|
|
121
120
|
|
|
122
121
|
1. **VGF constants table** via ARM's own `Model_Parser.exe` — gives
|
|
123
122
|
us the conv weights for every layer and biases for the 7 encoder
|
|
@@ -217,18 +216,14 @@ fp32 throughout our pipeline so the offset is implicit.
|
|
|
217
216
|
#### Head ordering — ARM's quantized model
|
|
218
217
|
|
|
219
218
|
The 6 heads come out of the SPIR-V in CONCAT order, which is NOT
|
|
220
|
-
KPN col 0..3 + ThetaAlpha + FB. ARM's
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Result->OutputIndices.KPNFilterCol2 = 3;
|
|
229
|
-
Result->OutputIndices.KPNFilterCol1 = 4;
|
|
230
|
-
Result->OutputIndices.KPNFilterCol0 = 5;
|
|
231
|
-
```
|
|
219
|
+
KPN col 0..3 + ThetaAlpha + FB. ARM's quantized model assigns the output head slots as:
|
|
220
|
+
|
|
221
|
+
- Slot 0: Feedback
|
|
222
|
+
- Slot 1: ThetaAlpha
|
|
223
|
+
- Slot 2: KPN column 3
|
|
224
|
+
- Slot 3: KPN column 2
|
|
225
|
+
- Slot 4: KPN column 1
|
|
226
|
+
- Slot 5: KPN column 0
|
|
232
227
|
|
|
233
228
|
Our postprocess shader reads the columns from `[5, 4, 3, 2]` in
|
|
234
229
|
that order to recover (col 0, col 1, col 2, col 3), and reads
|
|
@@ -236,7 +231,7 @@ ThetaAlpha from slot 1.
|
|
|
236
231
|
|
|
237
232
|
#### Postprocess two-stage blend
|
|
238
233
|
|
|
239
|
-
Mirrors ARM's
|
|
234
|
+
Mirrors ARM's reference postprocess:
|
|
240
235
|
1. Apply the 4×4 KPN to the jittered colour, normalising by
|
|
241
236
|
the (positive) weight sum. The centre tap (col=1, row=1) is also
|
|
242
237
|
captured separately.
|
|
@@ -275,8 +270,7 @@ Audited against `ffx_nss_callbacks_glsl.h`, `ffx_nss_preprocess.h`,
|
|
|
275
270
|
zeros tiny motion (`MotionWarpThresh=0.01`) and scales
|
|
276
271
|
disocclusion by `~0.725` on near-static frames
|
|
277
272
|
(`MotionDisThresh=0.25`). We do neither.
|
|
278
|
-
- **History warp filter:** ARM uses Catmull-Rom with deringing
|
|
279
|
-
(`CatmullRomWithDering`, NSSPostprocess.usf:55). We use plain
|
|
273
|
+
- **History warp filter:** ARM uses Catmull-Rom with deringing. We use plain
|
|
280
274
|
bilinear via `SAMPLER_LINEAR_UPSCALE`. Slight softness on
|
|
281
275
|
high-frequency history detail.
|
|
282
276
|
- **Per-tensor input scales (forward pass):** ARM's INT8
|
|
@@ -292,7 +286,7 @@ Audited against `ffx_nss_callbacks_glsl.h`, `ffx_nss_preprocess.h`,
|
|
|
292
286
|
- **Exposure factor:** ARM multiplies network colour reads by
|
|
293
287
|
`Exposure()` and the final write by `1/Exposure()`
|
|
294
288
|
(`ffx_nss_postprocess.h:48`). We hard-code `EXPOSURE = e^2` to
|
|
295
|
-
match ARM's
|
|
289
|
+
match ARM's reference constant — adequate for SDR output,
|
|
296
290
|
but doesn't track engine exposure changes.
|
|
297
291
|
- **2x preset KPN footprint:** ARM's 2x path uses a precomputed
|
|
298
292
|
`kernelLUT` indexed by `(out_pixel + jitter_tile_offset) % 2`,
|
|
@@ -326,12 +320,11 @@ via `NSS.recommended_jitter_sequence_size(upscale_ratio)`), forwards
|
|
|
326
320
|
| INT8 quantization with TOSA RESCALE + TABLE | Per-channel `127 * mult / 2^shift` rescale + per-head `output_zp` shift before LUT lookup; LUT dequant matches ARM's `(int8 + 127) / 255` |
|
|
327
321
|
| 2× preset uses a 4-tap LUT pattern | Generic 4×4 KPN footprint for any upscale ratio |
|
|
328
322
|
| Mirror-pad to round to 8 | Compute shader early-outs out-of-range threads; same effect, no extra pass |
|
|
329
|
-
|
|
|
323
|
+
| Sparse motion vectors | Engine velocity is already dense and pixel-space; no convert pass |
|
|
330
324
|
| Feedback aliased as R8G8B8A8_SNORM image | Plain rgba16f texture |
|
|
331
325
|
|
|
332
326
|
## References
|
|
333
327
|
|
|
334
|
-
- ARM / Unreal plugin: <https://github.com/arm/neural-graphics-for-unreal/tree/main>
|
|
335
328
|
- ARM SDK (kernel sources): `Source/NG-SDK/sdk/include/FidelityFX/gpu/nss/`
|
|
336
329
|
- ARM SDK Model Parser: `Source/NG-SDK/sdk/tools/binary_store/Model_Parser.exe`
|
|
337
330
|
- FSR2 depth-clip (used unchanged for the disocclusion mask):
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
* @typedef {import("../../GraphicsContext.js").GraphicsContext} GraphicsContext
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* Neural Super Sampling — port of ARM's NSS reference design
|
|
7
|
-
* (`https://github.com/arm/neural-graphics-for-unreal`) onto the
|
|
8
|
-
* engine's FrameGraph.
|
|
6
|
+
* Neural Super Sampling — port of ARM's NSS reference design onto the engine's FrameGraph.
|
|
9
7
|
*
|
|
10
8
|
* Pipeline (per frame):
|
|
11
9
|
* 1. Preprocess — assemble a 12-channel tensor from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NSS.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/NSS.js"],"names":[],"mappings":"AAgCA;;;GAGG;AAEH
|
|
1
|
+
{"version":3,"file":"NSS.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/NSS.js"],"names":[],"mappings":"AAgCA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH;IAsaI;;;;;;OAMG;IACH,uDAHW,MAAM,GACJ,MAAM,CAKlB;IAsCD,uGAQC;IAxRD;;OAEG;IACH,sBAFW,eAAe,EAwCzB;IAhOD;;;OAGG;IACH,uBAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;;;OAKG;IACH,eAFU,OAAO,CAEI;IAErB;;;;;;;;OAQG;IACH,mBAFU,MAAM,CAEQ;IAExB;;;;;;;OAOG;IACH,gBAFU,MAAM,CAEM;IAEtB;;;;;OAKG;IACH,YAFU,MAAM,CAED;IAEf;;;;;;;;;;;OAWG;IACH,mBAFU,MAAM,CAEQ;IAExB;;;;;;OAMG;IACH,gBAFU,MAAM,CAEK;IAErB;;;;;;OAMG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;;;;;;OASG;IACH,eAFU,MAAM,CAEI;IACpB,wCAAwC;IACxC,eAD8B,MAAM,CAChB;IAkKpB;;;;;OAKG;IACH,+BAyHC;IAED,wCAAwC;IACxC,0BAEC;IArKD;;OAEG;IACH,gBA4BC;IAwID;;OAEG;IACH,uCAEC;IAED;;OAEG;IACH,mCAEC;IAcD;;OAEG;IACH,2BAEC;IA2CD,2BAAkF;IAClF,0BAA+C;IAE/C;;;;;;;;;;;;;;;;;;OAkBG;IACH;QAf4B,KAAK,EAAtB,UAAU;QACG,qBAAqB,EAAlC,MAAM;QACO,qBAAqB,EAAlC,MAAM;QACO,gBAAgB,EAA7B,MAAM;QACO,+BAA+B,EAA5C,MAAM;QAKO,qBAAqB,EAAlC,MAAM;QACO,cAAc,EAA3B,MAAM;QACS,iBAAiB,EAAhC,MAAM,EAAE;QACO,iBAAiB,EAAhC,MAAM,EAAE;QACN,MAAM,CA4NlB;;CACJ;yBA/vBY,OAAO,8DAA8D,EAAE,UAAU;8BACjF,OAAO,0BAA0B,EAAE,eAAe;2BATpC,iBAAiB;0CAvBF,oDAAoD"}
|
|
@@ -36,9 +36,7 @@ import { shader_nss_preprocess } from "./shader_nss_preprocess.js";
|
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Neural Super Sampling — port of ARM's NSS reference design
|
|
40
|
-
* (`https://github.com/arm/neural-graphics-for-unreal`) onto the
|
|
41
|
-
* engine's FrameGraph.
|
|
39
|
+
* Neural Super Sampling — port of ARM's NSS reference design onto the engine's FrameGraph.
|
|
42
40
|
*
|
|
43
41
|
* Pipeline (per frame):
|
|
44
42
|
* 1. Preprocess — assemble a 12-channel tensor from
|
|
@@ -9,14 +9,13 @@
|
|
|
9
9
|
* ReLU; decoder is conv8..conv12 without bias; 6 parallel output
|
|
10
10
|
* heads each carry their own RESCALE + TABLE LUT.
|
|
11
11
|
*
|
|
12
|
-
* Head ordering
|
|
13
|
-
* QUANTIZED model (NSS.cpp:241-246):
|
|
12
|
+
* Head ordering for the quantized model:
|
|
14
13
|
* slot 0 = Feedback (FB) — passed back to next frame's preprocess
|
|
15
14
|
* slot 1 = ThetaAlpha — sigmoid temporal-blend params
|
|
16
|
-
* slot 2 =
|
|
17
|
-
* slot 3 =
|
|
18
|
-
* slot 4 =
|
|
19
|
-
* slot 5 =
|
|
15
|
+
* slot 2 = KPN column 3 — kernel column 3 (rightmost)
|
|
16
|
+
* slot 3 = KPN column 2
|
|
17
|
+
* slot 4 = KPN column 1
|
|
18
|
+
* slot 5 = KPN column 0 — kernel column 0 (leftmost)
|
|
20
19
|
*
|
|
21
20
|
* The KPN slot order is reversed because ARM packs the network outputs
|
|
22
21
|
* in CONCAT order while our postprocess reads them as columns 0..3.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NSS_NETWORK_SCHEMA.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.js"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"NSS_NETWORK_SCHEMA.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,oEAAoE;AACpE,6CACqE;AAErE;;;;GAIG;AACH,yCAA0C;AAE1C,kEAAkE;AAClE,mCAAoC;AAEpC,6DAA6D;AAC7D,qCAAsC;AAEtC,yCAAyC;AACzC,yCAA0C"}
|
|
@@ -9,14 +9,13 @@
|
|
|
9
9
|
* ReLU; decoder is conv8..conv12 without bias; 6 parallel output
|
|
10
10
|
* heads each carry their own RESCALE + TABLE LUT.
|
|
11
11
|
*
|
|
12
|
-
* Head ordering
|
|
13
|
-
* QUANTIZED model (NSS.cpp:241-246):
|
|
12
|
+
* Head ordering for the quantized model:
|
|
14
13
|
* slot 0 = Feedback (FB) — passed back to next frame's preprocess
|
|
15
14
|
* slot 1 = ThetaAlpha — sigmoid temporal-blend params
|
|
16
|
-
* slot 2 =
|
|
17
|
-
* slot 3 =
|
|
18
|
-
* slot 4 =
|
|
19
|
-
* slot 5 =
|
|
15
|
+
* slot 2 = KPN column 3 — kernel column 3 (rightmost)
|
|
16
|
+
* slot 3 = KPN column 2
|
|
17
|
+
* slot 4 = KPN column 1
|
|
18
|
+
* slot 5 = KPN column 0 — kernel column 0 (leftmost)
|
|
20
19
|
*
|
|
21
20
|
* The KPN slot order is reversed because ARM packs the network outputs
|
|
22
21
|
* in CONCAT order while our postprocess reads them as columns 0..3.
|
|
@@ -52,10 +51,10 @@ export const NSS_NETWORK_SCHEMA = Object.freeze({
|
|
|
52
51
|
// the slot index is what the postprocess reads back.
|
|
53
52
|
{ in: 16, out: 4, output_layer_offset: 0, kind: 'feedback' }, // 12 FB
|
|
54
53
|
{ in: 16, out: 4, output_layer_offset: 1, kind: 'theta_alpha' }, // 13 ThetaAlpha (sigmoid)
|
|
55
|
-
{ in: 16, out: 4, output_layer_offset: 2, kind: 'kpn_col_3' }, // 14
|
|
56
|
-
{ in: 16, out: 4, output_layer_offset: 3, kind: 'kpn_col_2' }, // 15
|
|
57
|
-
{ in: 16, out: 4, output_layer_offset: 4, kind: 'kpn_col_1' }, // 16
|
|
58
|
-
{ in: 16, out: 4, output_layer_offset: 5, kind: 'kpn_col_0' }, // 17
|
|
54
|
+
{ in: 16, out: 4, output_layer_offset: 2, kind: 'kpn_col_3' }, // 14 KPN column 3
|
|
55
|
+
{ in: 16, out: 4, output_layer_offset: 3, kind: 'kpn_col_2' }, // 15 KPN column 2
|
|
56
|
+
{ in: 16, out: 4, output_layer_offset: 4, kind: 'kpn_col_1' }, // 16 KPN column 1
|
|
57
|
+
{ in: 16, out: 4, output_layer_offset: 5, kind: 'kpn_col_0' }, // 17 KPN column 0
|
|
59
58
|
],
|
|
60
59
|
});
|
|
61
60
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_nss_extract_feedback.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_nss_extract_feedback.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js"],"names":[],"mappings":"AA2CA,wDAIG;8BA9C2B,+BAA+B"}
|
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
|
-
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
3
|
-
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
4
|
-
import { NSS_WORKGROUP_SIZE } from "./NSS_CONSTANTS.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Copies the feedback channel-group (z = 0 — head slot 0 in ARM's
|
|
8
|
-
* quantized model output ordering, see NSS_NETWORK_SCHEMA) of the
|
|
9
|
-
* network's 3D output tensor into a standalone 2D rgba16f texture, so
|
|
10
|
-
* the next frame's preprocess pass can sample it as a regular 2D
|
|
11
|
-
* texture (with bilinear filtering for the warp).
|
|
12
|
-
*
|
|
13
|
-
* Trivial pass — included as a separate shader rather than folded into
|
|
14
|
-
* postprocess because postprocess runs at output-res while feedback is
|
|
15
|
-
* needed at render-res.
|
|
16
|
-
*/
|
|
17
|
-
const resources = new ShaderResourceSetDescriptor();
|
|
18
|
-
resources.createGroup()
|
|
19
|
-
.addTexture("tNetworkOut", "float", "3d")
|
|
20
|
-
.addStorageTexture("tFeedback", "rgba16float", "2d", "write-only")
|
|
21
|
-
;
|
|
22
|
-
|
|
23
|
-
const body = CodeChunk.from(
|
|
24
|
-
//language=WGSL
|
|
25
|
-
`
|
|
26
|
-
@compute @workgroup_size(${NSS_WORKGROUP_SIZE}, ${NSS_WORKGROUP_SIZE}, 1)
|
|
27
|
-
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
28
|
-
let dim = textureDimensions(tFeedback);
|
|
29
|
-
|
|
30
|
-
if (any(gid.xy >= dim)) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let st = vec2<i32>(gid.xy);
|
|
35
|
-
|
|
36
|
-
// Slot 0 of the network output is the feedback tensor
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
1
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
3
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
4
|
+
import { NSS_WORKGROUP_SIZE } from "./NSS_CONSTANTS.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Copies the feedback channel-group (z = 0 — head slot 0 in ARM's
|
|
8
|
+
* quantized model output ordering, see NSS_NETWORK_SCHEMA) of the
|
|
9
|
+
* network's 3D output tensor into a standalone 2D rgba16f texture, so
|
|
10
|
+
* the next frame's preprocess pass can sample it as a regular 2D
|
|
11
|
+
* texture (with bilinear filtering for the warp).
|
|
12
|
+
*
|
|
13
|
+
* Trivial pass — included as a separate shader rather than folded into
|
|
14
|
+
* postprocess because postprocess runs at output-res while feedback is
|
|
15
|
+
* needed at render-res.
|
|
16
|
+
*/
|
|
17
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
18
|
+
resources.createGroup()
|
|
19
|
+
.addTexture("tNetworkOut", "float", "3d")
|
|
20
|
+
.addStorageTexture("tFeedback", "rgba16float", "2d", "write-only")
|
|
21
|
+
;
|
|
22
|
+
|
|
23
|
+
const body = CodeChunk.from(
|
|
24
|
+
//language=WGSL
|
|
25
|
+
`
|
|
26
|
+
@compute @workgroup_size(${NSS_WORKGROUP_SIZE}, ${NSS_WORKGROUP_SIZE}, 1)
|
|
27
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
28
|
+
let dim = textureDimensions(tFeedback);
|
|
29
|
+
|
|
30
|
+
if (any(gid.xy >= dim)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let st = vec2<i32>(gid.xy);
|
|
35
|
+
|
|
36
|
+
// Slot 0 of the network output is the feedback tensor.
|
|
37
|
+
let fb = textureLoad(tNetworkOut, vec3<i32>(st, 0), 0);
|
|
38
|
+
|
|
39
|
+
textureStore(tFeedback, st, fb);
|
|
40
|
+
}
|
|
41
|
+
`
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const shader_nss_extract_feedback = ComputeShader.from({
|
|
45
|
+
label: "NSS / extract feedback",
|
|
46
|
+
body,
|
|
47
|
+
resources,
|
|
48
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_nss_postprocess.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/shader_nss_postprocess.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_nss_postprocess.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/nss/shader_nss_postprocess.js"],"names":[],"mappings":"AAiSA,mDAIG;8BAnS2B,+BAA+B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
1
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
2
|
import { F16_MAX_DEFINITION } from "../../shader/chunk/math/F16_MAX_DEFINITION.js";
|
|
3
3
|
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
4
4
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
@@ -19,7 +19,7 @@ import { NSS_SETTINGS_STRUCT } from "./NSS_SETTINGS_STRUCT.js";
|
|
|
19
19
|
* - the warped history at output-res
|
|
20
20
|
* - the nearest-depth offset from preprocess (used to dilate velocity)
|
|
21
21
|
*
|
|
22
|
-
* Per-output-pixel logic mirrors ARM's reference
|
|
22
|
+
* Per-output-pixel logic mirrors ARM's reference:
|
|
23
23
|
* 1. Solve which render-res pixel feeds each of the 4x4 KPN taps.
|
|
24
24
|
* 2. Apply the KPN to those taps, normalising by the weight sum.
|
|
25
25
|
* 3. Warp the history (bilinear) using velocity dilated by the nearest
|
|
@@ -27,9 +27,6 @@ import { NSS_SETTINGS_STRUCT } from "./NSS_SETTINGS_STRUCT.js";
|
|
|
27
27
|
* 4. Blend the KPN colour with warped history using theta.
|
|
28
28
|
* 5. In tonemapped (Karis) space, accumulate the center tap with alpha.
|
|
29
29
|
* 6. Inverse tonemap, divide by EXPOSURE, write.
|
|
30
|
-
*
|
|
31
|
-
* @see ARM reference: UE5.5/Shaders/Private/NSSPostprocess.usf and
|
|
32
|
-
* NSSCommon.ush in github.com/arm/neural-graphics-for-unreal
|
|
33
30
|
*/
|
|
34
31
|
|
|
35
32
|
const resources = new ShaderResourceSetDescriptor();
|
|
@@ -53,9 +50,9 @@ resources.createGroup()
|
|
|
53
50
|
const body = CodeChunk.from(
|
|
54
51
|
//language=WGSL
|
|
55
52
|
`
|
|
56
|
-
const NSS_EXPOSURE: f32 = 7.38905609893; // e^2
|
|
53
|
+
const NSS_EXPOSURE: f32 = 7.38905609893; // e^2
|
|
57
54
|
|
|
58
|
-
// Karis tonemap (max-of-channels)
|
|
55
|
+
// Karis tonemap (max-of-channels).
|
|
59
56
|
// The guard is a FINITE clamp, not just a non-negative one: this target is rgba16float, so shading
|
|
60
57
|
// above its range stores as +Inf and rgb / (1.0 + m) is Inf/Inf = NaN, which goes straight into the
|
|
61
58
|
// next frame's history and stays there. NaN fails every comparison including with itself, which is
|
|
@@ -106,7 +103,7 @@ fn nss_sample_layer_bilinear(render_pos: vec2<f32>, render_res_max: vec2<i32>, l
|
|
|
106
103
|
|
|
107
104
|
// SolveInputLocation: figure out which render-res pixel maps to a given
|
|
108
105
|
// output-res pixel position, given upscale ratio and jitter. Direct port
|
|
109
|
-
// of ARM's helper
|
|
106
|
+
// of ARM's reference helper. Returns -1 when no render-res
|
|
110
107
|
// sample lands at this output position.
|
|
111
108
|
fn nss_solve_input_location(out_idx: i32, upscale: f32, jitter: f32) -> i32 {
|
|
112
109
|
let lower = f32(out_idx) / upscale - (-jitter + 0.5);
|
|
@@ -144,8 +141,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
144
141
|
let coef_st_clamped = clamp(coef_st, vec2<i32>(0, 0), render_res_max);
|
|
145
142
|
|
|
146
143
|
// ── KPN columns ──
|
|
147
|
-
// ARM's quantized model maps
|
|
148
|
-
// KPNFilterCol1 = 4, KPNFilterCol2 = 3, KPNFilterCol3 = 2 (NSS.cpp:243).
|
|
144
|
+
// ARM's quantized model maps KPN columns 0..3 to head slots 5, 4, 3, 2.
|
|
149
145
|
// Each column has 4 channels = the 4 row weights for that column.
|
|
150
146
|
// Bilinear at render_centre (matches ARM's ManualBilinear4) — without
|
|
151
147
|
// this, every 2x2 output block in 2x mode shares one set of weights and
|
|
@@ -155,7 +151,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
155
151
|
let col2 = nss_sample_layer_bilinear(render_centre, render_res_max, 3);
|
|
156
152
|
let col3 = nss_sample_layer_bilinear(render_centre, render_res_max, 2);
|
|
157
153
|
// Force tiny positive — ARM does this to dodge 0/0 in the
|
|
158
|
-
// weight-normalisation divide
|
|
154
|
+
// weight-normalisation divide.
|
|
159
155
|
let kpn_cols = array<vec4<f32>, 4>(
|
|
160
156
|
max(col0, vec4<f32>(1e-7)),
|
|
161
157
|
max(col1, vec4<f32>(1e-7)),
|
|
@@ -208,7 +204,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
208
204
|
let nearest_offset = vec2<i32>(round(nearest_packed * 2.0 - 1.0));
|
|
209
205
|
|
|
210
206
|
var velocity = textureLoad(tVelocity, coef_st_clamped + nearest_offset, 0).rg;
|
|
211
|
-
// Motion zero-clamp
|
|
207
|
+
// Motion zero-clamp. Sub-pixel velocity on
|
|
212
208
|
// near-static frames drifts prev_uv by fractions of a pixel each frame
|
|
213
209
|
// and bilinear-resamples the history at slightly different sub-pixel
|
|
214
210
|
// positions — visible as flicker even when nothing in the scene is
|
|
@@ -225,10 +221,10 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
225
221
|
let on_screen_f = select(0.0, 1.0, all(prev_uv >= vec2<f32>(0.0)) && all(prev_uv <= vec2<f32>(1.0)));
|
|
226
222
|
|
|
227
223
|
// ── ThetaAlpha (head slot 1) ──
|
|
228
|
-
// ARM's quantized model maps
|
|
229
|
-
//
|
|
224
|
+
// ARM's quantized model maps ThetaAlpha to head slot 1.
|
|
225
|
+
// Channel x = theta (history blend weight, [0, 1] from
|
|
230
226
|
// sigmoid LUT), channel y = alpha (raw [0, 1], remapped to
|
|
231
|
-
// [0.05, 0.4]
|
|
227
|
+
// [0.05, 0.4]).
|
|
232
228
|
// Bilinear at render_centre — same reasoning as the KPN cols above.
|
|
233
229
|
let ta = nss_sample_layer_bilinear(render_centre, render_res_max, 1);
|
|
234
230
|
let theta_network = saturate(ta.x);
|
|
@@ -286,7 +282,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
286
282
|
textureStore(tOutput, out_st, vec4<f32>(final_rgb, theta));
|
|
287
283
|
}
|
|
288
284
|
`, [
|
|
289
|
-
F16_MAX_DEFINITION,
|
|
285
|
+
F16_MAX_DEFINITION,
|
|
290
286
|
NSS_SETTINGS_STRUCT.declaration_chunk,
|
|
291
287
|
]
|
|
292
288
|
);
|