shaders: Extract niri_rounding_alpha() into a file

To have it in one place.
This commit is contained in:
Ivan Molodetskikh
2026-02-05 23:11:41 +03:00
parent dd1f28998f
commit 5abeb923de
7 changed files with 47 additions and 105 deletions
+3 -26
View File
@@ -208,35 +208,12 @@ vec4 gradient_color(vec2 coords) {
return color_mix(color_from, color_to, frac);
}
float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) {
vec2 center;
float radius;
if (coords.x < corner_radius.x && coords.y < corner_radius.x) {
radius = corner_radius.x;
center = vec2(radius, radius);
} else if (size.x - corner_radius.y < coords.x && coords.y < corner_radius.y) {
radius = corner_radius.y;
center = vec2(size.x - radius, radius);
} else if (size.x - corner_radius.z < coords.x && size.y - corner_radius.z < coords.y) {
radius = corner_radius.z;
center = vec2(size.x - radius, size.y - radius);
} else if (coords.x < corner_radius.w && size.y - corner_radius.w < coords.y) {
radius = corner_radius.w;
center = vec2(radius, size.y - radius);
} else {
return 1.0;
}
float dist = distance(coords, center);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
float niri_rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius);
void main() {
vec3 coords_geo = input_to_geo * vec3(niri_v_coords, 1.0);
vec4 color = gradient_color(coords_geo.xy);
color = color * rounding_alpha(coords_geo.xy, geo_size, outer_radius);
color = color * niri_rounding_alpha(coords_geo.xy, geo_size, outer_radius);
if (border_width > 0.0) {
coords_geo -= vec3(border_width);
@@ -245,7 +222,7 @@ void main() {
&& 0.0 <= coords_geo.y && coords_geo.y <= inner_geo_size.y)
{
vec4 inner_radius = max(outer_radius - vec4(border_width), 0.0);
color = color * (1.0 - rounding_alpha(coords_geo.xy, inner_geo_size, inner_radius));
color = color * (1.0 - niri_rounding_alpha(coords_geo.xy, inner_geo_size, inner_radius));
}
}
@@ -26,30 +26,7 @@ uniform vec2 geo_size;
uniform vec4 corner_radius;
uniform mat3 input_to_geo;
float rounding_alpha(vec2 coords, vec2 size) {
vec2 center;
float radius;
if (coords.x < corner_radius.x && coords.y < corner_radius.x) {
radius = corner_radius.x;
center = vec2(radius, radius);
} else if (size.x - corner_radius.y < coords.x && coords.y < corner_radius.y) {
radius = corner_radius.y;
center = vec2(size.x - radius, radius);
} else if (size.x - corner_radius.z < coords.x && size.y - corner_radius.z < coords.y) {
radius = corner_radius.z;
center = vec2(size.x - radius, size.y - radius);
} else if (coords.x < corner_radius.w && size.y - corner_radius.w < coords.y) {
radius = corner_radius.w;
center = vec2(radius, size.y - radius);
} else {
return 1.0;
}
float dist = distance(coords, center);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
float niri_rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius);
void main() {
vec3 coords_geo = input_to_geo * vec3(v_coords, 1.0);
@@ -65,7 +42,7 @@ void main() {
color = vec4(0.0);
} else {
// Apply corner rounding inside geometry.
color = color * rounding_alpha(coords_geo.xy * geo_size, geo_size);
color = color * niri_rounding_alpha(coords_geo.xy * geo_size, geo_size, corner_radius);
}
// Apply final alpha and tint.
+13 -3
View File
@@ -35,7 +35,10 @@ impl Shaders {
let border = ShaderProgram::compile(
renderer,
include_str!("border.frag"),
concat!(
include_str!("border.frag"),
include_str!("rounding_alpha.frag")
),
&[
UniformName::new("colorspace", UniformType::_1f),
UniformName::new("hue_interpolation", UniformType::_1f),
@@ -58,7 +61,10 @@ impl Shaders {
let shadow = ShaderProgram::compile(
renderer,
include_str!("shadow.frag"),
concat!(
include_str!("shadow.frag"),
include_str!("rounding_alpha.frag")
),
&[
UniformName::new("shadow_color", UniformType::_4f),
UniformName::new("sigma", UniformType::_1f),
@@ -78,7 +84,10 @@ impl Shaders {
let clipped_surface = renderer
.compile_custom_texture_shader(
include_str!("clipped_surface.frag"),
concat!(
include_str!("clipped_surface.frag"),
include_str!("rounding_alpha.frag")
),
&[
UniformName::new("niri_scale", UniformType::_1f),
UniformName::new("geo_size", UniformType::_2f),
@@ -183,6 +192,7 @@ fn compile_resize_program(
let mut program = include_str!("resize_prelude.frag").to_string();
program.push_str(src);
program.push_str(include_str!("resize_epilogue.frag"));
program.push_str(include_str!("rounding_alpha.frag"));
ShaderProgram::compile(
renderer,
@@ -12,7 +12,7 @@ void main() {
color = vec4(0.0);
} else {
// Apply corner rounding inside geometry.
color = color * niri_rounding_alpha(coords_curr_geo.xy * size_curr_geo.xy, size_curr_geo.xy);
color = color * niri_rounding_alpha(coords_curr_geo.xy * size_curr_geo.xy, size_curr_geo.xy, niri_corner_radius);
}
}
+1 -24
View File
@@ -27,27 +27,4 @@ uniform float niri_clip_to_geometry;
uniform float niri_alpha;
uniform float niri_scale;
float niri_rounding_alpha(vec2 coords, vec2 size) {
vec2 center;
float radius;
if (coords.x < niri_corner_radius.x && coords.y < niri_corner_radius.x) {
radius = niri_corner_radius.x;
center = vec2(radius, radius);
} else if (size.x - niri_corner_radius.y < coords.x && coords.y < niri_corner_radius.y) {
radius = niri_corner_radius.y;
center = vec2(size.x - radius, radius);
} else if (size.x - niri_corner_radius.z < coords.x && size.y - niri_corner_radius.z < coords.y) {
radius = niri_corner_radius.z;
center = vec2(size.x - radius, size.y - radius);
} else if (coords.x < niri_corner_radius.w && size.y - niri_corner_radius.w < coords.y) {
radius = niri_corner_radius.w;
center = vec2(radius, size.y - radius);
} else {
return 1.0;
}
float dist = distance(coords, center);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
float niri_rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius);
@@ -0,0 +1,24 @@
float niri_rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) {
vec2 center;
float radius;
if (coords.x < corner_radius.x && coords.y < corner_radius.x) {
radius = corner_radius.x;
center = vec2(radius, radius);
} else if (size.x - corner_radius.y < coords.x && coords.y < corner_radius.y) {
radius = corner_radius.y;
center = vec2(size.x - radius, radius);
} else if (size.x - corner_radius.z < coords.x && size.y - corner_radius.z < coords.y) {
radius = corner_radius.z;
center = vec2(size.x - radius, size.y - radius);
} else if (coords.x < corner_radius.w && size.y - corner_radius.w < coords.y) {
radius = corner_radius.w;
center = vec2(radius, size.y - radius);
} else {
return 1.0;
}
float dist = distance(coords, center);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
+3 -26
View File
@@ -72,30 +72,7 @@ float roundedBoxShadow(vec2 lower, vec2 upper, vec2 point, float sigma, float co
return value;
}
float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) {
vec2 center;
float radius;
if (coords.x < corner_radius.x && coords.y < corner_radius.x) {
radius = corner_radius.x;
center = vec2(radius, radius);
} else if (size.x - corner_radius.y < coords.x && coords.y < corner_radius.y) {
radius = corner_radius.y;
center = vec2(size.x - radius, radius);
} else if (size.x - corner_radius.z < coords.x && size.y - corner_radius.z < coords.y) {
radius = corner_radius.z;
center = vec2(size.x - radius, size.y - radius);
} else if (coords.x < corner_radius.w && size.y - corner_radius.w < coords.y) {
radius = corner_radius.w;
center = vec2(radius, size.y - radius);
} else {
return 1.0;
}
float dist = distance(coords, center);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
float niri_rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius);
void main() {
vec3 coords_geo = input_to_geo * vec3(niri_v_coords, 1.0);
@@ -106,7 +83,7 @@ void main() {
float shadow_value;
if (sigma < 0.1) {
// With low enough sigma just draw a rounded rectangle.
shadow_value = rounding_alpha(coords_geo.xy, geo_size, corner_radius);
shadow_value = niri_rounding_alpha(coords_geo.xy, geo_size, corner_radius);
} else {
shadow_value = roundedBoxShadow(
vec2(0.0, 0.0),
@@ -126,7 +103,7 @@ void main() {
if (window_geo_size != vec2(0.0, 0.0)) {
if (0.0 <= coords_window_geo.x && coords_window_geo.x <= window_geo_size.x
&& 0.0 <= coords_window_geo.y && coords_window_geo.y <= window_geo_size.y) {
float alpha = rounding_alpha(coords_window_geo.xy, window_geo_size, window_corner_radius);
float alpha = niri_rounding_alpha(coords_window_geo.xy, window_geo_size, window_corner_radius);
color = color * (1.0 - alpha);
}
}