figments_sample_shaders/
lib.rs1#![no_std]
2use figments::prelude::*;
3use figments::liber8tion::trig::*;
4use figments::liber8tion::noise::*;
5use core::cmp::max;
6use rgb::*;
7
8#[cfg(feature="micromath")]
9use micromath::F32Ext;
10
11#[derive(Default, Debug)]
12pub struct FrameNumber(pub usize);
13
14#[derive(Default, Debug)]
15pub struct RgbWaves {}
16
17impl<Space: CoordinateSpace<Data = usize>> Shader<FrameNumber, Space, Rgb<u8>> for RgbWaves {
18 fn draw(&self, coords: &Coordinates<Space>, frame: &FrameNumber) -> Rgb<u8> {
19 let offset_x = coords.x.wrapping_add(frame.0 / 30);
21 Rgb::new(
23 offset_x.wrapping_mul(3).wrapping_add(frame.0).sin8().to_raw().wrapping_add(coords.y as u8),
24 offset_x.wrapping_mul(5).wrapping_sub(frame.0).cos8().to_raw().wrapping_add(coords.y as u8),
25 offset_x.wrapping_mul(2).wrapping_add(frame.0).sin8().to_raw().wrapping_add(coords.y as u8)
26 )
27 }
28}
29
30
31#[derive(Default, Debug)]
32pub struct Thinking {}
33
34impl<Space: CoordinateSpace<Data = usize>> Shader<FrameNumber, Space, Rgb<u8>> for Thinking {
35 fn draw(&self, coords: &Coordinates<Space>, uniforms: &FrameNumber) -> Rgb<u8> {
36 let offset_x = uniforms.0.wrapping_add(coords.x).sin8().to_raw();
39 let offset_y = uniforms.0.wrapping_add(coords.y).cos8().to_raw();
40 let noise_x = offset_x / 2;
41 let noise_y = offset_y / 2;
42 Hsv::new(
45 inoise8(offset_x as i16, offset_y as i16).to_raw(),
46 128_u8.saturating_add(inoise8(noise_y.into(), noise_x.into()).to_raw()),
47 255
48 ).into()
49 }
50}
51
52#[derive(Default, Debug)]
53pub struct ColorGlow {
54 pub color: Hsv
55}
56
57impl<Space: CoordinateSpace<Data = usize>, Pixel> Shader<FrameNumber, Space, Pixel> for ColorGlow where Hsv: Into<Pixel> {
58 fn draw(&self, coords: &Coordinates<Space>, uniforms: &FrameNumber) -> Pixel {
59 let noise_y = uniforms.0.sin8().to_raw();
60 let noise_x = uniforms.0.cos8().to_raw();
61
62 let brightness = inoise8((noise_x.wrapping_add(coords.x as u8)).into(), (noise_y.wrapping_add(coords.y as u8)).into());
63
64 let saturation_min = self.color.saturation.saturating_sub(15);
66 let saturation_shift = 30u8 * inoise8((noise_y.wrapping_add(coords.y as u8)).into(), (noise_x.wrapping_add(coords.x as u8)).into());
67 let saturation = saturation_min.saturating_add(saturation_shift);
68
69 Hsv::new(self.color.hue.wrapping_add(16u8 * uniforms.0.sin8()).wrapping_sub(8), saturation, brightness.to_raw()).into()
70 }
71}
72
73#[derive(Default, Debug)]
74pub struct RainbowSpiralShader {}
75impl Shader<FrameNumber, Virtual, Rgba<u8>> for RainbowSpiralShader {
76 fn draw(&self, coords: &VirtualCoordinates, uniforms: &FrameNumber) -> Rgba<u8> {
77 let distance = (128f32 - coords.y as f32).hypot(128f32 - coords.x as f32);
78 let angle = (((128f32 - coords.y as f32).atan2(128f32 - coords.x as f32)) * 255f32) as u8;
79 let pixel_value = angle.wrapping_add((uniforms.0 % 255) as u8).wrapping_add(distance as u8);
80
81 Rgba::new(pixel_value.sin8().to_raw(), pixel_value.wrapping_add(64).sin8().to_raw(), pixel_value.wrapping_add(128).sin8().to_raw(), 255)
82 }
83}
84
85#[derive(Default, Debug)]
86pub struct Chimes {}
87impl<Space: CoordinateSpace<Data = usize>, Pixel> Shader<FrameNumber, Space, Pixel> for Chimes where Hsv: Into<Pixel> {
88 fn draw(&self, surface_coords: &Coordinates<Space>, uniforms: &FrameNumber) -> Pixel {
89 const CHIME_LENGTH: usize = 8;
90
91 let animation_frame = uniforms.0 / 5;
92 let local_x = surface_coords.x.wrapping_add(animation_frame / 300);
93
94 let chime_idx = (local_x / CHIME_LENGTH) % 32;
95 let chime_pos = local_x % CHIME_LENGTH;
96
97 let brightness = (animation_frame.wrapping_mul(chime_idx + 1) / 3).sin8();
98 let saturation = (chime_pos.wrapping_add(animation_frame / 3)).sin8();
99 let hue = chime_idx.wrapping_add(animation_frame / 30) as u8;
100
101 Hsv::new(
102 hue,
103 saturation.to_raw(),
104 brightness.to_raw()
105 ).into()
106 }
107}
108
109#[derive(Default, Debug)]
110pub struct Flashlight {}
111
112impl<Pixel, Space: CoordinateSpace<Data = usize>> Shader<FrameNumber, Space, Pixel> for Flashlight where Hsv: Into<Pixel> {
113 fn draw(&self, coords: &Coordinates<Space>, uniforms: &FrameNumber) -> Pixel {
114 let noise_y = uniforms.0.sin8().to_raw();
115 let noise_x = uniforms.0.cos8().to_raw();
116
117 let brightness = inoise8((noise_x.wrapping_add(coords.x as u8)).into(), (noise_y.wrapping_add(coords.y as u8)).into());
118 let saturation = inoise8((noise_y.wrapping_add(coords.y as u8)).into(), (noise_x.wrapping_add(coords.x as u8)).into());
119 let hue = 16u8 * uniforms.0.sin8();
120
121 Hsv::new(hue, max(128, saturation.to_raw()), brightness.to_raw()).into()
122 }
123}