Skip to main content

gizmo_renderer/
web_profile.rs

1/// WASM Optimizasyon Profil Sistemi
2///
3/// Oyun türüne göre otomatik GPU kaynak yönetimi sağlar.
4/// Tarayıcı ortamında maksimum performans için gereksiz
5/// subsistemler otomatik devre dışı bırakılır.
6///
7/// # Kullanım
8/// ```rust,ignore
9/// let profile = WebProfile::fighter(); // Dövüş oyunu preset'i
10/// let profile = WebProfile::racing();  // Yarış oyunu preset'i
11/// let profile = WebProfile::sandbox(); // Açık dünya / sandbox
12/// let profile = WebProfile::custom()   // Özel konfigürasyon
13///     .with_particles(true, 5000)
14///     .with_shadows(true)
15///     .with_post_processing(PostProcessLevel::Medium);
16/// ```
17
18/// Post-processing kalite seviyesi
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub enum PostProcessLevel {
21    /// Sadece tone mapping, gamma correction
22    Minimal,
23    /// Bloom + tone mapping (DoF yok)
24    Low,
25    /// Bloom + chromatic aberration + vignette (DoF yok)
26    Medium,
27    /// Full pipeline (bloom + DoF + film grain + vignette + CA)
28    High,
29}
30
31/// Shadow kalite seviyesi
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum ShadowQuality {
34    /// Gölge yok
35    Off,
36    /// Tek cascade, düşük çözünürlük
37    Low,
38    /// 2 cascade, orta çözünürlük
39    Medium,
40    /// 4 cascade, yüksek çözünürlük (masaüstü varsayılan)
41    High,
42}
43
44/// WASM ortamında GPU kaynak konfigürasyonu
45#[derive(Clone, Debug)]
46pub struct WebProfile {
47    /// Profil adı (log ve debug için)
48    pub name: &'static str,
49
50    // ── GPU Compute Subsystems ────────────────────────────
51    /// GPU particle sistemi aktif mi?
52    pub gpu_particles_enabled: bool,
53    /// Maksimum GPU particle sayısı
54    pub gpu_particles_max: u32,
55
56    /// GPU fizik simülasyonu aktif mi?
57    pub gpu_physics_enabled: bool,
58    /// Maksimum GPU fizik nesnesi
59    pub gpu_physics_max: u32,
60
61    /// GPU sıvı simülasyonu aktif mi?
62    pub gpu_fluid_enabled: bool,
63    /// Maksimum GPU sıvı parçacığı
64    pub gpu_fluid_max: u32,
65
66    // ── Rendering Pipeline ───────────────────────────────
67    /// Deferred rendering aktif mi? (false = forward only)
68    pub deferred_enabled: bool,
69
70    /// GPU frustum culling aktif mi?
71    pub gpu_cull_enabled: bool,
72
73    /// Gölge kalitesi
74    pub shadow_quality: ShadowQuality,
75
76    /// Post-processing seviyesi
77    pub post_process_level: PostProcessLevel,
78
79    // ── Screen Space Effects ─────────────────────────────
80    /// SSAO (Ambient Occlusion) aktif mi?
81    pub ssao_enabled: bool,
82
83    /// SSR (Screen Space Reflections) aktif mi?
84    pub ssr_enabled: bool,
85
86    /// SSGI (Screen Space Global Illumination) aktif mi?
87    pub ssgi_enabled: bool,
88
89    /// TAA (Temporal Anti-Aliasing) aktif mi?
90    pub taa_enabled: bool,
91
92    /// Volumetric lighting (God Rays) aktif mi?
93    pub volumetric_enabled: bool,
94
95    // ── Resource Limits ──────────────────────────────────
96    /// Maksimum bind group sayısı (Chrome WebGPU = 4)
97    pub max_bind_groups: u32,
98
99    /// Maksimum instance sayısı (instanced rendering)
100    pub max_instances: usize,
101
102    /// HDR texture formatı (Rgba16Float vs Rgba8Unorm)
103    pub use_hdr: bool,
104}
105
106impl WebProfile {
107    // ════════════════════════════════════════════════════════
108    //  PRESET'LER — Oyun türüne göre hazır profiller
109    // ════════════════════════════════════════════════════════
110
111    /// 🥊 Dövüş oyunu — 2 karakter, arena, hit efektleri
112    /// Particles: düşük (hit spark), Fluid: kapalı, Deferred: kapalı
113    pub fn fighter() -> Self {
114        Self {
115            name: "Fighter",
116            gpu_particles_enabled: true,
117            gpu_particles_max: 2_000, // Hit spark'lar için yeterli
118            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    /// 🏎️ Yarış oyunu — çok nesne, hız efektleri, geniş sahne
138    /// Particles: orta (toz/kıvılcım), Fluid: kapalı, Shadows: düşük
139    pub fn racing() -> Self {
140        Self {
141            name: "Racing",
142            gpu_particles_enabled: true,
143            gpu_particles_max: 10_000, // Toz, kıvılcım, exhaust
144            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, // CPU culling yeterli
150            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    /// 🌊 Su/sıvı odaklı oyun — SPH fluid, fizik etkileşimi
164    /// Particles: orta, Fluid: aktif (düşük limit), Physics: düşük
165    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, // Mobil/web için 10K yeterli
174            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    /// 🏗️ Sandbox / açık dünya — dengeli, her şeyden biraz
190    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    /// 🖥️ Masaüstü — tüm özellikler açık (varsayılan native profil)
215    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    /// 📱 Minimum — en düşük ayarlar (eski donanım / mobil)
240    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    // ════════════════════════════════════════════════════════
265    //  BUILDER API — Özel profil oluşturma
266    // ════════════════════════════════════════════════════════
267
268    /// Boş profil (her şey kapalı) — builder ile özelleştir
269    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    // ════════════════════════════════════════════════════════
322    //  UTILITY
323    // ════════════════════════════════════════════════════════
324
325    /// Mevcut platforma göre varsayılan profil seç
326    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    /// Profil özetini logla
338    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}