From 9efb800d47262d3021d3c509468fe0ed23cec875 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Fri, 13 Feb 2026 21:03:01 +0900 Subject: [PATCH] alpha blending diagnostic shaders --- .../diagnose_premult_alpha_detector.frag | 28 +++++++++++++++++++ ...nose_premult_alpha_detector_highlight.frag | 20 +++++++++++++ ...ose_premult_alpha_simulate_wrong_mode.frag | 18 ++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/shaders/diagnose_premult_alpha_detector.frag create mode 100644 src/shaders/diagnose_premult_alpha_detector_highlight.frag create mode 100644 src/shaders/diagnose_premult_alpha_simulate_wrong_mode.frag diff --git a/src/shaders/diagnose_premult_alpha_detector.frag b/src/shaders/diagnose_premult_alpha_detector.frag new file mode 100644 index 000000000..5783bbde2 --- /dev/null +++ b/src/shaders/diagnose_premult_alpha_detector.frag @@ -0,0 +1,28 @@ + +in vec2 v_texCoords; +uniform sampler2D u_texture; +out vec4 fragColor; + +void main() { + vec4 c = texture(u_texture, v_texCoords); + + float maxRGB = max(c.r, max(c.g, c.b)); + + // Visualise mismatches: + // RED = looks like straight alpha + // BLUE = looks like premultiplied alpha + // GREEN = impossible / corrupted + + if (maxRGB > c.a + 0.001) { + // RGB > A → straight alpha + fragColor = vec4(1, 0, 0, 1); + } + else if (maxRGB < c.a - 0.001) { + // RGB < A → premultiplied alpha + fragColor = vec4(0, 0, 1, 1); + } + else { + // borderline / linear content + fragColor = vec4(0, 1, 0, 1); + } +} diff --git a/src/shaders/diagnose_premult_alpha_detector_highlight.frag b/src/shaders/diagnose_premult_alpha_detector_highlight.frag new file mode 100644 index 000000000..b002f01c3 --- /dev/null +++ b/src/shaders/diagnose_premult_alpha_detector_highlight.frag @@ -0,0 +1,20 @@ + +in vec2 v_texCoords; +uniform sampler2D u_texture; +out vec4 fragColor; + +// This version highlights pixels that will cause halos +// Bright red = guaranteed fringe artifact. + +void main() { + vec4 c = texture(u_texture, v_texCoords); + float maxRGB = max(c.r, max(c.g, c.b)); + + float diff = maxRGB - c.a; + + // amplify mismatch + float halo = clamp(abs(diff) * 10.0, 0.0, 1.0); + + fragColor = vec4(halo, 0, 0, 1); // red glow where halos will appear +} + diff --git a/src/shaders/diagnose_premult_alpha_simulate_wrong_mode.frag b/src/shaders/diagnose_premult_alpha_simulate_wrong_mode.frag new file mode 100644 index 000000000..0875689a3 --- /dev/null +++ b/src/shaders/diagnose_premult_alpha_simulate_wrong_mode.frag @@ -0,0 +1,18 @@ + +in vec2 v_texCoords; +uniform sampler2D u_texture; +out vec4 fragColor; + +// This shows how the sprite *would* look if alpha mode were wrong +// If you see garbage edges, your texture is premultiplied. + +void main() { + vec4 c = texture(u_texture, v_texCoords); + + // simulate wrong blending + vec3 wrong = c.rgb / max(c.a, 0.001); + + fragColor = vec4(wrong, 1.0); +} + +