proof-engine 0.2.3

Real-time graphics from math: glyphs and particles moved by ODEs, strange attractors and force fields, drawn with HDR bloom on OpenGL.
Documentation

// ── Motion Blur ───────────────────────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct MotionBlurConfig {
    pub enabled: bool,
    pub shutter_angle: f32,
    pub sample_count: u32,
    pub tile_size: u32,
    pub max_blur_pixels: f32,
    pub motion_scale: f32,
    pub camera_motion_blur: bool,
    pub object_motion_blur: bool,
}

impl MotionBlurConfig {
    pub fn new() -> Self { Self { enabled: false, shutter_angle: 180.0, sample_count: 8, tile_size: 10, max_blur_pixels: 40.0, motion_scale: 1.0, camera_motion_blur: true, object_motion_blur: true } }
    pub fn cinematic() -> Self { Self { enabled: true, shutter_angle: 270.0, sample_count: 16, ..Self::new() } }
    pub fn subtle() -> Self { Self { enabled: true, shutter_angle: 90.0, sample_count: 4, max_blur_pixels: 20.0, ..Self::new() } }
}

impl Default for MotionBlurConfig { fn default() -> Self { Self::new() } }

// ── Vignette ──────────────────────────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct VignetteConfig {
    pub enabled: bool,
    pub intensity: f32,
    pub smoothness: f32,
    pub roundness: f32,
    pub color: [f32; 3],
    pub center: [f32; 2],
    pub mask_texture_id: Option<u32>,
}

impl VignetteConfig {
    pub fn new() -> Self { Self { enabled: true, intensity: 0.45, smoothness: 0.2, roundness: 1.0, color: [0.0; 3], center: [0.5, 0.5], mask_texture_id: None } }
    pub fn subtle() -> Self { Self { intensity: 0.2, ..Self::new() } }
    pub fn dramatic() -> Self { Self { intensity: 0.8, smoothness: 0.4, ..Self::new() } }
    pub fn colored(r: f32, g: f32, b: f32) -> Self { Self { color: [r, g, b], ..Self::new() } }
    pub fn disabled() -> Self { Self { enabled: false, ..Self::new() } }
}

impl Default for VignetteConfig { fn default() -> Self { Self::new() } }

// ── Chromatic Aberration ──────────────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct ChromaticAberrationConfig {
    pub enabled: bool,
    pub intensity: f32,
    pub radial: bool,
    pub offset_r: [f32; 2],
    pub offset_g: [f32; 2],
    pub offset_b: [f32; 2],
    pub sample_count: u32,
}

impl ChromaticAberrationConfig {
    pub fn new() -> Self { Self { enabled: false, intensity: 0.5, radial: true, offset_r: [-0.01, 0.0], offset_g: [0.0, 0.0], offset_b: [0.01, 0.0], sample_count: 3 } }
    pub fn subtle() -> Self { Self { enabled: true, intensity: 0.2, ..Self::new() } }
    pub fn strong() -> Self { Self { enabled: true, intensity: 1.5, sample_count: 5, ..Self::new() } }
}

impl Default for ChromaticAberrationConfig { fn default() -> Self { Self::new() } }

// ── Film Grain ────────────────────────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct FilmGrainConfig {
    pub enabled: bool,
    pub intensity: f32,
    pub size: f32,
    pub luminance_contribution: f32,
    pub color: bool,
    pub animated: bool,
}

impl FilmGrainConfig {
    pub fn new() -> Self { Self { enabled: false, intensity: 0.1, size: 1.5, luminance_contribution: 0.8, color: false, animated: true } }
    pub fn subtle() -> Self { Self { enabled: true, intensity: 0.05, ..Self::new() } }
    pub fn heavy() -> Self { Self { enabled: true, intensity: 0.4, ..Self::new() } }
}

impl Default for FilmGrainConfig { fn default() -> Self { Self::new() } }

// ── Anti-Aliasing Config ──────────────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct AntiAliasingConfig {
    pub mode: AntiAliasingMode,
    pub msaa_samples: u32,
    pub fxaa: bool,
    pub taa: Option<TaaConfig>,
    pub smaa_quality: u32,
}

#[derive(Clone, Debug, PartialEq)]
pub enum AntiAliasingMode { None, Msaa, Fxaa, Taa, Smaa, Dlss }

impl AntiAliasingConfig {
    pub fn none() -> Self { Self { mode: AntiAliasingMode::None, msaa_samples: 1, fxaa: false, taa: None, smaa_quality: 0 } }
    pub fn fxaa() -> Self { Self { mode: AntiAliasingMode::Fxaa, fxaa: true, ..Self::none() } }
    pub fn taa() -> Self { Self { mode: AntiAliasingMode::Taa, taa: Some(TaaConfig::new()), ..Self::none() } }
    pub fn msaa(samples: u32) -> Self { Self { mode: AntiAliasingMode::Msaa, msaa_samples: samples, ..Self::none() } }
    pub fn smaa(quality: u32) -> Self { Self { mode: AntiAliasingMode::Smaa, smaa_quality: quality, ..Self::none() } }
    pub fn is_temporal(&self) -> bool { self.mode == AntiAliasingMode::Taa || self.mode == AntiAliasingMode::Dlss }
    pub fn requires_velocity_buffer(&self) -> bool { self.is_temporal() }
}

