summaryrefslogtreecommitdiff
path: root/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'shaders')
-rw-r--r--shaders/crt.ci.metal78
-rw-r--r--shaders/image.frag.glsl60
-rw-r--r--shaders/prebuilt/image.frag.glsl60
-rw-r--r--shaders/prebuilt/image.frag.spvbin10372 -> 3684 bytes
-rw-r--r--shaders/prebuilt/ui.frag.glsl60
-rw-r--r--shaders/prebuilt/ui.frag.spvbin9712 -> 3908 bytes
-rw-r--r--shaders/ui.frag.glsl60
7 files changed, 14 insertions, 304 deletions
diff --git a/shaders/crt.ci.metal b/shaders/crt.ci.metal
index 32e26b21..e1db5770 100644
--- a/shaders/crt.ci.metal
+++ b/shaders/crt.ci.metal
@@ -106,7 +106,6 @@ float pardesPanelProgress(float effect, float frame) {
float frames = effect == 1.0 ? 12.0 :
effect == 2.0 ? 14.0 :
effect == 3.0 ? 10.0 :
- effect == 4.0 ? 16.0 :
effect == 5.0 ? 12.0 : 1.0;
if (frames <= 1.0 || frame >= frames - 1.0) return 1.0;
float t = clamp(frame / (frames - 1.0), 0.0, 1.0);
@@ -121,33 +120,7 @@ float pardesPanelProgress(float effect, float frame) {
return 1.0 + c3 * u * u * u + c1 * u * u;
}
if (effect == 3.0) return t * t * (3.0 - 2.0 * t); // dissolve
- return t; // ASCII materialization
-}
-
-float pardesAsciiGlyph(float2 uv, int glyph) {
- float2 p = uv * 2.0 - 1.0;
- const float thin = 0.12;
- float dotShape = 1.0 - smoothstep(0.10, 0.20, length(p - float2(0.0, 0.45)));
- float barH = 1.0 - smoothstep(thin, thin + 0.08, abs(p.y));
- float barV = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x));
- if (glyph == 0) return dotShape;
- if (glyph == 1) return max(dotShape,
- 1.0 - smoothstep(0.10, 0.20, length(p + float2(0.0, 0.45))));
- if (glyph == 2) return max(barH, barV);
- if (glyph == 3) {
- float d0 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x - p.y));
- float d1 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x + p.y));
- return max(max(d0, d1), max(barH, barV));
- }
- if (glyph == 4) {
- float rails = max(
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.x) - 0.34)),
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.y) - 0.34)));
- return rails;
- }
- float ring = 1.0 - smoothstep(thin, thin + 0.08,
- abs(length(p * float2(0.8, 1.0)) - 0.48));
- return max(ring, glyph == 6 ? dotShape : 0.0);
+ return t; // ASCII cells are already composed; retained for ABI completeness
}
// Prepare every geometric target before any translated panel is drawn. A
@@ -195,10 +168,18 @@ extern "C" float4 pardesPanel(
float progress = pardesPanelProgress(effect, frame);
float2 safeCell = max(cellSize, float2(1.0));
- // Content transitions stay at canonical geometry. Unchanged cells bypass
- // the effect completely; changed cells retain the exact old raster until
- // their deterministic wave reaches them.
- if (effect == 3.0 || effect == 4.0) {
+ // ASCII bytes were already composed in Pardes core before CoreText built
+ // `current`. Pixel attachments have no character value and intentionally
+ // pass through unchanged, so this kernel only clips the pane batch.
+ if (effect == 4.0) {
+ if (!pardesInside(coord, target)) return underneath;
+ return current.sample(current.transform(coord));
+ }
+
+ // Dissolve stays at canonical geometry. Unchanged cells bypass the effect
+ // completely; changed cells retain the exact old raster until their
+ // deterministic threshold is crossed.
+ if (effect == 3.0) {
if (!pardesInside(coord, target)) return underneath;
// During a live resize the grid is still anchored at the view's top,
// leaving a partial strip below its final logical row. Account for
@@ -223,38 +204,7 @@ extern "C" float4 pardesPanel(
float2 cellCount = max(round(target.zw / safeCell), float2(1.0));
cell = clamp(cell, float2(0.0), cellCount - 1.0);
float noise = pardesCellNoise(serialParts, cell.x, cell.y);
- if (effect == 3.0)
- return noise < progress ? newPixel : oldPixel;
-
- float diagonal = fmod(cell.x + cell.y * 2.0, 17.0) / 17.0;
- float threshold = noise * 0.72 + diagonal * 0.28;
- if (progress >= threshold) return newPixel;
- if (progress + 0.22 < threshold) return oldPixel;
-
- float2 cellUV = fract(float2(
- (coord.x - target.x) / safeCell.x,
- (target.y + target.w - coord.y) / safeCell.y));
- int glyph = min(int(floor(noise * 7.0)), 6);
- float ink = pardesAsciiGlyph(cellUV, glyph);
- float2 cellOrigin = float2(
- target.x + cell.x * safeCell.x,
- target.y + target.w - (cell.y + 1.0) * safeCell.y);
- float4 bgSample = current.sample(current.transform(
- cellOrigin + safeCell * float2(0.12, 0.12)));
- float4 bg = coreimage::unpremultiply(bgSample);
- float4 fg = coreimage::unpremultiply(newPixel);
- // A procedural mark usually crosses pixels where the target glyph has
- // no ink, so sampling `newPixel` alone can make it background-on-
- // background and erase the ASCII phase. Preserve target ink where it
- // is present; otherwise derive restrained contrast from the cell's
- // own background instead of imposing a fixed palette.
- float3 contrastInk = dot(bg.rgb, float3(0.2126, 0.7152, 0.0722)) > 0.5
- ? float3(0.0) : float3(1.0);
- float sourceContrast = smoothstep(0.025, 0.14, length(fg.rgb - bg.rgb));
- float3 inkColor = mix(contrastInk, fg.rgb, sourceContrast);
- float3 dimInk = mix(bg.rgb, inkColor, 0.62);
- return coreimage::premultiply(float4(
- mix(bg.rgb, dimInk, ink), max(bg.a, newPixel.a)));
+ return noise < progress ? newPixel : oldPixel;
}
float4 shown = mix(from, to, progress);
diff --git a/shaders/image.frag.glsl b/shaders/image.frag.glsl
index 747ceef7..2a3c2038 100644
--- a/shaders/image.frag.glsl
+++ b/shaders/image.frag.glsl
@@ -17,35 +17,6 @@ float cellNoise(uint serial, uint col, uint row) {
return float(x & 0xffffu) / 65535.0;
}
-// The same seven procedural ASCII marks as ui.frag.glsl and the macOS Metal
-// panel kernel. Native attachments are content in the panel, so they should
-// not switch to a smaller two-symbol animation when the glyph grid over them
-// is using `. : + * # % @`.
-float asciiGlyph(vec2 uv, int glyph) {
- vec2 p = uv * 2.0 - 1.0;
- float thin = 0.12;
- float dotShape = 1.0 - smoothstep(0.10, 0.20, length(p - vec2(0.0, 0.45)));
- float barH = 1.0 - smoothstep(thin, thin + 0.08, abs(p.y));
- float barV = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x));
- if (glyph == 0) return dotShape;
- if (glyph == 1) return max(dotShape, 1.0 - smoothstep(0.10, 0.20, length(p + vec2(0.0, 0.45))));
- if (glyph == 2) return max(barH, barV);
- if (glyph == 3) {
- float d0 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x - p.y));
- float d1 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x + p.y));
- return max(max(d0, d1), max(barH, barV));
- }
- if (glyph == 4) {
- float rails = max(
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.x) - 0.34)),
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.y) - 0.34))
- );
- return rails;
- }
- float ring = 1.0 - smoothstep(thin, thin + 0.08, abs(length(p * vec2(0.8, 1.0)) - 0.48));
- return max(ring, glyph == 6 ? dotShape : 0.0);
-}
-
void main() {
vec4 source = texture(u_image, v_uv);
uint effect = v_effect.x & 0x7fffffffu;
@@ -64,36 +35,5 @@ void main() {
o_col = source;
return;
}
- if (effect == 4u) {
- float diagonal = float((cellCoord.x + cellCoord.y * 2u) % 17u) / 17.0;
- float threshold = noise * 0.72 + diagonal * 0.28;
- bool reveal = progress >= 1.0 || (progress > 0.0 && progress >= threshold);
- bool wave = !reveal && progress > 0.0 && progress + 0.22 >= threshold;
- if (oldLayer) {
- if (wave || reveal) discard;
- o_col = source;
- return;
- }
- if (reveal) {
- o_col = source;
- return;
- }
- if (!wave) discard;
- vec2 cellUV = fract(v_panel_uv * vec2(dimensions));
- int glyph = min(int(floor(noise * 7.0)), 6);
- float mark = asciiGlyph(cellUV, glyph);
- float luma = dot(source.rgb, vec3(0.2126, 0.7152, 0.0722));
- vec3 paper = source.rgb * 0.10;
- // Preserve source colour when it already separates from the dimmed
- // paper. Solid black pixels have no such separation, so derive a
- // readable mark from their own luminance instead of letting the ASCII
- // phase disappear on dark images/PDF regions.
- vec3 contrastInk = luma > 0.5 ? vec3(0.0) : vec3(1.0);
- float sourceContrast = smoothstep(0.025, 0.14, length(source.rgb - paper));
- vec3 ink = mix(contrastInk, source.rgb, sourceContrast);
- vec3 dimInk = mix(paper, ink, 0.62);
- o_col = vec4(mix(paper, dimInk, mark), source.a);
- return;
- }
o_col = source;
}
diff --git a/shaders/prebuilt/image.frag.glsl b/shaders/prebuilt/image.frag.glsl
index 747ceef7..2a3c2038 100644
--- a/shaders/prebuilt/image.frag.glsl
+++ b/shaders/prebuilt/image.frag.glsl
@@ -17,35 +17,6 @@ float cellNoise(uint serial, uint col, uint row) {
return float(x & 0xffffu) / 65535.0;
}
-// The same seven procedural ASCII marks as ui.frag.glsl and the macOS Metal
-// panel kernel. Native attachments are content in the panel, so they should
-// not switch to a smaller two-symbol animation when the glyph grid over them
-// is using `. : + * # % @`.
-float asciiGlyph(vec2 uv, int glyph) {
- vec2 p = uv * 2.0 - 1.0;
- float thin = 0.12;
- float dotShape = 1.0 - smoothstep(0.10, 0.20, length(p - vec2(0.0, 0.45)));
- float barH = 1.0 - smoothstep(thin, thin + 0.08, abs(p.y));
- float barV = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x));
- if (glyph == 0) return dotShape;
- if (glyph == 1) return max(dotShape, 1.0 - smoothstep(0.10, 0.20, length(p + vec2(0.0, 0.45))));
- if (glyph == 2) return max(barH, barV);
- if (glyph == 3) {
- float d0 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x - p.y));
- float d1 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x + p.y));
- return max(max(d0, d1), max(barH, barV));
- }
- if (glyph == 4) {
- float rails = max(
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.x) - 0.34)),
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.y) - 0.34))
- );
- return rails;
- }
- float ring = 1.0 - smoothstep(thin, thin + 0.08, abs(length(p * vec2(0.8, 1.0)) - 0.48));
- return max(ring, glyph == 6 ? dotShape : 0.0);
-}
-
void main() {
vec4 source = texture(u_image, v_uv);
uint effect = v_effect.x & 0x7fffffffu;
@@ -64,36 +35,5 @@ void main() {
o_col = source;
return;
}
- if (effect == 4u) {
- float diagonal = float((cellCoord.x + cellCoord.y * 2u) % 17u) / 17.0;
- float threshold = noise * 0.72 + diagonal * 0.28;
- bool reveal = progress >= 1.0 || (progress > 0.0 && progress >= threshold);
- bool wave = !reveal && progress > 0.0 && progress + 0.22 >= threshold;
- if (oldLayer) {
- if (wave || reveal) discard;
- o_col = source;
- return;
- }
- if (reveal) {
- o_col = source;
- return;
- }
- if (!wave) discard;
- vec2 cellUV = fract(v_panel_uv * vec2(dimensions));
- int glyph = min(int(floor(noise * 7.0)), 6);
- float mark = asciiGlyph(cellUV, glyph);
- float luma = dot(source.rgb, vec3(0.2126, 0.7152, 0.0722));
- vec3 paper = source.rgb * 0.10;
- // Preserve source colour when it already separates from the dimmed
- // paper. Solid black pixels have no such separation, so derive a
- // readable mark from their own luminance instead of letting the ASCII
- // phase disappear on dark images/PDF regions.
- vec3 contrastInk = luma > 0.5 ? vec3(0.0) : vec3(1.0);
- float sourceContrast = smoothstep(0.025, 0.14, length(source.rgb - paper));
- vec3 ink = mix(contrastInk, source.rgb, sourceContrast);
- vec3 dimInk = mix(paper, ink, 0.62);
- o_col = vec4(mix(paper, dimInk, mark), source.a);
- return;
- }
o_col = source;
}
diff --git a/shaders/prebuilt/image.frag.spv b/shaders/prebuilt/image.frag.spv
index c3d87e58..ac6a2682 100644
--- a/shaders/prebuilt/image.frag.spv
+++ b/shaders/prebuilt/image.frag.spv
Binary files differ
diff --git a/shaders/prebuilt/ui.frag.glsl b/shaders/prebuilt/ui.frag.glsl
index 2113f6ae..ddc1cde0 100644
--- a/shaders/prebuilt/ui.frag.glsl
+++ b/shaders/prebuilt/ui.frag.glsl
@@ -23,31 +23,6 @@ float cellNoise(uint serial, uint col, uint row) {
return float(x & 0xffffu) / 65535.0;
}
-float asciiGlyph(vec2 uv, int glyph) {
- vec2 p = uv * 2.0 - 1.0;
- float thin = 0.12;
- float dotShape = 1.0 - smoothstep(0.10, 0.20, length(p - vec2(0.0, 0.45)));
- float barH = 1.0 - smoothstep(thin, thin + 0.08, abs(p.y));
- float barV = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x));
- if (glyph == 0) return dotShape;
- if (glyph == 1) return max(dotShape, 1.0 - smoothstep(0.10, 0.20, length(p + vec2(0.0, 0.45))));
- if (glyph == 2) return max(barH, barV);
- if (glyph == 3) {
- float d0 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x - p.y));
- float d1 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x + p.y));
- return max(max(d0, d1), max(barH, barV));
- }
- if (glyph == 4) {
- float rails = max(
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.x) - 0.34)),
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.y) - 0.34))
- );
- return rails;
- }
- float ring = 1.0 - smoothstep(thin, thin + 0.08, abs(length(p * vec2(0.8, 1.0)) - 0.48));
- return max(ring, glyph == 6 ? dotShape : 0.0);
-}
-
void main() {
float a = texture(u_atlas, v_uv).r;
bool oldLayer = (v_effect.x & 0x80000000u) != 0u;
@@ -69,41 +44,6 @@ void main() {
return;
}
- // 4 = ASCII materialization. A diagonal/noise threshold matches the TTY
- // compositor's idea: cells briefly become punctuation, then their real
- // atlas glyph arrives. The procedural marks keep the GUI implementation
- // entirely shader-side.
- if (effect == 4u) {
- if (progress <= 0.0) {
- if (!oldLayer) discard;
- o_col = vec4(cell, 1.0);
- return;
- }
- if (progress >= 1.0) {
- if (oldLayer) discard;
- o_col = vec4(cell, 1.0);
- return;
- }
- float diagonal = float((cellCol + cellRow * 2u) % 17u) / 17.0;
- float threshold = noise * 0.72 + diagonal * 0.28;
- if (progress >= threshold) {
- if (oldLayer) discard;
- o_col = vec4(cell, 1.0);
- return;
- }
- if (progress + 0.22 >= threshold) {
- if (oldLayer) discard;
- int glyph = int(floor(noise * 7.0));
- float ink = asciiGlyph(v_cell_uv, min(glyph, 6));
- vec3 dimInk = mix(v_bg, v_fg, 0.62);
- o_col = vec4(mix(v_bg, dimInk, ink), 1.0);
- return;
- }
- if (!oldLayer) discard;
- o_col = vec4(cell, 1.0);
- 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);
diff --git a/shaders/prebuilt/ui.frag.spv b/shaders/prebuilt/ui.frag.spv
index b97495b3..6b8a88e0 100644
--- a/shaders/prebuilt/ui.frag.spv
+++ b/shaders/prebuilt/ui.frag.spv
Binary files differ
diff --git a/shaders/ui.frag.glsl b/shaders/ui.frag.glsl
index 2113f6ae..ddc1cde0 100644
--- a/shaders/ui.frag.glsl
+++ b/shaders/ui.frag.glsl
@@ -23,31 +23,6 @@ float cellNoise(uint serial, uint col, uint row) {
return float(x & 0xffffu) / 65535.0;
}
-float asciiGlyph(vec2 uv, int glyph) {
- vec2 p = uv * 2.0 - 1.0;
- float thin = 0.12;
- float dotShape = 1.0 - smoothstep(0.10, 0.20, length(p - vec2(0.0, 0.45)));
- float barH = 1.0 - smoothstep(thin, thin + 0.08, abs(p.y));
- float barV = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x));
- if (glyph == 0) return dotShape;
- if (glyph == 1) return max(dotShape, 1.0 - smoothstep(0.10, 0.20, length(p + vec2(0.0, 0.45))));
- if (glyph == 2) return max(barH, barV);
- if (glyph == 3) {
- float d0 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x - p.y));
- float d1 = 1.0 - smoothstep(thin, thin + 0.08, abs(p.x + p.y));
- return max(max(d0, d1), max(barH, barV));
- }
- if (glyph == 4) {
- float rails = max(
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.x) - 0.34)),
- 1.0 - smoothstep(thin, thin + 0.08, abs(abs(p.y) - 0.34))
- );
- return rails;
- }
- float ring = 1.0 - smoothstep(thin, thin + 0.08, abs(length(p * vec2(0.8, 1.0)) - 0.48));
- return max(ring, glyph == 6 ? dotShape : 0.0);
-}
-
void main() {
float a = texture(u_atlas, v_uv).r;
bool oldLayer = (v_effect.x & 0x80000000u) != 0u;
@@ -69,41 +44,6 @@ void main() {
return;
}
- // 4 = ASCII materialization. A diagonal/noise threshold matches the TTY
- // compositor's idea: cells briefly become punctuation, then their real
- // atlas glyph arrives. The procedural marks keep the GUI implementation
- // entirely shader-side.
- if (effect == 4u) {
- if (progress <= 0.0) {
- if (!oldLayer) discard;
- o_col = vec4(cell, 1.0);
- return;
- }
- if (progress >= 1.0) {
- if (oldLayer) discard;
- o_col = vec4(cell, 1.0);
- return;
- }
- float diagonal = float((cellCol + cellRow * 2u) % 17u) / 17.0;
- float threshold = noise * 0.72 + diagonal * 0.28;
- if (progress >= threshold) {
- if (oldLayer) discard;
- o_col = vec4(cell, 1.0);
- return;
- }
- if (progress + 0.22 >= threshold) {
- if (oldLayer) discard;
- int glyph = int(floor(noise * 7.0));
- float ink = asciiGlyph(v_cell_uv, min(glyph, 6));
- vec3 dimInk = mix(v_bg, v_fg, 0.62);
- o_col = vec4(mix(v_bg, dimInk, ink), 1.0);
- return;
- }
- if (!oldLayer) discard;
- o_col = vec4(cell, 1.0);
- 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);