1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub enum PostProcessLevel {
21 Minimal,
23 Low,
25 Medium,
27 High,
29}
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum ShadowQuality {
34 Off,
36 Low,
38 Medium,
40 High,
42}
43
44#[derive(Clone, Debug)]
46pub struct WebProfile {
47 pub name: &'static str,
49
50 pub gpu_particles_enabled: bool,
53 pub gpu_particles_max: u32,
55
56 pub gpu_physics_enabled: bool,
58 pub gpu_physics_max: u32,
60
61 pub gpu_fluid_enabled: bool,
63 pub gpu_fluid_max: u32,
65
66 pub deferred_enabled: bool,
69
70 pub gpu_cull_enabled: bool,
72
73 pub shadow_quality: ShadowQuality,
75
76 pub post_process_level: PostProcessLevel,
78
79 pub ssao_enabled: bool,
82
83 pub ssr_enabled: bool,
85
86 pub ssgi_enabled: bool,
88
89 pub taa_enabled: bool,
91
92 pub volumetric_enabled: bool,
94
95 pub max_bind_groups: u32,
98
99 pub max_instances: usize,
101
102 pub use_hdr: bool,
104}
105
106impl WebProfile {
107 pub fn fighter() -> Self {
114 Self {
115 name: "Fighter",
116 gpu_particles_enabled: true,
117 gpu_particles_max: 2_000, gpu_physics_enabled: false,
119 gpu_physics_max: 0,
120 gpu_fluid_enabled: false,
121 gpu_fluid_max: 0,
122 deferred_enabled: false,
123 gpu_cull_enabled: false,
124 shadow_quality: ShadowQuality::Off,
125 post_process_level: PostProcessLevel::Medium,
126 ssao_enabled: false,
127 ssr_enabled: false,
128 ssgi_enabled: false,
129 taa_enabled: false,
130 volumetric_enabled: false,
131 max_bind_groups: 4,
132 max_instances: 256,
133 use_hdr: true,
134 }
135 }
136
137 pub fn racing() -> Self {
140 Self {
141 name: "Racing",
142 gpu_particles_enabled: true,
143 gpu_particles_max: 10_000, gpu_physics_enabled: false,
145 gpu_physics_max: 0,
146 gpu_fluid_enabled: false,
147 gpu_fluid_max: 0,
148 deferred_enabled: false,
149 gpu_cull_enabled: false, shadow_quality: ShadowQuality::Low,
151 post_process_level: PostProcessLevel::Medium,
152 ssao_enabled: false,
153 ssr_enabled: false,
154 ssgi_enabled: false,
155 taa_enabled: false,
156 volumetric_enabled: false,
157 max_bind_groups: 4,
158 max_instances: 512,
159 use_hdr: true,
160 }
161 }
162
163 pub fn fluid() -> Self {
166 Self {
167 name: "Fluid",
168 gpu_particles_enabled: true,
169 gpu_particles_max: 5_000,
170 gpu_physics_enabled: true,
171 gpu_physics_max: 1_000,
172 gpu_fluid_enabled: true,
173 gpu_fluid_max: 10_000, deferred_enabled: false,
175 gpu_cull_enabled: false,
176 shadow_quality: ShadowQuality::Off,
177 post_process_level: PostProcessLevel::Low,
178 ssao_enabled: false,
179 ssr_enabled: false,
180 ssgi_enabled: false,
181 taa_enabled: false,
182 volumetric_enabled: false,
183 max_bind_groups: 4,
184 max_instances: 128,
185 use_hdr: true,
186 }
187 }
188
189 pub fn sandbox() -> Self {
191 Self {
192 name: "Sandbox",
193 gpu_particles_enabled: true,
194 gpu_particles_max: 5_000,
195 gpu_physics_enabled: true,
196 gpu_physics_max: 5_000,
197 gpu_fluid_enabled: false,
198 gpu_fluid_max: 0,
199 deferred_enabled: false,
200 gpu_cull_enabled: false,
201 shadow_quality: ShadowQuality::Low,
202 post_process_level: PostProcessLevel::Low,
203 ssao_enabled: false,
204 ssr_enabled: false,
205 ssgi_enabled: false,
206 taa_enabled: false,
207 volumetric_enabled: false,
208 max_bind_groups: 4,
209 max_instances: 1024,
210 use_hdr: true,
211 }
212 }
213
214 pub fn desktop() -> Self {
216 Self {
217 name: "Desktop",
218 gpu_particles_enabled: true,
219 gpu_particles_max: 100_000,
220 gpu_physics_enabled: true,
221 gpu_physics_max: 50_000,
222 gpu_fluid_enabled: true,
223 gpu_fluid_max: 100_000,
224 deferred_enabled: true,
225 gpu_cull_enabled: true,
226 shadow_quality: ShadowQuality::High,
227 post_process_level: PostProcessLevel::High,
228 ssao_enabled: true,
229 ssr_enabled: true,
230 ssgi_enabled: true,
231 taa_enabled: true,
232 volumetric_enabled: true,
233 max_bind_groups: 8,
234 max_instances: 16384,
235 use_hdr: true,
236 }
237 }
238
239 pub fn minimal() -> Self {
241 Self {
242 name: "Minimal",
243 gpu_particles_enabled: false,
244 gpu_particles_max: 0,
245 gpu_physics_enabled: false,
246 gpu_physics_max: 0,
247 gpu_fluid_enabled: false,
248 gpu_fluid_max: 0,
249 deferred_enabled: false,
250 gpu_cull_enabled: false,
251 shadow_quality: ShadowQuality::Off,
252 post_process_level: PostProcessLevel::Minimal,
253 ssao_enabled: false,
254 ssr_enabled: false,
255 ssgi_enabled: false,
256 taa_enabled: false,
257 volumetric_enabled: false,
258 max_bind_groups: 4,
259 max_instances: 64,
260 use_hdr: false,
261 }
262 }
263
264 pub fn custom() -> Self {
270 Self::minimal()
271 }
272
273 pub fn with_particles(mut self, enabled: bool, max: u32) -> Self {
274 self.gpu_particles_enabled = enabled;
275 self.gpu_particles_max = max;
276 self
277 }
278
279 pub fn with_physics(mut self, enabled: bool, max: u32) -> Self {
280 self.gpu_physics_enabled = enabled;
281 self.gpu_physics_max = max;
282 self
283 }
284
285 pub fn with_fluid(mut self, enabled: bool, max: u32) -> Self {
286 self.gpu_fluid_enabled = enabled;
287 self.gpu_fluid_max = max;
288 self
289 }
290
291 pub fn with_shadows(mut self, quality: ShadowQuality) -> Self {
292 self.shadow_quality = quality;
293 self
294 }
295
296 pub fn with_post_processing(mut self, level: PostProcessLevel) -> Self {
297 self.post_process_level = level;
298 self
299 }
300
301 pub fn with_deferred(mut self, enabled: bool) -> Self {
302 self.deferred_enabled = enabled;
303 self
304 }
305
306 pub fn with_ssao(mut self, enabled: bool) -> Self {
307 self.ssao_enabled = enabled;
308 self
309 }
310
311 pub fn with_ssr(mut self, enabled: bool) -> Self {
312 self.ssr_enabled = enabled;
313 self
314 }
315
316 pub fn with_max_instances(mut self, max: usize) -> Self {
317 self.max_instances = max;
318 self
319 }
320
321 pub fn auto() -> Self {
327 #[cfg(target_arch = "wasm32")]
328 {
329 Self::fighter()
330 }
331 #[cfg(not(target_arch = "wasm32"))]
332 {
333 Self::desktop()
334 }
335 }
336
337 pub fn log_summary(&self) {
339 log::info!("╔══════════════════════════════════════════╗");
340 log::info!("║ WebProfile: {:26} ║", self.name);
341 log::info!("╠══════════════════════════════════════════╣");
342 log::info!(
343 "║ Particles: {:>6} ({}) ║",
344 if self.gpu_particles_enabled {
345 format!("{}", self.gpu_particles_max)
346 } else {
347 "OFF".to_string()
348 },
349 if self.gpu_particles_enabled {
350 "✓"
351 } else {
352 "✗"
353 }
354 );
355 log::info!(
356 "║ Physics: {:>6} ({}) ║",
357 if self.gpu_physics_enabled {
358 format!("{}", self.gpu_physics_max)
359 } else {
360 "OFF".to_string()
361 },
362 if self.gpu_physics_enabled {
363 "✓"
364 } else {
365 "✗"
366 }
367 );
368 log::info!(
369 "║ Fluid: {:>6} ({}) ║",
370 if self.gpu_fluid_enabled {
371 format!("{}", self.gpu_fluid_max)
372 } else {
373 "OFF".to_string()
374 },
375 if self.gpu_fluid_enabled { "✓" } else { "✗" }
376 );
377 log::info!("║ Shadows: {:?}{:>16} ║", self.shadow_quality, "");
378 log::info!("║ PostFX: {:?}{:>16} ║", self.post_process_level, "");
379 log::info!(
380 "║ Deferred: {:<24} ║",
381 if self.deferred_enabled { "✓" } else { "✗" }
382 );
383 log::info!(
384 "║ SSAO: {:<24} ║",
385 if self.ssao_enabled { "✓" } else { "✗" }
386 );
387 log::info!("║ Instances: {:<24} ║", self.max_instances);
388 log::info!("╚══════════════════════════════════════════╝");
389 }
390}
391
392impl Default for WebProfile {
393 fn default() -> Self {
394 Self::auto()
395 }
396}