diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index ee8415afd..0ed242f66 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -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 {