#pragma once inline const char* vertD = R"( #version 330 core layout (location = 0) in vec3 position; layout (location = 1) in vec4 color; uniform mat4 prMatrix; uniform mat4 camMatrix; out DATA { vec4 color_out; } vs_out; void main() { gl_Position = prMatrix * camMatrix * vec4(position, 1.0); vs_out.color_out = color; } )"; inline const char* fragD = R"( #version 330 core layout (location = 0) out vec4 color; in DATA { vec4 color_out; } fs_in; // 8x8 Bayer-Matrix (0..63), als Schwellwerttabelle float bayer8(vec2 fragXY) { int x = int(mod(fragXY.x, 8.0)); int y = int(mod(fragXY.y, 8.0)); int idx = x + y * 8; // Werte aus klassischer 8x8 Ordered-Dithering-Matrix int m[64] = int[64]( 0, 48, 12, 60, 3, 51, 15, 63, 32, 16, 44, 28, 35, 19, 47, 31, 8, 56, 4, 52, 11, 59, 7, 55, 40, 24, 36, 20, 43, 27, 39, 23, 2, 50, 14, 62, 1, 49, 13, 61, 34, 18, 46, 30, 33, 17, 45, 29, 10, 58, 6, 54, 9, 57, 5, 53, 42, 26, 38, 22, 41, 25, 37, 21 ); // +0.5, damit die Schwellen mittig zwischen Stufen liegen return (float(m[idx]) + 0.5) / 64.0; } void main() { vec4 c = fs_in.color_out; // alpha == 0 -> nichts rendern if (c.a <= 0.0) discard; // Für alpha < 1 verwenden wir Ordered Dithering if (c.a < 1.0) { float threshold = bayer8(gl_FragCoord.xy); // ist der Schwellenwert größer als alpha? -> Pixel auslassen if (threshold > c.a) discard; } // Wenn wir bis hier nicht verworfen haben, zeichnen wir den Pixel. // Typischerweise setzt man die ausgegebene Alpha dann auf 1.0, // weil die Transparenz bereits über das Dithering realisiert wurde. color = vec4(c.rgb, 1.0); } )";