aboutsummaryrefslogtreecommitdiff
path: root/src/render_helpers
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-02-22 10:17:06 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-02-22 10:17:06 +0400
commitaefbad0cf73daade747ca47b8cb63b6c6fbdfc2b (patch)
tree1d02199e152396f31968fbb3b884e044911a5558 /src/render_helpers
parentb091202d86c1d824ce0a9ba83b21e5d50f2fc291 (diff)
downloadniri-aefbad0cf73daade747ca47b8cb63b6c6fbdfc2b.tar.gz
niri-aefbad0cf73daade747ca47b8cb63b6c6fbdfc2b.tar.bz2
niri-aefbad0cf73daade747ca47b8cb63b6c6fbdfc2b.zip
Simplify gradient border shader
Diffstat (limited to 'src/render_helpers')
-rw-r--r--src/render_helpers/gradient.rs42
-rw-r--r--src/render_helpers/shaders/gradient_border.frag31
-rw-r--r--src/render_helpers/shaders/mod.rs7
3 files changed, 31 insertions, 49 deletions
diff --git a/src/render_helpers/gradient.rs b/src/render_helpers/gradient.rs
index 1dbed05a..62fd3714 100644
--- a/src/render_helpers/gradient.rs
+++ b/src/render_helpers/gradient.rs
@@ -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,
);
diff --git a/src/render_helpers/shaders/gradient_border.frag b/src/render_helpers/shaders/gradient_border.frag
index 354968cf..91f2f3f0 100644
--- a/src/render_helpers/shaders/gradient_border.frag
+++ b/src/render_helpers/shaders/gradient_border.frag
@@ -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)
diff --git a/src/render_helpers/shaders/mod.rs b/src/render_helpers/shaders/mod.rs
index 72e9fa1c..1adbaf82 100644
--- a/src/render_helpers/shaders/mod.rs
+++ b/src/render_helpers/shaders/mod.rs
@@ -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| {