mirror of
https://github.com/YaLTeR/niri.git
synced 2024-09-11 12:35:58 +03:00
Simplify gradient border shader
This commit is contained in:
parent
b091202d86
commit
aefbad0cf7
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -1390,6 +1390,12 @@ dependencies = [
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.19.0"
|
||||
@ -2104,6 +2110,7 @@ dependencies = [
|
||||
"directories",
|
||||
"futures-util",
|
||||
"git-version",
|
||||
"glam",
|
||||
"input",
|
||||
"keyframe",
|
||||
"libc",
|
||||
|
@ -50,6 +50,7 @@ clap = { workspace = true, features = ["string"] }
|
||||
directories = "5.0.1"
|
||||
futures-util = { version = "0.3.30", default-features = false, features = ["std", "io"] }
|
||||
git-version = "0.3.9"
|
||||
glam = "0.25.0"
|
||||
input = { version = "0.9.0", features = ["libinput_1_21"] }
|
||||
keyframe = { version = "1.1.1", default-features = false }
|
||||
libc = "0.2.153"
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::f32::consts::{self, FRAC_PI_2, PI};
|
||||
|
||||
use glam::Vec2;
|
||||
use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage};
|
||||
use smithay::backend::renderer::gles::element::PixelShaderElement;
|
||||
use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, Uniform};
|
||||
@ -23,31 +22,25 @@ impl GradientRenderElement {
|
||||
gradient_area: Rectangle<i32, Logical>,
|
||||
color_from: [f32; 4],
|
||||
color_to: [f32; 4],
|
||||
mut angle: f32,
|
||||
angle: f32,
|
||||
) -> Option<Self> {
|
||||
let shader = Shaders::get(renderer).gradient_border.clone()?;
|
||||
let g_offset = (area.loc - gradient_area.loc).to_f64().to_physical(scale);
|
||||
let grad_offset = (area.loc - gradient_area.loc).to_f64().to_physical(scale);
|
||||
|
||||
let g_size = gradient_area.size.to_f64().to_physical(scale);
|
||||
let (w, h) = (g_size.w as f32, g_size.h as f32);
|
||||
let g_area_angle = f32::atan2(h, w);
|
||||
let g_area_diag = f32::hypot(h, w);
|
||||
let grad_dir = Vec2::from_angle(angle);
|
||||
|
||||
// Normalize the angle to [0°; 360°).
|
||||
while angle < 0. {
|
||||
angle += consts::TAU;
|
||||
}
|
||||
while angle >= consts::TAU {
|
||||
angle -= consts::TAU;
|
||||
let grad_area_size = gradient_area.size.to_f64().to_physical(scale);
|
||||
let (w, h) = (grad_area_size.w as f32, grad_area_size.h as f32);
|
||||
|
||||
let mut grad_area_diag = Vec2::new(w, h);
|
||||
if (grad_dir.x < 0. && 0. <= grad_dir.y) || (0. <= grad_dir.x && grad_dir.y < 0.) {
|
||||
grad_area_diag.x = -w;
|
||||
}
|
||||
|
||||
let angle_diag_to_grad =
|
||||
if (0. ..=FRAC_PI_2).contains(&angle) || (PI..=PI + FRAC_PI_2).contains(&angle) {
|
||||
angle - g_area_angle
|
||||
} else {
|
||||
(PI - angle) - g_area_angle
|
||||
};
|
||||
let g_total = angle_diag_to_grad.cos().abs() * g_area_diag;
|
||||
let mut grad_vec = grad_area_diag.project_onto(grad_dir);
|
||||
if grad_dir.y <= 0. {
|
||||
grad_vec = -grad_vec;
|
||||
}
|
||||
|
||||
let elem = PixelShaderElement::new(
|
||||
shader,
|
||||
@ -57,10 +50,9 @@ impl GradientRenderElement {
|
||||
vec![
|
||||
Uniform::new("color_from", color_from),
|
||||
Uniform::new("color_to", color_to),
|
||||
Uniform::new("angle", angle),
|
||||
Uniform::new("gradient_offset", (g_offset.x as f32, g_offset.y as f32)),
|
||||
Uniform::new("gradient_width", w),
|
||||
Uniform::new("gradient_total", g_total),
|
||||
Uniform::new("grad_offset", (grad_offset.x as f32, grad_offset.y as f32)),
|
||||
Uniform::new("grad_width", w),
|
||||
Uniform::new("grad_vec", grad_vec.to_array()),
|
||||
],
|
||||
Kind::Unspecified,
|
||||
);
|
||||
|
@ -8,33 +8,24 @@ varying vec2 v_coords;
|
||||
|
||||
uniform vec4 color_from;
|
||||
uniform vec4 color_to;
|
||||
uniform float angle;
|
||||
uniform vec2 gradient_offset;
|
||||
uniform float gradient_width;
|
||||
uniform float gradient_total;
|
||||
|
||||
#define FRAC_PI_2 1.57079632679
|
||||
#define PI 3.14159265359
|
||||
#define FRAC_3_PI_2 4.71238898038
|
||||
#define TAU 6.28318530718
|
||||
uniform vec2 grad_offset;
|
||||
uniform float grad_width;
|
||||
uniform vec2 grad_vec;
|
||||
|
||||
void main() {
|
||||
vec2 coords = v_coords * size + gradient_offset;
|
||||
vec2 coords = v_coords * size + grad_offset;
|
||||
|
||||
if ((FRAC_PI_2 <= angle && angle < PI) || (FRAC_3_PI_2 <= angle && angle < TAU))
|
||||
coords.x -= gradient_width;
|
||||
if ((grad_vec.x < 0.0 && 0.0 <= grad_vec.y)
|
||||
|| (0.0 <= grad_vec.x && grad_vec.y < 0.0)) {
|
||||
coords.x -= grad_width;
|
||||
}
|
||||
|
||||
float frag_angle = FRAC_PI_2;
|
||||
if (coords.x != 0.0)
|
||||
frag_angle = atan(coords.y, coords.x);
|
||||
float frac = dot(coords, grad_vec) / dot(grad_vec, grad_vec);
|
||||
|
||||
float angle_frag_to_grad = frag_angle - angle;
|
||||
if (grad_vec.y < 0.0)
|
||||
frac = 1.0 + frac;
|
||||
|
||||
float frac = cos(angle_frag_to_grad) * length(coords) / gradient_total;
|
||||
if (PI <= angle)
|
||||
frac += 1.0;
|
||||
frac = clamp(frac, 0.0, 1.0);
|
||||
|
||||
vec4 out_color = mix(color_from, color_to, frac);
|
||||
|
||||
#if defined(DEBUG_FLAGS)
|
||||
|
@ -16,10 +16,9 @@ impl Shaders {
|
||||
&[
|
||||
UniformName::new("color_from", UniformType::_4f),
|
||||
UniformName::new("color_to", UniformType::_4f),
|
||||
UniformName::new("angle", UniformType::_1f),
|
||||
UniformName::new("gradient_offset", UniformType::_2f),
|
||||
UniformName::new("gradient_width", UniformType::_1f),
|
||||
UniformName::new("gradient_total", UniformType::_1f),
|
||||
UniformName::new("grad_offset", UniformType::_2f),
|
||||
UniformName::new("grad_width", UniformType::_1f),
|
||||
UniformName::new("grad_vec", UniformType::_2f),
|
||||
],
|
||||
)
|
||||
.map_err(|err| {
|
||||
|
Loading…
Reference in New Issue
Block a user