cranpose_ui_graphics/
gradient_blur.rs1use crate::{RenderEffect, RuntimeShader, SubstrateSpec};
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 = runtime_shader_wgsl!("gradient_blur.wgsl");
33
34pub const GRADIENT_BLUR_LEVELS: [f32; 3] = [1.0, 0.5, 0.25];
38
39pub fn gradient_blur_effect(
48 start_radius_px: f32,
49 end_radius_px: f32,
50 direction: GradientBlurDirection,
51) -> RenderEffect {
52 let start_radius_px = start_radius_px.max(0.0);
53 let end_radius_px = end_radius_px.max(0.0);
54 let mut shader = RuntimeShader::new(GRADIENT_BLUR_WGSL);
55 shader.set_position_independent(true);
56 shader.set_float(0, start_radius_px);
57 shader.set_float(1, end_radius_px);
58 shader.set_float(2, direction.uniform_code());
59 let wide_radius_px = start_radius_px.max(end_radius_px);
60 shader.set_input_padding(wide_radius_px.ceil());
61 shader.set_batched_source(true);
62 shader.set_substrates(&GRADIENT_BLUR_LEVELS.map(|level| SubstrateSpec::Blur {
63 radius_px: wide_radius_px * level,
64 }));
65 RenderEffect::runtime_shader(shader)
66}
67
68#[cfg(test)]
69#[path = "tests/gradient_blur_tests.rs"]
70mod tests;