summaryrefslogtreecommitdiff
path: root/shaders/prebuilt
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/prebuilt
parentb3595e04e67708c3b060a15cbbbf2478d9e6241e (diff)
downloadpardes-848ad99fa597387a85f75e752dc4c9e10f8c24f4.tar.gz
pardes-848ad99fa597387a85f75e752dc4c9e10f8c24f4.zip
macos fix
Diffstat (limited to 'shaders/prebuilt')
-rw-r--r--shaders/prebuilt/crt.frag.glsl27
-rw-r--r--shaders/prebuilt/crt.frag.spvbin13348 -> 13832 bytes
-rw-r--r--shaders/prebuilt/ui.frag.glsl20
-rw-r--r--shaders/prebuilt/ui.frag.spvbin3908 -> 4076 bytes
-rw-r--r--shaders/prebuilt/ui.vert.glsl7
-rw-r--r--shaders/prebuilt/ui.vert.spvbin5468 -> 5468 bytes
6 files changed, 39 insertions, 15 deletions
diff --git a/shaders/prebuilt/crt.frag.glsl b/shaders/prebuilt/crt.frag.glsl
index e43d5b86..b0b0b93b 100644
--- a/shaders/prebuilt/crt.frag.glsl
+++ b/shaders/prebuilt/crt.frag.glsl
@@ -81,24 +81,29 @@ vec2 sceneUv(vec2 uv) {
return uv;
}
-vec3 sceneSrgb(vec2 uv) {
+// The scene, ALPHA INCLUDED: with a see-through ground the grid arrives
+// premultiplied and partly empty, and a pass that dropped .a would turn the
+// desktop behind a `*_transparent` theme into opaque black the moment Crt,
+// Ripple or Glitch came on.
+vec4 sceneSrgb(vec2 uv) {
vec2 warped = sceneUv(uv);
- vec3 center = texture(u_scene, warped).rgb;
+ vec4 center = texture(u_scene, warped);
if (u_crt.effects.z <= 0.5) return center;
float band = floor(warped.y * 96.0);
float seed = noiseAt(vec2(band, floor(u_crt.time_seconds * 13.0)));
float tear = smoothstep(0.955, 1.0, seed);
vec2 chroma = vec2((0.35 + 1.25 * tear) / u_crt.viewport.x, 0.0);
- return vec3(
+ return vec4(
texture(u_scene, warped + chroma).r,
center.g,
- texture(u_scene, warped - chroma).b
+ texture(u_scene, warped - chroma).b,
+ center.a
);
}
vec3 effectSceneLinear(vec2 uv) {
- return srgbToLinear(sceneSrgb(uv));
+ return srgbToLinear(sceneSrgb(uv).rgb);
}
void main() {
@@ -113,11 +118,16 @@ void main() {
if (u_crt.effects.x <= 0.5) {
// The scene texture is already sRGB. Avoid a needless transfer-curve
// round trip so a coordinate-only effect preserves theme bytes.
- o_col = vec4(clamp(sceneSrgb(uv), 0.0, 1.0), 1.0);
+ vec4 s = sceneSrgb(uv);
+ o_col = vec4(clamp(s.rgb, 0.0, 1.0), clamp(s.a, 0.0, 1.0));
return;
}
vec3 col = vec3(0.0);
+ // Outside the tube nothing is drawn, so nothing is covered either: the
+ // old opaque black there would have punched a rectangle out of the
+ // compositor's backdrop.
+ float alpha = 0.0;
float edge = min(min(uv.x, uv.y), min(1.0 - uv.x, 1.0 - uv.y));
if (edge > 0.0) {
vec3 center = effectSceneLinear(uv);
@@ -153,10 +163,13 @@ void main() {
float vignette = 1.0 - VIGNETTE_STRENGTH * pow(clamp(r2 * 0.5, 0.0, 1.0), 1.6);
float hum = 1.0 + HUM_STRENGTH * sin((uv.y * 1.35 - u_crt.time_seconds * 0.11) * TAU);
col *= tube * vignette * hum * EXPOSURE;
+ // The tube's edge falloff dims coverage as well as colour; everything
+ // else here is a light adjustment and leaves it alone.
+ alpha = sceneSrgb(uv).a * tube;
float luma = dot(col, vec3(0.2126, 0.7152, 0.0722));
vec2 noise_seed = gl_FragCoord.xy + vec2(u_crt.frame * 17.0, u_crt.frame * 59.0);
col += (noiseAt(noise_seed) - 0.5) * NOISE_STRENGTH * (0.15 + 0.85 * clamp(luma, 0.0, 1.0));
}
- o_col = vec4(linearToSrgb(clamp(col, 0.0, 1.0)), 1.0);
+ o_col = vec4(linearToSrgb(clamp(col, 0.0, 1.0)), clamp(alpha, 0.0, 1.0));
}
diff --git a/shaders/prebuilt/crt.frag.spv b/shaders/prebuilt/crt.frag.spv
index 057f0e06..f0e14627 100644
--- a/shaders/prebuilt/crt.frag.spv
+++ b/shaders/prebuilt/crt.frag.spv
Binary files differ
diff --git a/shaders/prebuilt/ui.frag.glsl b/shaders/prebuilt/ui.frag.glsl
index ddc1cde0..69cb63b9 100644
--- a/shaders/prebuilt/ui.frag.glsl
+++ b/shaders/prebuilt/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;
}
diff --git a/shaders/prebuilt/ui.frag.spv b/shaders/prebuilt/ui.frag.spv
index 6b8a88e0..4eb9993e 100644
--- a/shaders/prebuilt/ui.frag.spv
+++ b/shaders/prebuilt/ui.frag.spv
Binary files differ
diff --git a/shaders/prebuilt/ui.vert.glsl b/shaders/prebuilt/ui.vert.glsl
index 08627dc0..5ec596fe 100644
--- a/shaders/prebuilt/ui.vert.glsl
+++ b/shaders/prebuilt/ui.vert.glsl
@@ -14,8 +14,9 @@ layout(location = 3) in vec3 a_bg;
layout(location = 4) in vec4 a_panel_rect;
layout(location = 5) in vec4 a_present_rect;
// effect id, eased-progress float bits, pane serial, local row/column packed
-// into one uint. The high effect bit marks the frozen-old cell layer; integer
-// transport preserves the exact cross-backend hash.
+// into one uint. The TWO high effect bits are flags — the frozen-old cell
+// layer and a see-through cell background — so the id is what is left below
+// them; integer transport preserves the exact cross-backend hash.
layout(location = 6) in uvec4 a_effect;
layout(location = 0) out vec2 v_uv;
@@ -54,7 +55,7 @@ void main() {
v_cell_uv = vec2(0.0, 1.0);
}
- uint effect = a_effect.x & 0x7fffffffu;
+ uint effect = a_effect.x & 0x3fffffffu;
if (effect == 1u || effect == 2u || effect == 5u) {
// NDC y points up, so a top-left/bottom-right box has a NEGATIVE y
// delta. Preserve that sign or every local y is mirrored/outside.
diff --git a/shaders/prebuilt/ui.vert.spv b/shaders/prebuilt/ui.vert.spv
index f0d5f653..08e81e42 100644
--- a/shaders/prebuilt/ui.vert.spv
+++ b/shaders/prebuilt/ui.vert.spv
Binary files differ