diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-02-22 10:17:06 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-02-22 10:17:06 +0400 |
| commit | aefbad0cf73daade747ca47b8cb63b6c6fbdfc2b (patch) | |
| tree | 1d02199e152396f31968fbb3b884e044911a5558 /src/render_helpers | |
| parent | b091202d86c1d824ce0a9ba83b21e5d50f2fc291 (diff) | |
| download | niri-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.rs | 42 | ||||
| -rw-r--r-- | src/render_helpers/shaders/gradient_border.frag | 31 | ||||
| -rw-r--r-- | src/render_helpers/shaders/mod.rs | 7 |
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| { |
