fix: make glass backdrop visibly blur

This commit is contained in:
Samuel Onoja committed 2026-09-25 05:45:24 +01:00
1 parent 1ab366c9a8
commit cbf7bf3539
3 files changed
+31 -18

No files matched your search

+8 -4
View File
@@ -41,7 +41,7 @@ pub(crate) struct ResolvedMaterial {
} }
pub(crate) fn resolve_material(role: SemanticRole, style: MaterialStyle) -> ResolvedMaterial { pub(crate) fn resolve_material(role: SemanticRole, style: MaterialStyle) -> ResolvedMaterial {
let (opacity, blur, saturation, brightness, noise) = match role { let (base_opacity, blur, saturation, brightness, noise) = match role {
SemanticRole::Panel => (0.78, 24.0, 1.08, 1.02, 0.012), SemanticRole::Panel => (0.78, 24.0, 1.08, 1.02, 0.012),
SemanticRole::PanelElevated SemanticRole::PanelElevated
| SemanticRole::Popover | SemanticRole::Popover
@@ -53,7 +53,11 @@ pub(crate) fn resolve_material(role: SemanticRole, style: MaterialStyle) -> Reso
match style { match style {
MaterialStyle::Glass => ResolvedMaterial { MaterialStyle::Glass => ResolvedMaterial {
style, style,
opacity, // Glass already contains an opaque copy of the backdrop. Its tint
// therefore needs less coverage than the no-capture translucent
// profile or the blur becomes visually indistinguishable from a
// flat alpha surface.
opacity: base_opacity * 0.72,
blur, blur,
saturation, saturation,
brightness, brightness,
@@ -61,7 +65,7 @@ pub(crate) fn resolve_material(role: SemanticRole, style: MaterialStyle) -> Reso
}, },
MaterialStyle::Translucent => ResolvedMaterial { MaterialStyle::Translucent => ResolvedMaterial {
style, style,
opacity, opacity: base_opacity,
blur: 0.0, blur: 0.0,
saturation: 1.0, saturation: 1.0,
brightness: 1.0, brightness: 1.0,
@@ -299,7 +303,7 @@ mod tests {
assert!(glass.blur > 0.0); assert!(glass.blur > 0.0);
assert!(glass.noise > 0.0); assert!(glass.noise > 0.0);
assert_eq!(translucent.opacity, glass.opacity); assert!(glass.opacity < translucent.opacity);
assert_eq!(translucent.blur, 0.0); assert_eq!(translucent.blur, 0.0);
assert_eq!(translucent.noise, 0.0); assert_eq!(translucent.noise, 0.0);
assert_eq!(solid.opacity, 1.0); assert_eq!(solid.opacity, 1.0);
+21 -10
View File
@@ -261,6 +261,17 @@ float random(vec2 point) {
return fract(sin(dot(point, vec2(12.9898, 78.233))) * 43758.5453); return fract(sin(dot(point, vec2(12.9898, 78.233))) * 43758.5453);
} }
float kernel_weight(int tap) {
int distance = tap < 0 ? -tap : tap;
if (distance == 0) {
return 6.0;
}
if (distance == 1) {
return 4.0;
}
return 1.0;
}
void main() { void main() {
vec2 point = gl_FragCoord.xy; vec2 point = gl_FragCoord.xy;
vec2 visible_max = visible_rect.xy + visible_rect.zw; vec2 visible_max = visible_rect.xy + visible_rect.zw;
@@ -270,16 +281,16 @@ void main() {
return; return;
} }
vec2 step_size = vec2(blur_radius) / max(texture_size, vec2(1.0)); vec2 step_size = vec2(blur_radius * 0.5) / max(texture_size, vec2(1.0));
vec4 color = texture2D(tex, v_coords) * 0.20; vec4 color = vec4(0.0);
color += texture2D(tex, v_coords + vec2(step_size.x, 0.0)) * 0.12; for (int y = -2; y <= 2; y++) {
color += texture2D(tex, v_coords - vec2(step_size.x, 0.0)) * 0.12; for (int x = -2; x <= 2; x++) {
color += texture2D(tex, v_coords + vec2(0.0, step_size.y)) * 0.12; float weight = kernel_weight(x) * kernel_weight(y);
color += texture2D(tex, v_coords - vec2(0.0, step_size.y)) * 0.12; vec2 offset = vec2(float(x), float(y)) * step_size;
color += texture2D(tex, v_coords + step_size) * 0.08; color += texture2D(tex, v_coords + offset) * weight;
color += texture2D(tex, v_coords - step_size) * 0.08; }
color += texture2D(tex, v_coords + vec2(step_size.x, -step_size.y)) * 0.08; }
color += texture2D(tex, v_coords + vec2(-step_size.x, step_size.y)) * 0.08; color /= 256.0;
float luma = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); float luma = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
vec3 adjusted = mix(vec3(luma), color.rgb, saturation) * brightness; vec3 adjusted = mix(vec3(luma), color.rgb, saturation) * brightness;
+2 -4
View File
@@ -70,11 +70,9 @@ fn main() -> Result<(), Box<dyn Error>> {
} }
if preview { if preview {
effects.set_role(ferese_surface_effects_v1::Role::Popover); effects.set_role(ferese_surface_effects_v1::Role::Panel);
queue.roundtrip(&mut state)?; queue.roundtrip(&mut state)?;
println!( println!("PREVIEW glass panel is mapped over the patterned card; press Ctrl+C to stop");
"PREVIEW glass popover is mapped; press Ctrl+C in the compositor terminal to stop"
);
while !state.closed { while !state.closed {
queue.blocking_dispatch(&mut state)?; queue.blocking_dispatch(&mut state)?;