impl Default for AntiAliasingConfig { fn default() -> Self { Self::fxaa() } }

// ── Extended post process config ──────────────────────────────────────────────

#[derive(Clone, Debug, Default)]
pub struct ExtendedPostProcessConfig {
    pub motion_blur: MotionBlurConfig,
    pub vignette: VignetteConfig,
    pub chromatic_aberration: ChromaticAberrationConfig,
    pub film_grain: FilmGrainConfig,
    pub anti_aliasing: AntiAliasingConfig,
}

impl ExtendedPostProcessConfig {
    pub fn new() -> Self { Self::default() }
    pub fn cinematic() -> Self {
        Self { motion_blur: MotionBlurConfig::cinematic(), vignette: VignetteConfig::dramatic(), chromatic_aberration: ChromaticAberrationConfig::subtle(), film_grain: FilmGrainConfig::subtle(), anti_aliasing: AntiAliasingConfig::taa() }
    }
    pub fn game() -> Self {
        Self { motion_blur: MotionBlurConfig::subtle(), vignette: VignetteConfig::subtle(), anti_aliasing: AntiAliasingConfig::fxaa(), ..Self::new() }
    }
    pub fn count_active(&self) -> usize {
        [self.motion_blur.enabled, self.vignette.enabled, self.chromatic_aberration.enabled, self.film_grain.enabled].iter().filter(|&&b| b).count()
    }
}

// ── GPU Program Lifecycle ─────────────────────────────────────────────────────

#[derive(Clone, Debug, PartialEq)]
pub enum GpuProgramState { Uncompiled, Compiling, Compiled, Failed, Stale }

#[derive(Clone, Debug)]
pub struct GpuProgramLifecycle {
    pub program_id: u32,
    pub state: GpuProgramState,
    pub compile_attempts: u32,
    pub last_success: Option<u64>,
    pub last_failure: Option<u64>,
    pub auto_retry: bool,
    pub max_retries: u32,
}

impl GpuProgramLifecycle {
    pub fn new(program_id: u32) -> Self { Self { program_id, state: GpuProgramState::Uncompiled, compile_attempts: 0, last_success: None, last_failure: None, auto_retry: true, max_retries: 3 } }
    pub fn begin_compile(&mut self) { self.state = GpuProgramState::Compiling; self.compile_attempts += 1; }
    pub fn mark_success(&mut self, ts: u64) { self.state = GpuProgramState::Compiled; self.last_success = Some(ts); }
    pub fn mark_failure(&mut self, ts: u64) { self.state = GpuProgramState::Failed; self.last_failure = Some(ts); }
    pub fn mark_stale(&mut self) { self.state = GpuProgramState::Stale; }
    pub fn can_retry(&self) -> bool { self.auto_retry && self.compile_attempts < self.max_retries }
    pub fn is_compiled(&self) -> bool { self.state == GpuProgramState::Compiled }
    pub fn is_failed(&self) -> bool { self.state == GpuProgramState::Failed }
}

// ── Final system constants ────────────────────────────────────────────────────

pub const MOTION_BLUR_MAX_SAMPLES: u32 = 32;
pub const FILM_GRAIN_MAX_SIZE: f32 = 10.0;
pub const VIGNETTE_MAX_INTENSITY: f32 = 1.0;
pub const CHROMATIC_MAX_OFFSET: f32 = 0.1;
pub const AA_MSAA_MAX_SAMPLES: u32 = 8;
pub const SHADER_GPU_PROGRAM_MAX_RETRIES: u32 = 3;
pub const RENDER_EXTENDED_PP_EFFECT_COUNT: usize = 5;

pub fn anti_aliasing_name(mode: &AntiAliasingMode) -> &'static str {
    match mode { AntiAliasingMode::None => "None", AntiAliasingMode::Msaa => "MSAA", AntiAliasingMode::Fxaa => "FXAA", AntiAliasingMode::Taa => "TAA", AntiAliasingMode::Smaa => "SMAA", AntiAliasingMode::Dlss => "DLSS" }
}
pub fn gpu_program_state_name(s: &GpuProgramState) -> &'static str {
    match s { GpuProgramState::Uncompiled => "Uncompiled", GpuProgramState::Compiling => "Compiling", GpuProgramState::Compiled => "Compiled", GpuProgramState::Failed => "Failed", GpuProgramState::Stale => "Stale" }
}
pub fn shader_editor_complete_version() -> String { format!("ShaderCompilerEditor — complete build, v{}", shader_system_version()) }