15
15
@group (1 ) @binding (0 ) var view_output : texture_storage_2d <rgba16float , read_write >;
16
16
@group (1 ) @binding (1 ) var <storage , read_write > light_tile_samples : array <LightSample >;
17
17
@group (1 ) @binding (2 ) var <storage , read_write > light_tile_resolved_samples : array <ResolvedLightSamplePacked >;
18
- @group (1 ) @binding (3 ) var < storage , read_write > di_reservoirs_a : array < Reservoir >;
19
- @group (1 ) @binding (4 ) var < storage , read_write > di_reservoirs_b : array < Reservoir >;
18
+ @group (1 ) @binding (3 ) var di_reservoirs_a : texture_storage_2d < rgba32uint , read_write >;
19
+ @group (1 ) @binding (4 ) var di_reservoirs_b : texture_storage_2d < rgba32uint , read_write >;
20
20
@group (1 ) @binding (7 ) var gbuffer : texture_2d <u32 >;
21
21
@group (1 ) @binding (8 ) var depth_buffer : texture_depth_2d ;
22
22
@group (1 ) @binding (9 ) var motion_vectors : texture_2d <f32 >;
@@ -42,7 +42,7 @@ fn initial_and_temporal(@builtin(workgroup_id) workgroup_id: vec3<u32>, @builtin
42
42
43
43
let depth = textureLoad (depth_buffer , global_id . xy, 0 );
44
44
if depth == 0.0 {
45
- di_reservoirs_b [ pixel_index ] = empty_reservoir ();
45
+ store_reservoir_b ( global_id . xy, empty_reservoir () );
46
46
return ;
47
47
}
48
48
let gpixel = textureLoad (gbuffer , global_id . xy, 0 );
@@ -55,7 +55,7 @@ fn initial_and_temporal(@builtin(workgroup_id) workgroup_id: vec3<u32>, @builtin
55
55
let temporal_reservoir = load_temporal_reservoir (global_id . xy, depth , world_position , world_normal );
56
56
let merge_result = merge_reservoirs (initial_reservoir , temporal_reservoir , world_position , world_normal , diffuse_brdf , & rng );
57
57
58
- di_reservoirs_b [ pixel_index ] = merge_result . merged_reservoir;
58
+ store_reservoir_b ( global_id . xy, merge_result . merged_reservoir) ;
59
59
}
60
60
61
61
@compute @workgroup_size (8 , 8 , 1 )
@@ -67,7 +67,7 @@ fn spatial_and_shade(@builtin(global_invocation_id) global_id: vec3<u32>) {
67
67
68
68
let depth = textureLoad (depth_buffer , global_id . xy, 0 );
69
69
if depth == 0.0 {
70
- di_reservoirs_a [ pixel_index ] = empty_reservoir ();
70
+ store_reservoir_a ( global_id . xy, empty_reservoir () );
71
71
textureStore (view_output , global_id . xy, vec4 (vec3 (0.0 ), 1.0 ));
72
72
return ;
73
73
}
@@ -78,12 +78,12 @@ fn spatial_and_shade(@builtin(global_invocation_id) global_id: vec3<u32>) {
78
78
let diffuse_brdf = base_color / PI ;
79
79
let emissive = rgb9e5_to_vec3_ (gpixel . g);
80
80
81
- let input_reservoir = di_reservoirs_b [ pixel_index ] ;
81
+ let input_reservoir = load_reservoir_b ( global_id . xy) ;
82
82
let spatial_reservoir = load_spatial_reservoir (global_id . xy, depth , world_position , world_normal , & rng );
83
83
let merge_result = merge_reservoirs (input_reservoir , spatial_reservoir , world_position , world_normal , diffuse_brdf , & rng );
84
84
let combined_reservoir = merge_result . merged_reservoir;
85
85
86
- di_reservoirs_a [ pixel_index ] = combined_reservoir ;
86
+ store_reservoir_a ( global_id . xy, combined_reservoir ) ;
87
87
88
88
var pixel_color = merge_result . selected_sample_radiance * combined_reservoir . unbiased_contribution_weight;
89
89
pixel_color *= view . exposure;
@@ -155,8 +155,7 @@ fn load_temporal_reservoir(pixel_id: vec2<u32>, depth: f32, world_position: vec3
155
155
return empty_reservoir ();
156
156
}
157
157
158
- let temporal_pixel_index = temporal_pixel_id . x + temporal_pixel_id . y * u32 (view . main_pass_viewport. z);
159
- var temporal_reservoir = di_reservoirs_a [temporal_pixel_index ];
158
+ var temporal_reservoir = load_reservoir_a (temporal_pixel_id );
160
159
161
160
// Check if the light selected in the previous frame no longer exists in the current frame (e.g. entity despawned)
162
161
let previous_light_id = temporal_reservoir . sample. light_id >> 16u ;
@@ -183,8 +182,7 @@ fn load_spatial_reservoir(pixel_id: vec2<u32>, depth: f32, world_position: vec3<
183
182
return empty_reservoir ();
184
183
}
185
184
186
- let spatial_pixel_index = spatial_pixel_id . x + spatial_pixel_id . y * u32 (view . main_pass_viewport. z);
187
- var spatial_reservoir = di_reservoirs_b [spatial_pixel_index ];
185
+ var spatial_reservoir = load_reservoir_b (spatial_pixel_id );
188
186
189
187
if reservoir_valid (spatial_reservoir ) {
190
188
let resolved_light_sample = resolve_light_sample (spatial_reservoir . sample, light_sources [spatial_reservoir . sample. light_id >> 16u ]);
@@ -234,7 +232,6 @@ fn depth_ndc_to_view_z(ndc_depth: f32) -> f32 {
234
232
#endif
235
233
}
236
234
237
- // Don't adjust the size of this struct without also adjusting DI_RESERVOIR_STRUCT_SIZE.
238
235
struct Reservoir {
239
236
sample : LightSample ,
240
237
confidence_weight : f32 ,
@@ -253,6 +250,32 @@ fn reservoir_valid(reservoir: Reservoir) -> bool {
253
250
return reservoir . sample. light_id != NULL_RESERVOIR_SAMPLE;
254
251
}
255
252
253
+ fn pack_reservoir (reservoir : Reservoir ) -> vec4 <u32 > {
254
+ let weights = bitcast <vec2 <u32 >> (vec2 <f32 >(reservoir . confidence_weight, reservoir . unbiased_contribution_weight));
255
+ return vec4 <u32 >(reservoir . sample. light_id, reservoir . sample. seed, weights );
256
+ }
257
+
258
+ fn store_reservoir_a (pixel : vec2 <u32 >, reservoir : Reservoir ) {
259
+ textureStore (di_reservoirs_a , pixel , pack_reservoir (reservoir ));
260
+ }
261
+
262
+ fn store_reservoir_b (pixel : vec2 <u32 >, reservoir : Reservoir ) {
263
+ textureStore (di_reservoirs_b , pixel , pack_reservoir (reservoir ));
264
+ }
265
+
266
+ fn unpack_reservoir (packed : vec4 <u32 >) -> Reservoir {
267
+ let weights = bitcast <vec2 <f32 >> (packed . zw);
268
+ return Reservoir (LightSample (packed . x, packed . y), weights . x, weights . y);
269
+ }
270
+
271
+ fn load_reservoir_a (pixel : vec2 <u32 >) -> Reservoir {
272
+ return unpack_reservoir (textureLoad (di_reservoirs_a , pixel ));
273
+ }
274
+
275
+ fn load_reservoir_b (pixel : vec2 <u32 >) -> Reservoir {
276
+ return unpack_reservoir (textureLoad (di_reservoirs_b , pixel ));
277
+ }
278
+
256
279
struct ReservoirMergeResult {
257
280
merged_reservoir : Reservoir ,
258
281
selected_sample_radiance : vec3 <f32 >,
0 commit comments