1#[derive(
2 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
3)]
4pub enum RenderTier {
5 Tier1GPU = 0,
7 Tier2GPU = 1,
9 Tier3Fallback = 2,
11}
12use bytemuck::{Pod, Zeroable};
16#[repr(C)]
18#[derive(Copy, Clone, Debug, Pod, Zeroable, serde::Serialize, serde::Deserialize)]
19pub struct ColorTheme {
20 pub primary_neon: [f32; 4], pub shatter_neon: [f32; 4],
22 pub glass_base: [f32; 4],
23 pub glass_edge: [f32; 4],
24 pub rune_glow: [f32; 4],
25 pub ember_core: [f32; 4],
26 pub background_deep: [f32; 4],
27 pub mani_glow: [f32; 4], pub glass_blur_strength: f32,
29 pub shatter_edge_width: f32,
30 pub neon_bloom_radius: f32,
31 pub rune_opacity: f32,
32 pub glass_tint_adapt: f32,
35 pub glass_ior: f32,
37 pub color_space: u32,
39 pub _pad0: f32,
41 pub _pad1: f32,
42 pub _pad2: f32,
43 pub _pad3: f32,
44 pub _pad4: f32,
45}
46const _: () = assert!(
50 std::mem::size_of::<ColorTheme>() == 176,
51 "ColorTheme Rust/WGSL layout mismatch: expected 176 bytes"
52);
53impl ColorTheme {
54 pub fn asgard() -> Self {
56 Self {
57 primary_neon: [0.0, 1.0, 0.95, 1.2],
58 shatter_neon: [1.0, 0.0, 0.75, 1.5],
59 glass_base: [0.04, 0.04, 0.06, 0.82],
60 glass_edge: [0.0, 0.45, 0.55, 0.6],
61 rune_glow: [0.75, 0.98, 1.0, 0.9],
62 ember_core: [0.95, 0.12, 0.12, 1.0],
63 background_deep: [0.01, 0.01, 0.03, 1.0],
64 mani_glow: [0.7, 0.9, 1.0, 0.05],
65 glass_blur_strength: 0.6,
66 shatter_edge_width: 1.8,
67 neon_bloom_radius: 0.022,
68 rune_opacity: 0.55,
69 glass_tint_adapt: 0.35,
70 glass_ior: 1.45,
71 color_space: 0,
72 _pad0: 0.0,
73 _pad1: 0.0,
74 _pad2: 0.0,
75 _pad3: 0.0,
76 _pad4: 0.0,
77 }
78 }
79
80 pub fn midgard() -> Self {
82 Self {
83 primary_neon: [0.2, 0.4, 0.6, 1.0], shatter_neon: [0.5, 0.5, 0.5, 1.0], glass_base: [0.1, 0.12, 0.15, 1.0], glass_edge: [0.3, 0.35, 0.4, 1.0], rune_glow: [0.8, 0.8, 0.8, 0.0], ember_core: [0.5, 0.5, 0.5, 1.0],
89 background_deep: [0.05, 0.05, 0.07, 1.0],
90 mani_glow: [0.0, 0.0, 0.0, 0.0], glass_blur_strength: 0.0, shatter_edge_width: 1.0,
93 neon_bloom_radius: 0.0,
94 rune_opacity: 0.0,
95 glass_tint_adapt: 0.0,
96 glass_ior: 1.0,
97 color_space: 0,
98 _pad0: 0.0,
99 _pad1: 0.0,
100 _pad2: 0.0,
101 _pad3: 0.0,
102 _pad4: 0.0,
103 }
104 }
105
106 pub fn cyberpunk_viking() -> Self {
107 Self::asgard()
108 }
109 pub fn vibrant_glass() -> Self {
110 Self {
111 primary_neon: [0.0, 1.0, 0.95, 1.2],
112 shatter_neon: [1.0, 0.0, 0.75, 1.5],
113 glass_base: [0.55, 0.6, 0.7, 0.08], glass_edge: [0.7, 0.85, 1.0, 0.45], rune_glow: [0.75, 0.98, 1.0, 0.9],
116 ember_core: [1.0, 0.4, 0.1, 1.0],
117 background_deep: [0.05, 0.05, 0.1, 1.0],
118 mani_glow: [0.7, 0.9, 1.0, 0.05],
119 glass_blur_strength: 0.9,
120 shatter_edge_width: 1.8,
121 neon_bloom_radius: 0.022,
122 rune_opacity: 0.55,
123 glass_tint_adapt: 0.65,
124 glass_ior: 1.45,
125 color_space: 0,
126 _pad0: 0.0,
127 _pad1: 0.0,
128 _pad2: 0.0,
129 _pad3: 0.0,
130 _pad4: 0.0,
131 }
132 }
133
134 pub fn berserker() -> Self {
136 Self {
137 primary_neon: [1.0, 0.08, 0.12, 1.1], shatter_neon: [0.95, 0.92, 0.88, 1.0], glass_base: [0.02, 0.01, 0.01, 0.92], glass_edge: [0.7, 0.15, 0.05, 0.55], rune_glow: [0.95, 0.35, 0.1, 0.6], ember_core: [0.98, 0.25, 0.05, 0.8],
143 background_deep: [0.005, 0.002, 0.002, 1.0], mani_glow: [0.8, 0.15, 0.02, 0.03], glass_blur_strength: 0.5, shatter_edge_width: 2.0,
147 neon_bloom_radius: 0.018, rune_opacity: 0.45, glass_tint_adapt: 0.1,
150 glass_ior: 1.5,
151 color_space: 0,
152 _pad0: 0.0,
153 _pad1: 0.0,
154 _pad2: 0.0,
155 _pad3: 0.0,
156 _pad4: 0.0,
157 }
158 }
159}
160impl Default for ColorTheme {
161 fn default() -> Self {
162 Self::berserker()
163 }
164}
165#[repr(C)]
167#[derive(Copy, Clone, Debug, Pod, Zeroable, serde::Serialize, serde::Deserialize)]
168pub struct SceneUniforms {
169 pub view: glam::Mat4,
170 pub proj: glam::Mat4,
171 pub time: f32,
172 pub delta_time: f32,
173 pub resolution: [f32; 2],
174 pub mouse: [f32; 2],
175 pub mouse_velocity: [f32; 2],
176 pub shatter_origin: [f32; 2],
177 pub shatter_time: f32,
178 pub shatter_force: f32,
179 pub berzerker_rage: f32,
180 pub berzerker_mode: u32,
181 pub scroll_offset: f32,
182 pub scale_factor: f32,
183 pub scene_type: u32,
184 pub _pad_vec2_align: [u32; 1], pub fireball_pos: [f32; 2],
186 pub _pad: [f32; 4], }
188
189pub const SCENE_AURORA: u32 = 0;
190pub const SCENE_VOID: u32 = 1;
191pub const SCENE_NEBULA: u32 = 2;
192pub const SCENE_GLITCH: u32 = 3;
193pub const SCENE_YGGDRASIL: u32 = 4;
194
195pub fn resolve_scene_by_name(name: &str) -> Option<u32> {
200 let normalized = name.to_lowercase().replace(['-', '_', ' ', '.'], "");
201 match normalized.as_str() {
202 "aurora" => Some(SCENE_AURORA),
203 "void" | "empty" | "none" | "blank" => Some(SCENE_VOID),
204 "nebula" => Some(SCENE_NEBULA),
205 "glitch" => Some(SCENE_GLITCH),
206 "yggdrasil" | "worldtree" | "tree" => Some(SCENE_YGGDRASIL),
207 _ => None,
208 }
209}
210
211impl SceneUniforms {
212 pub fn new(width: f32, height: f32) -> Self {
213 Self {
214 view: glam::Mat4::IDENTITY,
215 proj: glam::Mat4::orthographic_lh(0.0, width, height, 0.0, -100.0, 100.0),
216 time: 0.0,
217 delta_time: 0.016,
218 resolution: [width, height],
219 mouse: [0.5, 0.5],
220 mouse_velocity: [0.0, 0.0],
221 shatter_origin: [0.5, 0.5],
222 shatter_time: -100.0,
223 shatter_force: 0.0,
224 berzerker_rage: 0.0,
225 berzerker_mode: 0,
226 scroll_offset: 0.0,
227 scale_factor: 1.0,
228 scene_type: SCENE_AURORA,
229 _pad_vec2_align: [0],
230 fireball_pos: [0.0, 0.0],
231 _pad: [0.0; 4],
232 }
233 }
234}