@@ -14,11 +14,40 @@ fn skybox_light_srgb(dir: vec3f) -> vec3f {
14
14
return vec3f (0.85 ) + 0.15 * rgb ;
15
15
}
16
16
17
+ // -----------------------------------------------
18
+ // Adapted from
19
+ // https://www.shadertoy.com/view/llVGzG
20
+ // Originally presented in:
21
+ // Jimenez 2014, "Next Generation Post-Processing in Call of Duty"
22
+ //
23
+ // A good overview can be found in
24
+ // https://blog.demofox.org/2022/01/01/interleaved-gradient-noise-a-different-kind-of-low-discrepancy-sequence/
25
+
26
+ fn interleaved_gradient_noise (n : vec2f ) -> f32 {
27
+ let f = 0.06711056 * n . x + 0.00583715 * n . y;
28
+ return fract (52.9829189 * fract (f ));
29
+ }
30
+
31
+ fn dither_interleaved (rgb : vec3f , levels : f32 , frag_coord : vec4 <f32 >) -> vec3f {
32
+ var noise = interleaved_gradient_noise (frag_coord . xy);
33
+ noise = noise - 0.5 ;
34
+ return rgb + noise / (levels - 1.0 );
35
+ }
36
+
37
+ // -----------------------------------------------
38
+
17
39
@fragment
18
- fn main (in : FragmentInput ) -> @location (0 ) vec4f {
40
+ fn main (in : FragmentInput , @ builtin ( position ) frag_coord : vec4 < f32 > ) -> @location (0 ) vec4f {
19
41
let camera_dir = camera_ray_direction_from_screenuv (in . texcoord);
20
42
// Messing with direction a bit so it looks like in our old three-d based renderer (for easier comparison)
21
43
let rgb = skybox_dark_srgb (camera_dir ); // TODO(andreas): Allow switching to skybox_light
22
- return vec4f (linear_from_srgb (rgb ), 1.0 );
44
+
45
+ // Apply dithering in gamma space.
46
+ // TODO(andreas): Once we switch to HDR outputs, this can be removed.
47
+ // As of writing, the render target itself is (s)RGB8, so we need to dither while we still have maximum precision.
48
+ let rgb_dithered = dither_interleaved (rgb , 256.0 , frag_coord );
49
+
50
+ return vec4f (linear_from_srgb (rgb_dithered ), 1.0 );
51
+ //return vec4f(linear_from_srgb(rgb), 1.0); // Without dithering
23
52
//return vec4f(camera_dir, 1.0);
24
53
}
0 commit comments