diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-28 16:12:01 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-09-01 08:30:41 -0300 |
| commit | 848ad99fa597387a85f75e752dc4c9e10f8c24f4 (patch) | |
| tree | 623ee400f6bec5e2a823e5a590dc4760a3084771 /shaders/prebuilt | |
| parent | b3595e04e67708c3b060a15cbbbf2478d9e6241e (diff) | |
| download | pardes-848ad99fa597387a85f75e752dc4c9e10f8c24f4.tar.gz pardes-848ad99fa597387a85f75e752dc4c9e10f8c24f4.zip | |
macos fix
Diffstat (limited to 'shaders/prebuilt')
| -rw-r--r-- | shaders/prebuilt/crt.frag.glsl | 27 | ||||
| -rw-r--r-- | shaders/prebuilt/crt.frag.spv | bin | 13348 -> 13832 bytes | |||
| -rw-r--r-- | shaders/prebuilt/ui.frag.glsl | 20 | ||||
| -rw-r--r-- | shaders/prebuilt/ui.frag.spv | bin | 3908 -> 4076 bytes | |||
| -rw-r--r-- | shaders/prebuilt/ui.vert.glsl | 7 | ||||
| -rw-r--r-- | shaders/prebuilt/ui.vert.spv | bin | 5468 -> 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 Binary files differindex 057f0e06..f0e14627 100644 --- a/shaders/prebuilt/crt.frag.spv +++ b/shaders/prebuilt/crt.frag.spv 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 Binary files differindex 6b8a88e0..4eb9993e 100644 --- a/shaders/prebuilt/ui.frag.spv +++ b/shaders/prebuilt/ui.frag.spv 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 Binary files differindex f0d5f653..08e81e42 100644 --- a/shaders/prebuilt/ui.vert.spv +++ b/shaders/prebuilt/ui.vert.spv |
