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