summaryrefslogtreecommitdiff
path: root/shaders/ui.frag.glsl
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-28 16:12:01 -0300
committerGabriel Schneider <[email protected]>2026-09-01 08:30:41 -0300
commit848ad99fa597387a85f75e752dc4c9e10f8c24f4 (patch)
tree623ee400f6bec5e2a823e5a590dc4760a3084771 /shaders/ui.frag.glsl
parentb3595e04e67708c3b060a15cbbbf2478d9e6241e (diff)
downloadpardes-848ad99fa597387a85f75e752dc4c9e10f8c24f4.tar.gz
pardes-848ad99fa597387a85f75e752dc4c9e10f8c24f4.zip
macos fix
Diffstat (limited to 'shaders/ui.frag.glsl')
-rw-r--r--shaders/ui.frag.glsl20
1 files changed, 15 insertions, 5 deletions
diff --git a/shaders/ui.frag.glsl b/shaders/ui.frag.glsl
index ddc1cde0..69cb63b9 100644
--- a/shaders/ui.frag.glsl
+++ b/shaders/ui.frag.glsl
@@ -1,7 +1,10 @@
#version 450
// Sample the glyph atlas (R = coverage 0..1) and mix the cell's bg up to its fg
-// by that coverage. Fully opaque: the swapchain is SDR, no blending needed.
+// by that coverage. Output is PREMULTIPLIED: an opaque cell is unchanged, and a
+// cell whose background is the see-through ground (config.gui_transparent, a
+// theme with no bg of its own) contributes only its ink, at the ink's own
+// coverage, so the compositor keeps the rest.
layout(set = 2, binding = 0) uniform sampler2D u_atlas;
@@ -26,13 +29,20 @@ float cellNoise(uint serial, uint col, uint row) {
void main() {
float a = texture(u_atlas, v_uv).r;
bool oldLayer = (v_effect.x & 0x80000000u) != 0u;
- uint effect = v_effect.x & 0x7fffffffu;
+ // 0 where the cell's background IS the ground and the ground is nothing.
+ // src/gui/gui.zig sets that bit; the two flags above it are why the effect
+ // id is masked with 0x3fffffff here and in ui.vert.glsl.
+ float bgA = (v_effect.x & 0x40000000u) != 0u ? 0.0 : 1.0;
+ uint effect = v_effect.x & 0x3fffffffu;
float progress = clamp(uintBitsToFloat(v_effect.y), 0.0, 1.0);
uint cellCol = v_effect.w & 0xffffu;
uint cellRow = v_effect.w >> 16;
float noise = cellNoise(v_effect.z, cellCol, cellRow);
- vec3 cell = mix(v_bg, v_fg, a);
+ // Ink over ground, both premultiplied: v_fg*a + (v_bg*bgA)*(1-a), which is
+ // mix() with the ground already premultiplied. At bgA = 1 that is exactly
+ // the mix(v_bg, v_fg, a) at alpha 1 this shader always wrote.
+ vec4 cell = vec4(mix(v_bg * bgA, v_fg, a), mix(bgA, 1.0, a));
// 3 = data dissolve. Changed cells retain the frozen old cell until their
// stable threshold, then atomically become the new cell. Exact endpoints
@@ -40,11 +50,11 @@ void main() {
if (effect == 3u) {
bool reveal = progress >= 1.0 || (progress > 0.0 && noise < progress);
if (oldLayer ? reveal : !reveal) discard;
- o_col = vec4(cell, 1.0);
+ o_col = cell;
return;
}
// FreeType's hinted grayscale bitmap is already the intended coverage.
// Preserve it exactly; weight-changing gamma hacks blur small stems.
- o_col = vec4(cell, 1.0);
+ o_col = cell;
}