@woosh/meep-engine 3.61.0 → 3.61.2
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/package.json +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts +46 -2
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/Decal.js +74 -5
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts +9 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts.map +1 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.js +37 -0
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +462 -447
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts +14 -0
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts.map +1 -1
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +53 -13
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts +6 -1
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts.map +1 -1
- package/src/engine/graphics3/decal/chunk_decal_record.js +28 -9
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts +2 -1
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_gpu_records.js +26 -5
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts +6 -0
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_material_samplers.js +13 -0
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +5 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +69 -28
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -0
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +4 -0
- package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -1
- package/src/generation/foliage/material/foliage_atlas_cutout.js +21 -5
- package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts +8 -0
- package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_cluster_representatives.js +178 -78
- package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_mesh_build_bark.js +178 -97
- package/src/generation/foliage/skeleton/ShootLightField.d.ts +1 -0
- package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootLightField.js +88 -17
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts +8 -4
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootWoodHash.js +216 -27
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +4 -0
- package/src/shade/playground/probe_clipmap_box/README.md +55 -0
- package/src/shade/playground/probe_clipmap_box/index.html +185 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts +8 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -0
- package/src/shade/playground/probe_clipmap_box/main.js +323 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +93 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -0
- package/src/shade/playground/probe_clipmap_box/scene.js +256 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +6 -1
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts +3 -1
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/graph_read_buffer.js +9 -6
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts +12 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.js +49 -24
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts +12 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.js +50 -19
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.js +6 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +5 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +7 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +6 -4
- 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 +10 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +12 -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 +14 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -22
- 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 +53 -65
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +9 -20
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +2 -2
- 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 +14 -19
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +1 -1
- 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 +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.js +13 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.js +4 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.js +4 -7
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +4 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +14 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +3 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +7 -15
- 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 +5 -1
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -7
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +26 -8
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +170 -142
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js +5 -8
- package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/chunk_restir_resolve.js +91 -94
- package/src/shade/renderer/restir/reservoir/chunk_rtxdi_stream_sample.js +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts +14 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js +36 -21
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js +64 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +15 -4
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +33 -7
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js +13 -18
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js +28 -30
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js +15 -16
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts +0 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js +15 -18
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts +40 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.js +75 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js +3 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts +28 -0
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.js +41 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.js +24 -0
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +3 -2
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +4 -0
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +2 -5
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +3 -20
- package/src/shade/renderer/water/chunk_water_gi.d.ts +1 -1
- package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
- package/src/shade/renderer/water/chunk_water_gi.js +6 -8
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +79 -35
- package/src/core/math/hash/squirrel3.d.ts +0 -17
- package/src/core/math/hash/squirrel3.d.ts.map +0 -1
- package/src/core/math/hash/squirrel3.js +0 -30
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts +0 -2
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.js +0 -6
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts +0 -12
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.js +0 -30
|
@@ -12,11 +12,28 @@ import { shader_autoexposure_read_histogram } from "./shader_autoexposure_read_h
|
|
|
12
12
|
* @typedef {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
const HISTOGRAM_DESCRIPTOR = BufferResourceDescriptor.empty(
|
|
16
|
+
AUTOEXPOSURE_WRITE_HISTOGRAM_STRUCT.aligned_size,
|
|
17
|
+
GPUBufferUsage.STORAGE,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const TARGET_LUMINANCE_DESCRIPTOR = BufferResourceDescriptor.from(
|
|
21
|
+
F32_CONTAINER_STRUCT.size,
|
|
22
|
+
GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM,
|
|
23
|
+
);
|
|
24
|
+
|
|
15
25
|
/**
|
|
16
|
-
*
|
|
26
|
+
* The exposure: the factor the tonemapper multiplies the scene's linear radiance by ahead of its curve, metered from
|
|
27
|
+
* the frame and adapted to it ({@link update}), or set by {@link exposure_compensation} alone ({@link unadapted}).
|
|
28
|
+
*
|
|
29
|
+
* The factor lives in one buffer for the manager's life, {@link multiplier}, which a frame's {@link update} or
|
|
30
|
+
* {@link unadapted} writes over. A pass recorded ahead of that write in the frame reads the factor the last frame was
|
|
31
|
+
* shown with: the exposure of the image on screen, Unreal Engine's `View.PreExposure`.
|
|
17
32
|
*/
|
|
18
33
|
export class GPUCameraExposureManager {
|
|
19
34
|
/**
|
|
35
|
+
* The adapted luminance: last frame's, which this frame's adaptation reads, and this frame's, which it writes.
|
|
36
|
+
* They swap every {@link update}.
|
|
20
37
|
*
|
|
21
38
|
* @type {GPUTypedBuffer[]}
|
|
22
39
|
*/
|
|
@@ -24,6 +41,12 @@ export class GPUCameraExposureManager {
|
|
|
24
41
|
|
|
25
42
|
#frame_index = 0;
|
|
26
43
|
|
|
44
|
+
/**
|
|
45
|
+
* {@link F32_CONTAINER_STRUCT}: the factor the last {@link update} or {@link unadapted} wrote.
|
|
46
|
+
* @type {GPUTypedBuffer}
|
|
47
|
+
*/
|
|
48
|
+
#multiplier;
|
|
49
|
+
|
|
27
50
|
/**
|
|
28
51
|
* How fast do we adapt to brighter environments?
|
|
29
52
|
* in f-stops per second.
|
|
@@ -54,6 +77,17 @@ export class GPUCameraExposureManager {
|
|
|
54
77
|
*/
|
|
55
78
|
exposure_compensation = 0.0;
|
|
56
79
|
|
|
80
|
+
// what each pass's execution reads, kept across frames: a frame records them and runs them before the next does
|
|
81
|
+
#unadapted_data = { output: -1 };
|
|
82
|
+
#unadapted_value = { value: 1.0 };
|
|
83
|
+
#build_data = { input_color: -1, output: -1 };
|
|
84
|
+
#parse_data = { input_histogram: -1, output: -1 };
|
|
85
|
+
#adapt_data = { goal: -1, previous: -1, adapted: -1, out_multiplier: -1 };
|
|
86
|
+
#adapt_settings = { speed_up: 0, speed_down: 0, time_delta: 0, exp_transition_distance: 0, compensation: 0 };
|
|
87
|
+
#build_bindings = { tInput: null, histogram: null };
|
|
88
|
+
#parse_bindings = { histogram: null, output: null };
|
|
89
|
+
#adapt_bindings = { goal: null, previous: null, settings: this.#adapt_settings, adapted: null, out_multiplier: null };
|
|
90
|
+
|
|
57
91
|
/**
|
|
58
92
|
*
|
|
59
93
|
* @param {GPUDevice} device
|
|
@@ -72,12 +106,36 @@ export class GPUCameraExposureManager {
|
|
|
72
106
|
});
|
|
73
107
|
}
|
|
74
108
|
|
|
109
|
+
// a factor of one until the first frame writes its own
|
|
110
|
+
this.#multiplier = GPUTypedBuffer.create({
|
|
111
|
+
label: 'exposure multiplier',
|
|
112
|
+
device,
|
|
113
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
114
|
+
type: F32_CONTAINER_STRUCT,
|
|
115
|
+
initial_value: {
|
|
116
|
+
value: 1.0
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
75
120
|
}
|
|
76
121
|
|
|
77
122
|
destroy() {
|
|
78
123
|
for (const buffer of this.#exposure_buffers) {
|
|
79
124
|
buffer.destroy();
|
|
80
125
|
}
|
|
126
|
+
|
|
127
|
+
this.#multiplier.destroy();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The factor, {@link F32_CONTAINER_STRUCT}, as the last {@link update} or {@link unadapted} wrote it. A frame
|
|
132
|
+
* imports it into its graph once, and hands the handle both to the passes that read it ahead of the exposure,
|
|
133
|
+
* which take the last frame's factor, and to {@link update} or {@link unadapted}, which write this frame's.
|
|
134
|
+
*
|
|
135
|
+
* @returns {GPUBuffer} usable as a uniform or read-only storage
|
|
136
|
+
*/
|
|
137
|
+
get multiplier() {
|
|
138
|
+
return this.#multiplier.buffer;
|
|
81
139
|
}
|
|
82
140
|
|
|
83
141
|
/**
|
|
@@ -93,62 +151,61 @@ export class GPUCameraExposureManager {
|
|
|
93
151
|
}
|
|
94
152
|
|
|
95
153
|
/**
|
|
154
|
+
* This frame's factor from {@link exposure_compensation} alone: 2^compensation.
|
|
96
155
|
*
|
|
97
156
|
* @param {Object} options
|
|
98
157
|
* @param {FrameGraph} options.graph
|
|
99
|
-
* @
|
|
158
|
+
* @param {number} options.multiplier the graph handle of {@link multiplier}, imported into `graph`
|
|
159
|
+
* @return {number} the handle of {@link multiplier} with this frame's factor written
|
|
100
160
|
*/
|
|
101
161
|
unadapted({
|
|
102
162
|
graph,
|
|
163
|
+
multiplier,
|
|
103
164
|
}) {
|
|
165
|
+
assert.defined(graph, 'graph');
|
|
166
|
+
assert.isNonNegativeInteger(multiplier, 'multiplier');
|
|
104
167
|
|
|
105
|
-
const data =
|
|
106
|
-
|
|
107
|
-
const pass = graph.add("unadapted", data,
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
*
|
|
111
|
-
* @param data
|
|
112
|
-
* @param {FramePassResources} resources
|
|
113
|
-
* @param {GraphicsExecutionContext} context
|
|
114
|
-
*/
|
|
115
|
-
(data, resources, context) => {
|
|
168
|
+
const data = this.#unadapted_data;
|
|
169
|
+
const pass = graph.add("unadapted", data, this.#execute_unadapted);
|
|
116
170
|
|
|
117
|
-
|
|
171
|
+
data.output = pass.write(multiplier);
|
|
118
172
|
|
|
173
|
+
return data.output;
|
|
174
|
+
}
|
|
119
175
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
data.output = pass.create("final", BufferResourceDescriptor.from(
|
|
134
|
-
F32_CONTAINER_STRUCT.size,
|
|
135
|
-
GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
136
|
-
));
|
|
176
|
+
/**
|
|
177
|
+
* @param data
|
|
178
|
+
* @param {FramePassResources} resources
|
|
179
|
+
* @param {GraphicsExecutionContext} context
|
|
180
|
+
*/
|
|
181
|
+
#execute_unadapted = (data, resources, context) => {
|
|
182
|
+
/**
|
|
183
|
+
* @type {ShadeGPUCommandContext}
|
|
184
|
+
*/
|
|
185
|
+
const encoder = context.encoder;
|
|
137
186
|
|
|
138
|
-
|
|
187
|
+
// compensation is in f-stops: each stop doubles/halves brightness
|
|
188
|
+
this.#unadapted_value.value = Math.pow(2, this.exposure_compensation);
|
|
139
189
|
|
|
190
|
+
// in the command stream, so a pass recorded ahead of this one still reads the last frame's factor
|
|
191
|
+
encoder.writeValueBuffer(resources.get(data.output), 0, F32_CONTAINER_STRUCT, this.#unadapted_value);
|
|
140
192
|
}
|
|
141
193
|
|
|
142
194
|
/**
|
|
195
|
+
* This frame's factor metered from `input_color`: the luminance adapted toward the frame's, from the last
|
|
196
|
+
* frame's, by the adaptation speeds; its factor is middle grey over it, times 2^{@link exposure_compensation}.
|
|
143
197
|
*
|
|
144
198
|
* @param {Object} options
|
|
145
199
|
* @param {FrameGraph} options.graph
|
|
146
200
|
* @param {number} options.input_color
|
|
201
|
+
* @param {number} options.multiplier the graph handle of {@link multiplier}, imported into `graph`
|
|
147
202
|
* @param {number} [options.time_delta_seconds]
|
|
203
|
+
* @return {number} the handle of {@link multiplier} with this frame's factor written
|
|
148
204
|
*/
|
|
149
205
|
update({
|
|
150
206
|
input_color,
|
|
151
207
|
graph,
|
|
208
|
+
multiplier,
|
|
152
209
|
time_delta_seconds = 0.01666,
|
|
153
210
|
}) {
|
|
154
211
|
|
|
@@ -160,142 +217,113 @@ export class GPUCameraExposureManager {
|
|
|
160
217
|
this used to be given, is Karis-averaged for precisely that purpose.
|
|
161
218
|
*/
|
|
162
219
|
|
|
220
|
+
assert.defined(graph, 'graph');
|
|
221
|
+
assert.isNonNegativeInteger(multiplier, 'multiplier');
|
|
163
222
|
assert.isNumber(time_delta_seconds, 'time_delta_seconds');
|
|
164
223
|
assert.greaterThanOrEqual(time_delta_seconds, 0, 'time_delta_seconds');
|
|
165
224
|
|
|
166
225
|
this.#frame_index++;
|
|
167
226
|
|
|
168
|
-
const build_data =
|
|
227
|
+
const build_data = this.#build_data;
|
|
228
|
+
const build_pass = graph.add("build histogram", build_data, this.#execute_build_histogram);
|
|
169
229
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
* @param data
|
|
173
|
-
* @param {FramePassResources} resources
|
|
174
|
-
* @param {GraphicsExecutionContext} context
|
|
175
|
-
*/
|
|
176
|
-
function build_histogram(data, resources, context) {
|
|
177
|
-
const input_color = resources.get(data.input_color);
|
|
178
|
-
const output = resources.get(data.output);
|
|
230
|
+
build_data.input_color = build_pass.read(input_color);
|
|
231
|
+
build_data.output = build_pass.create("histogram", HISTOGRAM_DESCRIPTOR);
|
|
179
232
|
|
|
180
|
-
|
|
181
|
-
|
|
233
|
+
const parse_data = this.#parse_data;
|
|
234
|
+
const parse_pass = graph.add("parse histogram", parse_data, this.#execute_parse_histogram);
|
|
182
235
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
236
|
+
parse_data.input_histogram = parse_pass.read(build_data.output);
|
|
237
|
+
parse_data.output = parse_pass.create("target luminance", TARGET_LUMINANCE_DESCRIPTOR);
|
|
187
238
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
group_count_x: gx,
|
|
191
|
-
group_count_y: gy,
|
|
192
|
-
bindings: {
|
|
193
|
-
tInput: input_color.obtainView(),
|
|
194
|
-
histogram: output,
|
|
195
|
-
},
|
|
196
|
-
});
|
|
239
|
+
const exposure_buffer_previous = this.#exposure_buffers[this.#frame_index % 2];
|
|
240
|
+
const exposure_buffer_current = this.#exposure_buffers[(this.#frame_index + 1) % 2];
|
|
197
241
|
|
|
198
|
-
|
|
242
|
+
// the frame's step; the rest of the settings are read as the pass runs
|
|
243
|
+
this.#adapt_settings.time_delta = time_delta_seconds;
|
|
199
244
|
|
|
200
|
-
const
|
|
245
|
+
const adapt_data = this.#adapt_data;
|
|
246
|
+
const adapt_pass = graph.add("adaptation", adapt_data, this.#execute_adapt);
|
|
201
247
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
248
|
+
adapt_data.goal = adapt_pass.read(parse_data.output);
|
|
249
|
+
adapt_data.previous = adapt_pass.read(graph_import_buffer(graph, exposure_buffer_previous.buffer, "previous adapted luminance"));
|
|
250
|
+
adapt_data.adapted = adapt_pass.write(graph_import_buffer(graph, exposure_buffer_current.buffer, "adapted luminance"));
|
|
251
|
+
adapt_data.out_multiplier = adapt_pass.write(multiplier);
|
|
252
|
+
|
|
253
|
+
return adapt_data.out_multiplier;
|
|
254
|
+
}
|
|
207
255
|
|
|
208
|
-
|
|
256
|
+
/**
|
|
257
|
+
* @param data
|
|
258
|
+
* @param {FramePassResources} resources
|
|
259
|
+
* @param {GraphicsExecutionContext} context
|
|
260
|
+
*/
|
|
261
|
+
#execute_build_histogram = (data, resources, context) => {
|
|
262
|
+
const input_color = resources.get(data.input_color);
|
|
263
|
+
const output = resources.get(data.output);
|
|
209
264
|
|
|
210
|
-
const
|
|
265
|
+
const gx = Math.ceil(input_color.width / 16);
|
|
266
|
+
const gy = Math.ceil(input_color.height / 16);
|
|
211
267
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
* @param {FramePassResources} resources
|
|
216
|
-
* @param {GraphicsExecutionContext} context
|
|
217
|
-
*/
|
|
218
|
-
function parse_histogram(data, resources, context) {
|
|
219
|
-
const input_histogram = resources.get(data.input_histogram);
|
|
220
|
-
const output = resources.get(data.output);
|
|
221
|
-
|
|
222
|
-
shader_autoexposure_read_histogram.dispatch({
|
|
223
|
-
encoder: context.encoder,
|
|
224
|
-
bindings: {
|
|
225
|
-
histogram: input_histogram,
|
|
226
|
-
output: output,
|
|
227
|
-
},
|
|
228
|
-
});
|
|
268
|
+
if (gx <= 0 || gy <= 0) {
|
|
269
|
+
// nothing to dispatch
|
|
270
|
+
return;
|
|
229
271
|
}
|
|
230
272
|
|
|
231
|
-
|
|
273
|
+
const bindings = this.#build_bindings;
|
|
232
274
|
|
|
233
|
-
|
|
234
|
-
|
|
275
|
+
bindings.tInput = input_color.obtainView();
|
|
276
|
+
bindings.histogram = output;
|
|
235
277
|
|
|
236
|
-
|
|
237
|
-
|
|
278
|
+
shader_autoexposure_build_histogram.dispatch({
|
|
279
|
+
encoder: context.encoder,
|
|
280
|
+
group_count_x: gx,
|
|
281
|
+
group_count_y: gy,
|
|
282
|
+
bindings,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
238
285
|
|
|
239
|
-
|
|
286
|
+
/**
|
|
287
|
+
* @param data
|
|
288
|
+
* @param {FramePassResources} resources
|
|
289
|
+
* @param {GraphicsExecutionContext} context
|
|
290
|
+
*/
|
|
291
|
+
#execute_parse_histogram = (data, resources, context) => {
|
|
292
|
+
const bindings = this.#parse_bindings;
|
|
240
293
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
F32_CONTAINER_STRUCT.size,
|
|
244
|
-
GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM,
|
|
245
|
-
));
|
|
294
|
+
bindings.histogram = resources.get(data.input_histogram);
|
|
295
|
+
bindings.output = resources.get(data.output);
|
|
246
296
|
|
|
297
|
+
shader_autoexposure_read_histogram.dispatch({
|
|
298
|
+
encoder: context.encoder,
|
|
299
|
+
bindings,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
247
302
|
|
|
248
|
-
|
|
303
|
+
/**
|
|
304
|
+
* @param data
|
|
305
|
+
* @param {FramePassResources} resources
|
|
306
|
+
* @param {GraphicsExecutionContext} context
|
|
307
|
+
*/
|
|
308
|
+
#execute_adapt = (data, resources, context) => {
|
|
309
|
+
const settings = this.#adapt_settings;
|
|
249
310
|
|
|
250
|
-
|
|
311
|
+
settings.speed_up = this.adaptation_speed_up;
|
|
312
|
+
settings.speed_down = this.adaptation_speed_down;
|
|
313
|
+
settings.exp_transition_distance = this.exp_transition_distance;
|
|
314
|
+
settings.compensation = this.exposure_compensation;
|
|
251
315
|
|
|
252
|
-
|
|
253
|
-
*
|
|
254
|
-
* @param data
|
|
255
|
-
* @param {FramePassResources} resources
|
|
256
|
-
* @param {GraphicsExecutionContext} context
|
|
257
|
-
*/
|
|
258
|
-
const adapt = (data, resources, context) => {
|
|
259
|
-
|
|
260
|
-
const encoder = context.encoder;
|
|
261
|
-
|
|
262
|
-
const settings = {
|
|
263
|
-
speed_up: this.adaptation_speed_up,
|
|
264
|
-
speed_down: this.adaptation_speed_down,
|
|
265
|
-
time_delta: time_delta_seconds,
|
|
266
|
-
exp_transition_distance: this.exp_transition_distance,
|
|
267
|
-
compensation: this.exposure_compensation,
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const goal = resources.get(data.goal);
|
|
272
|
-
const previous = resources.get(data.previous);
|
|
273
|
-
const adapted = resources.get(data.adapted);
|
|
274
|
-
const out_multiplier = resources.get(data.out_multiplier);
|
|
275
|
-
|
|
276
|
-
shader_autoexposure_adapt.dispatch({
|
|
277
|
-
encoder,
|
|
278
|
-
bindings: {
|
|
279
|
-
goal,
|
|
280
|
-
previous,
|
|
281
|
-
settings,
|
|
282
|
-
adapted,
|
|
283
|
-
out_multiplier,
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
}
|
|
316
|
+
const bindings = this.#adapt_bindings;
|
|
287
317
|
|
|
288
|
-
|
|
318
|
+
bindings.goal = resources.get(data.goal);
|
|
319
|
+
bindings.previous = resources.get(data.previous);
|
|
320
|
+
bindings.adapted = resources.get(data.adapted);
|
|
321
|
+
bindings.out_multiplier = resources.get(data.out_multiplier);
|
|
289
322
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
F32_CONTAINER_STRUCT.size,
|
|
295
|
-
GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM,
|
|
296
|
-
));
|
|
297
|
-
|
|
298
|
-
return adapt_data.out_multiplier;
|
|
323
|
+
shader_autoexposure_adapt.dispatch({
|
|
324
|
+
encoder: context.encoder,
|
|
325
|
+
bindings,
|
|
326
|
+
});
|
|
299
327
|
}
|
|
300
328
|
|
|
301
|
-
}
|
|
329
|
+
}
|
package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* {@link chunk_forward_sample_indirect} from the probe clipmap (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §9.5): one
|
|
3
3
|
* pick at the fragment by its shading normal and view, jittered by a hash of its position and normal that
|
|
4
|
-
* changes every frame, as Brick4's is, for both lobes. The irradiance is
|
|
4
|
+
* changes every frame, as Brick4's is, for both lobes. The irradiance is the picked SH resolved at the normal,
|
|
5
5
|
* the specular the pick's radiance at the fragment's roughness (§9.3); where no probe weighs anything, both are
|
|
6
6
|
* the environment's. Reads the probes' group, `view` and `tEnvironment`.
|
|
7
7
|
*
|
package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_forward_sample_indirect_probe_clipmap.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_forward_sample_indirect_probe_clipmap.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js"],"names":[],"mappings":"AAYA;;;;;;;;GAQG;AACH,0DAFU,SAAS,CAkCjB;0BA3CwB,oCAAoC"}
|
|
@@ -4,17 +4,16 @@ import { chunk_probe_clipmap_pick } from "../../global_illumination/probe_clipma
|
|
|
4
4
|
import {
|
|
5
5
|
chunk_probe_clipmap_sample_radiance
|
|
6
6
|
} from "../../global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js";
|
|
7
|
-
import { PI_DECLARATION } from "../../shader/chunk/math/PI_DECLARATION.js";
|
|
8
7
|
import { chunk_jitter_from_vectors } from "../../shader/chunk/random/chunk_jitter_from_vectors.js";
|
|
9
8
|
import {
|
|
10
|
-
|
|
11
|
-
} from "../../shader/chunk/spherical_harmonics/
|
|
9
|
+
chunk_sh3_color_get_irradiance_at
|
|
10
|
+
} from "../../shader/chunk/spherical_harmonics/chunk_sh3_color_get_irradiance_at.js";
|
|
12
11
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* {@link chunk_forward_sample_indirect} from the probe clipmap (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §9.5): one
|
|
16
15
|
* pick at the fragment by its shading normal and view, jittered by a hash of its position and normal that
|
|
17
|
-
* changes every frame, as Brick4's is, for both lobes. The irradiance is
|
|
16
|
+
* changes every frame, as Brick4's is, for both lobes. The irradiance is the picked SH resolved at the normal,
|
|
18
17
|
* the specular the pick's radiance at the fragment's roughness (§9.3); where no probe weighs anything, both are
|
|
19
18
|
* the environment's. Reads the probes' group, `view` and `tEnvironment`.
|
|
20
19
|
*
|
|
@@ -37,8 +36,7 @@ fn forward_sample_indirect(
|
|
|
37
36
|
let probes = probe_clipmap_sh_of(pick);
|
|
38
37
|
|
|
39
38
|
if (probes.found) {
|
|
40
|
-
|
|
41
|
-
*irradiance = PI * resolve_irradiance_sh_to_diffuse(probes.sh.Y, probes.sh.CoCg, normal);
|
|
39
|
+
*irradiance = sh3_color_get_irradiance_at(normal, probes.sh);
|
|
42
40
|
*radiance = probe_clipmap_radiance_of(pick, position_ws, normal, view_direction, roughness).radiance;
|
|
43
41
|
} else {
|
|
44
42
|
*irradiance = get_ibl_irradiance(normal);
|
|
@@ -50,8 +48,7 @@ fn forward_sample_indirect(
|
|
|
50
48
|
chunk_get_ibl_irradiance,
|
|
51
49
|
chunk_probe_clipmap_pick,
|
|
52
50
|
chunk_probe_clipmap_sample_radiance,
|
|
53
|
-
|
|
51
|
+
chunk_sh3_color_get_irradiance_at,
|
|
54
52
|
chunk_jitter_from_vectors,
|
|
55
|
-
PI_DECLARATION,
|
|
56
53
|
]
|
|
57
54
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_restir_resolve.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/restir/di/chunk_restir_resolve.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,mCAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_restir_resolve.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/restir/di/chunk_restir_resolve.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,mCAFU,SAAS,CA4DjB;0BApFwB,oCAAoC"}
|
|
@@ -1,94 +1,91 @@
|
|
|
1
|
-
import { REFLECTED_LIGHT_STRUCT } from "../../shader/chunk/light/REFLECTED_LIGHT_STRUCT.js";
|
|
2
|
-
import { chunk_re_direct_multiscatter } from "../../shader/chunk/material/chunk_re_direct_multiscatter.js";
|
|
3
|
-
import { chunk_re_direct_physical } from "../../shader/chunk/material/chunk_re_direct_physical.js";
|
|
4
|
-
import { GEOMETRIC_SHADING_INFO_STRUCT } from "../../shader/chunk/material/GEOMETRIC_SHADING_INFO_STRUCT.js";
|
|
5
|
-
import { MATERIAL_SHADING_INFO_STRUCT } from "../../shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js";
|
|
6
|
-
import { RTXDI_Reservoir } from "../reservoir/RTXDI_Reservoir.js";
|
|
7
|
-
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
8
|
-
import { chunk_restir_get_light_info } from "./chunk_restir_get_light_info.js";
|
|
9
|
-
import { chunk_restir_light_ref } from "./chunk_restir_light_ref.js";
|
|
10
|
-
import { chunk_restir_sample_light_record } from "./chunk_restir_sample_light_record.js";
|
|
11
|
-
import { chunk_restir_trace_visibility } from "./chunk_restir_trace_visibility.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Resolve a finalized reservoir to outgoing radiance for the selected light:
|
|
15
|
-
*
|
|
16
|
-
* radiance = BRDF·Le·G (full RGB, unshadowed) · W · V
|
|
17
|
-
*
|
|
18
|
-
* where W == reservoir.weightSum after FinalizeResampling (it already folds in
|
|
19
|
-
* 1/p_hat and 1/M) and V is the traced visibility (the RTXDI `f_rgb · weightSum`
|
|
20
|
-
* identity). p_hat is the luminance of the single-scattering BRDF·Le·G; this
|
|
21
|
-
* BRDF also carries `re_direct_multiscatter`'s per-pixel scale of the specular,
|
|
22
|
-
* so f / p_hat is no longer 1 but stays within [1, that scale]. The estimate is
|
|
23
|
-
* unbiased either way: f and p_hat are positive on the same lights.
|
|
24
|
-
*
|
|
25
|
-
* Visibility is a single opaque shadow ray toward the survivor's sampled emitter
|
|
26
|
-
* point — matching the brute-force NEE reference (`ray_sample_light`), which also
|
|
27
|
-
* uses `ray_query_occluded`. Requires the RTX resource group to be bound.
|
|
28
|
-
*
|
|
29
|
-
* Emissive is intentionally excluded; the deferred pass adds it once.
|
|
30
|
-
*
|
|
31
|
-
* @type {CodeChunk}
|
|
32
|
-
*/
|
|
33
|
-
export const chunk_restir_resolve = CodeChunk.from(
|
|
34
|
-
//language=WGSL
|
|
35
|
-
`
|
|
36
|
-
fn restir_resolve(
|
|
37
|
-
i_coord: vec2<u32>,
|
|
38
|
-
reservoir: ${RTXDI_Reservoir.wgsl_ref},
|
|
39
|
-
geometry: ${GEOMETRIC_SHADING_INFO_STRUCT.wgsl_ref},
|
|
40
|
-
material: ${MATERIAL_SHADING_INFO_STRUCT.wgsl_ref},
|
|
41
|
-
use_screen_space_shadow: u32
|
|
42
|
-
) -> vec3<f32> {
|
|
43
|
-
if (!restir_light_ref_is_valid(reservoir.lightData) || reservoir.weightSum <= 0.0) {
|
|
44
|
-
return vec3<f32>(0.0);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let light_type = restir_light_ref_type(reservoir.lightData);
|
|
48
|
-
let light_index = restir_light_ref_index(reservoir.lightData);
|
|
49
|
-
|
|
50
|
-
// Full RGB unshadowed contribution via the representative-point incident light.
|
|
51
|
-
let incident = restir_get_light_info(light_type, light_index, geometry.position);
|
|
52
|
-
var reflected: ${REFLECTED_LIGHT_STRUCT.wgsl_ref};
|
|
53
|
-
re_direct_physical(incident, geometry, material, &reflected);
|
|
54
|
-
re_direct_multiscatter(geometry, material, &reflected);
|
|
55
|
-
let radiance = reflected.diffuse + reflected.specular;
|
|
56
|
-
|
|
57
|
-
if (all(radiance <= vec3<f32>(0.0))) {
|
|
58
|
-
return vec3<f32>(0.0);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Decode the stored 16-bit-fixed-point area-light sample point.
|
|
62
|
-
let uv =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
chunk_restir_trace_visibility,
|
|
93
|
-
]
|
|
94
|
-
);
|
|
1
|
+
import { REFLECTED_LIGHT_STRUCT } from "../../shader/chunk/light/REFLECTED_LIGHT_STRUCT.js";
|
|
2
|
+
import { chunk_re_direct_multiscatter } from "../../shader/chunk/material/chunk_re_direct_multiscatter.js";
|
|
3
|
+
import { chunk_re_direct_physical } from "../../shader/chunk/material/chunk_re_direct_physical.js";
|
|
4
|
+
import { GEOMETRIC_SHADING_INFO_STRUCT } from "../../shader/chunk/material/GEOMETRIC_SHADING_INFO_STRUCT.js";
|
|
5
|
+
import { MATERIAL_SHADING_INFO_STRUCT } from "../../shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js";
|
|
6
|
+
import { RTXDI_Reservoir } from "../reservoir/RTXDI_Reservoir.js";
|
|
7
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
8
|
+
import { chunk_restir_get_light_info } from "./chunk_restir_get_light_info.js";
|
|
9
|
+
import { chunk_restir_light_ref } from "./chunk_restir_light_ref.js";
|
|
10
|
+
import { chunk_restir_sample_light_record } from "./chunk_restir_sample_light_record.js";
|
|
11
|
+
import { chunk_restir_trace_visibility } from "./chunk_restir_trace_visibility.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a finalized reservoir to outgoing radiance for the selected light:
|
|
15
|
+
*
|
|
16
|
+
* radiance = BRDF·Le·G (full RGB, unshadowed) · W · V
|
|
17
|
+
*
|
|
18
|
+
* where W == reservoir.weightSum after FinalizeResampling (it already folds in
|
|
19
|
+
* 1/p_hat and 1/M) and V is the traced visibility (the RTXDI `f_rgb · weightSum`
|
|
20
|
+
* identity). p_hat is the luminance of the single-scattering BRDF·Le·G; this
|
|
21
|
+
* BRDF also carries `re_direct_multiscatter`'s per-pixel scale of the specular,
|
|
22
|
+
* so f / p_hat is no longer 1 but stays within [1, that scale]. The estimate is
|
|
23
|
+
* unbiased either way: f and p_hat are positive on the same lights.
|
|
24
|
+
*
|
|
25
|
+
* Visibility is a single opaque shadow ray toward the survivor's sampled emitter
|
|
26
|
+
* point — matching the brute-force NEE reference (`ray_sample_light`), which also
|
|
27
|
+
* uses `ray_query_occluded`. Requires the RTX resource group to be bound.
|
|
28
|
+
*
|
|
29
|
+
* Emissive is intentionally excluded; the deferred pass adds it once.
|
|
30
|
+
*
|
|
31
|
+
* @type {CodeChunk}
|
|
32
|
+
*/
|
|
33
|
+
export const chunk_restir_resolve = CodeChunk.from(
|
|
34
|
+
//language=WGSL
|
|
35
|
+
`
|
|
36
|
+
fn restir_resolve(
|
|
37
|
+
i_coord: vec2<u32>,
|
|
38
|
+
reservoir: ${RTXDI_Reservoir.wgsl_ref},
|
|
39
|
+
geometry: ${GEOMETRIC_SHADING_INFO_STRUCT.wgsl_ref},
|
|
40
|
+
material: ${MATERIAL_SHADING_INFO_STRUCT.wgsl_ref},
|
|
41
|
+
use_screen_space_shadow: u32
|
|
42
|
+
) -> vec3<f32> {
|
|
43
|
+
if (!restir_light_ref_is_valid(reservoir.lightData) || reservoir.weightSum <= 0.0) {
|
|
44
|
+
return vec3<f32>(0.0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let light_type = restir_light_ref_type(reservoir.lightData);
|
|
48
|
+
let light_index = restir_light_ref_index(reservoir.lightData);
|
|
49
|
+
|
|
50
|
+
// Full RGB unshadowed contribution via the representative-point incident light.
|
|
51
|
+
let incident = restir_get_light_info(light_type, light_index, geometry.position);
|
|
52
|
+
var reflected: ${REFLECTED_LIGHT_STRUCT.wgsl_ref};
|
|
53
|
+
re_direct_physical(incident, geometry, material, &reflected);
|
|
54
|
+
re_direct_multiscatter(geometry, material, &reflected);
|
|
55
|
+
let radiance = reflected.diffuse + reflected.specular;
|
|
56
|
+
|
|
57
|
+
if (all(radiance <= vec3<f32>(0.0))) {
|
|
58
|
+
return vec3<f32>(0.0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Decode the stored 16-bit-fixed-point area-light sample point.
|
|
62
|
+
let uv = unpack2x16unorm(reservoir.uvData);
|
|
63
|
+
let record = restir_sample_light_record(light_type, light_index, geometry.position, uv);
|
|
64
|
+
|
|
65
|
+
var visibility = 1.0;
|
|
66
|
+
if (record.distance > 0.0) {
|
|
67
|
+
visibility = restir_trace_visibility(
|
|
68
|
+
i_coord,
|
|
69
|
+
geometry.position,
|
|
70
|
+
geometry.geometric_normal,
|
|
71
|
+
record.direction,
|
|
72
|
+
record.distance,
|
|
73
|
+
use_screen_space_shadow != 0u,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return radiance * reservoir.weightSum * visibility;
|
|
78
|
+
}
|
|
79
|
+
`, [
|
|
80
|
+
RTXDI_Reservoir.declaration_chunk,
|
|
81
|
+
REFLECTED_LIGHT_STRUCT.declaration_chunk,
|
|
82
|
+
GEOMETRIC_SHADING_INFO_STRUCT.declaration_chunk,
|
|
83
|
+
MATERIAL_SHADING_INFO_STRUCT.declaration_chunk,
|
|
84
|
+
chunk_re_direct_physical,
|
|
85
|
+
chunk_re_direct_multiscatter,
|
|
86
|
+
chunk_restir_get_light_info,
|
|
87
|
+
chunk_restir_light_ref,
|
|
88
|
+
chunk_restir_sample_light_record,
|
|
89
|
+
chunk_restir_trace_visibility,
|
|
90
|
+
]
|
|
91
|
+
);
|