Orgnaization & cleanup

This commit is contained in:
Zachary Levy
2026-04-30 16:52:55 -07:00
parent 16989cbb71
commit fd64bc01bf
13 changed files with 269 additions and 258 deletions
+22 -23
View File
@@ -1,19 +1,18 @@
#version 450 core
// Unified backdrop blur fragment shader.
// Handles both H-blur (mode 0, blurs the ¼-resolution downsample texture into
// the ¼-resolution h_blur texture) and V-blur+composite (mode 1, blurs h_blur
// vertically, masks via RRect SDF, applies tint, composites outline, and writes
// to the main render target with premultiplied alpha).
// Handles both the 1D separable blur passes (mode 0, used for BOTH the H-pass and V-pass;
// `direction` picks the axis) and the composite pass (mode 1, reads the fully-blurred
// working texture, masks via RRect SDF, applies tint, and writes to source_texture with
// premultiplied-over blending). Working textures are sized at the full swapchain resolution;
// downsampled content occupies only a sub-rect at downsample factor > 1 (set via viewport).
//
// Following RAD's pattern, V-mode replaces a separate composite pass: the SDF
// discard limits V-blur work to the masked region, and the per-primitive tint
// is folded in. Output blends with the main render target via the standard
// premultiplied-over blend state (ONE, ONE_MINUS_SRC_ALPHA).
// The composite blends with source_texture via the standard premultiplied-over blend state
// (ONE, ONE_MINUS_SRC_ALPHA).
//
// Backdrop primitives are tint-only — there is no outline. A specialized edge
// effect (e.g. liquid-glass-style refraction outlines) would be implemented
// as a dedicated primitive type with its own pipeline.
// Backdrop primitives are tint-only — there is no outline. A specialized edge effect
// (e.g. liquid-glass-style refraction outlines) would be implemented as a dedicated
// primitive type with its own pipeline.
//
// Two modes, structurally distinct:
//
@@ -30,11 +29,11 @@
// (gl_FragCoord.xy * inv_downsample_factor) * inv_working_size.
// No kernel is applied here — the blur is already complete.
//
// Splitting V-blur out of the composite pass (an earlier version combined them) was needed
// to avoid a horizontal-vs-vertical asymmetry artifact: when the V-blur sampled the H-blur
// output through the bilinear-upsample/SDF-mask/tint pipeline in one shader invocation,
// horizontal source features ended up looking sharper than vertical ones. Running V-blur as
// its own working→working pass (matching H's structure exactly) restores symmetry.
// V-blur is run as its own working→working pass rather than folded into the composite. The
// folded variant produced a horizontal-vs-vertical asymmetry artifact: when V-blur sampled
// the H-blur output through the bilinear-upsample/SDF-mask/tint pipeline in one shader
// invocation, horizontal source features ended up looking sharper than vertical ones.
// Matching V's structure exactly to H's restores symmetry.
const uint MAX_KERNEL_PAIRS = 32;
@@ -140,16 +139,16 @@ void main() {
vec2 uv = (gl_FragCoord.xy * inv_downsample_factor) * inv_working_size;
vec3 color = texture(blur_input_tex, uv).rgb;
// Tint composition (Option B semantics): inside the masked region the panel is fully
// opaque — it completely hides the original framebuffer content, just like real frosted
// glass and like iOS UIBlurEffect / CSS backdrop-filter. f_color.rgb specifies the tint
// color; f_color.a specifies the tint *mix strength* (NOT panel opacity). At alpha=0 we
// see the pure blur; at alpha=255 we see the blur fully multiplied by the tint color.
// Tint composition: inside the masked region the panel is fully opaque — it completely
// hides the original framebuffer content, just like real frosted glass and like iOS
// UIBlurEffect / CSS backdrop-filter. f_color.rgb specifies the tint color; f_color.a
// specifies the tint *mix strength* (NOT panel opacity). At alpha=0 we see the pure
// blur; at alpha=255 we see the blur fully multiplied by the tint color.
//
// Output is premultiplied to match the ONE, ONE_MINUS_SRC_ALPHA blend state. Coverage
// (the SDF mask's edge AA) modulates only the alpha channel, never the panel-vs-source
// blend; that way edge pixels still feather correctly without re-introducing the bug
// where mid-panel pixels became semi-transparent.
// blend; that way edge pixels still feather correctly while mid-panel pixels stay fully
// opaque.
mediump vec3 tinted = mix(color, color * f_color.rgb, f_color.a);
mediump float coverage = sdf_alpha(d_n, h_n);
out_color = vec4(tinted * coverage, coverage);