use std::collections::{BTreeMap, HashMap};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BounceLimit {
Unlimited,
Limited(u32),
}
impl Default for BounceLimit {
fn default() -> Self {
Self::Limited(4)
}
}
#[derive(Debug, Clone)]
pub struct RayTracerConfig {
pub max_bounces: BounceLimit,
pub samples_per_pixel: u32,
pub enable_denoising: bool,
pub enable_global_illumination: bool,
}
impl Default for RayTracerConfig {
fn default() -> Self {
Self {
max_bounces: BounceLimit::Limited(4),
samples_per_pixel: 1,
enable_denoising: true,
enable_global_illumination: false,
}
}
}
pub struct RayTracer {
config: RayTracerConfig,
accumulated_frames: u64,
}
impl RayTracer {
pub fn new(config: RayTracerConfig) -> Result<Self, RayTracerError> {
Ok(Self {
config,
accumulated_frames: 0,
})
}
pub fn max_bounces(&self) -> u32 {
match self.config.max_bounces {
BounceLimit::Unlimited => u32::MAX,
BounceLimit::Limited(n) => n,
}
}
pub fn denoising_enabled(&self) -> bool {
self.config.enable_denoising
}
pub fn global_illumination_enabled(&self) -> bool {
self.config.enable_global_illumination
}
pub fn samples_per_pixel(&self) -> u32 {
self.config.samples_per_pixel
}
pub fn trace_ray(&self, origin: [f32; 3], direction: [f32; 3]) -> RayHit {
RayHit {
hit: true,
distance: 1.0,
position: [
origin[0] + direction[0],
origin[1] + direction[1],
origin[2] + direction[2],
],
normal: [0.0, 1.0, 0.0],
color: [1.0, 1.0, 1.0, 1.0],
}
}
pub fn render(
&mut self,
width: u32,
height: u32,
) -> Result<Vec<[f32; 4]>, RayTracerError> {
self.accumulated_frames += 1;
let pixel_count: _ = (width * height) as usize;
Ok(vec![[0.5, 0.5, 0.5, 1.0]; pixel_count])
}
pub fn reset_accumulation(&mut self) {
self.accumulated_frames = 0;
}
}
#[derive(Debug, Clone)]
pub struct RayHit {
pub hit: bool,
pub distance: f32,
pub position: [f32; 3],
pub normal: [f32; 3],
pub color: [f32; 4],
}
#[derive(Debug, Clone)]
pub enum RayTracerError {
InitializationFailed(String),
RenderFailed(String),
GpuNotSupported,
}
impl std::fmt::Display for RayTracerError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::InitializationFailed(msg) => write!(f, "光线追踪初始化失败: {}", msg),
Self::RenderFailed(msg) => write!(f, "渲染失败: {}", msg),
Self::GpuNotSupported => write!(f, "GPU 不支持光线追踪"),
}
}
}
impl std::error::Error for RayTracerError {}