cranpose_ui_graphics/
gradient_blur.rs1use crate::{RenderEffect, RuntimeShader};
9
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
12pub enum GradientBlurDirection {
13 LeftToRight,
14 RightToLeft,
15 #[default]
16 TopToBottom,
17 BottomToTop,
18}
19
20impl GradientBlurDirection {
21 fn uniform_code(self) -> f32 {
22 match self {
23 Self::LeftToRight => 0.0,
24 Self::RightToLeft => 1.0,
25 Self::TopToBottom => 2.0,
26 Self::BottomToTop => 3.0,
27 }
28 }
29}
30
31pub const GRADIENT_BLUR_WGSL: &str = include_str!("../shaders/gradient_blur.wgsl");
33
34pub fn gradient_blur_effect(
40 start_radius_px: f32,
41 end_radius_px: f32,
42 direction: GradientBlurDirection,
43) -> RenderEffect {
44 let start_radius_px = start_radius_px.max(0.0);
45 let end_radius_px = end_radius_px.max(0.0);
46 let mut shader = RuntimeShader::new(GRADIENT_BLUR_WGSL);
47 shader.set_float(0, start_radius_px);
48 shader.set_float(1, end_radius_px);
49 shader.set_float(2, direction.uniform_code());
50 shader.set_input_padding(start_radius_px.max(end_radius_px).ceil());
51 RenderEffect::runtime_shader(shader)
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn gradient_blur_carries_endpoint_radii_and_capture_padding() {
60 let RenderEffect::Shader { shader } =
61 gradient_blur_effect(0.5, 18.25, GradientBlurDirection::BottomToTop)
62 else {
63 panic!("gradient blur must use the spatial runtime shader");
64 };
65 assert_eq!(&shader.uniforms()[..3], &[0.5, 18.25, 3.0]);
66 assert_eq!(shader.input_padding(), 19.0);
67 }
68}