replace random noise with Bayer for dithering

This commit is contained in:
James Seibel
2024-10-02 18:08:53 -05:00
parent ec151d398e
commit b77828f984
@@ -2,13 +2,13 @@
in vec4 vertexColor;
in vec3 vertexWorldPos;
//in float vertexYPos;
in vec4 vPos;
in vec4 gl_FragCoord;
out vec4 fragColor;
// Fog/Clip Uniforms
// Fade/Clip Uniforms
uniform float uClipDistance = 0.0;
// Noise Uniforms
@@ -61,7 +61,26 @@ void applyNoise(inout vec4 fragColor, const in float viewDist)
fragColor.rgb = newCol;
}
float worldPosToNoise(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); }
/** returns a normalized value between 0.0 and 1.0 */
float bayerMatrix4x4(vec2 st)
{
int x = int(mod(st.x, 4.0));
int y = int(mod(st.y, 4.0));
// Flattened 4x4 Bayer matrix
float bayer4x4[16] = float[16](
0.0, 8.0, 2.0, 10.0,
12.0, 4.0, 14.0, 6.0,
3.0, 11.0, 1.0, 9.0,
15.0, 7.0, 13.0, 5.0
);
// Calculate the 1D index from the 2D coordinates
int index = y * 4 + x;
// Return the Bayer value normalized between 0.0 and 1.0
return bayer4x4[index] / 16.0;
}
@@ -75,20 +94,19 @@ void main()
{
// Dither out the fragment based on distance and noise.
// Dithering is used since it works for both opaque and transparent rendering
// noise increases as the distance increases
float worldNoise = worldPosToNoise(vertexWorldPos.xy);
// the fragCoord is used since it is stable and small so the dithering is cleaner
float worldNoise = bayerMatrix4x4(gl_FragCoord.xy);
// minor fudge factor to make sure all pixels fade out
// if not included 1 in 16 pixels would never fade away
worldNoise += 0.001;
float fadeStep = smoothstep(uClipDistance, uClipDistance * 1.5, viewDist);
if (fadeStep < worldNoise)
if (fadeStep <= worldNoise)
{
discard;
}
// this logic could be used for transparent rendering,
// however we don't currently have the logic needed to differentiate opaque/transparenet rendering
//float fadeStep = smoothstep(uClipDistance, uClipDistance * 2, viewDist);
//fragColor.a = min(fadeStep, fragColor.a);
}
else
{