TriDither.fxh (3475B)
1 //////////////////////////////////////////////////////////////////////////////// 2 // Triangular Dither // 3 // By The Sandvich Maker // 4 // Ported to ReShade by TreyM // 5 //////////////////////////////////////////////////////////////////////////////// 6 7 //////////////////////////////////////////////////////////////////////////////// 8 // // 9 // Usage: // 10 // Include this file in your shader like so: #include "TriDither.fx" // 11 // // 12 // For shader developers, use this syntax to do a function call in your // 13 // code as the last thing before exiting a given shader. You should dither // 14 // anytime data is going to be truncated to a lower bitdepth. Color input // 15 // must be a float3 value. // 16 // // 17 // input.rgb += TriDither(input.rgb, uv, bits); // 18 // // 19 // "bits" is an integer number that determines the bit depth // 20 // being dithered to. Usually 8, sometimes 10 // 21 // You can automate this by letting Reshade decide like so: // 22 // // 23 // input += TriDither(input, uv, BUFFER_COLOR_BIT_DEPTH); // 24 // // 25 // Manual setup looks something like this for an 8-bit backbuffer: // 26 // // 27 // input.rgb += TriDither(input.rgb, uv, 8); // 28 // // 29 //////////////////////////////////////////////////////////////////////////////// 30 31 uniform float DitherTimer < source = "timer"; >; 32 #define remap(v, a, b) (((v) - (a)) / ((b) - (a))) 33 34 float rand21(float2 uv) 35 { 36 float2 noise = frac(sin(dot(uv, float2(12.9898, 78.233) * 2.0)) * 43758.5453); 37 return (noise.x + noise.y) * 0.5; 38 } 39 40 float rand11(float x) 41 { 42 return frac(x * 0.024390243); 43 } 44 45 float permute(float x) 46 { 47 return ((34.0 * x + 1.0) * x) % 289.0; 48 } 49 50 float3 TriDither(float3 color, float2 uv, int bits) 51 { 52 float bitstep = exp2(bits) - 1.0; 53 float lsb = 1.0 / bitstep; 54 float lobit = 0.5 / bitstep; 55 float hibit = (bitstep - 0.5) / bitstep; 56 57 float3 m = float3(uv, rand21(uv + (DitherTimer * 0.001))) + 1.0; 58 float h = permute(permute(permute(m.x) + m.y) + m.z); 59 60 float3 noise1, noise2; 61 noise1.x = rand11(h); h = permute(h); 62 noise2.x = rand11(h); h = permute(h); 63 noise1.y = rand11(h); h = permute(h); 64 noise2.y = rand11(h); h = permute(h); 65 noise1.z = rand11(h); h = permute(h); 66 noise2.z = rand11(h); 67 68 float3 lo = saturate(remap(color.xyz, 0.0, lobit)); 69 float3 hi = saturate(remap(color.xyz, 1.0, hibit)); 70 float3 uni = noise1 - 0.5; 71 float3 tri = noise1 - noise2; 72 return lerp(uni, tri, min(lo, hi)) * lsb; 73 }