minitracing/src/scene.rs
numzero c1b3e862d6 Remove load_envmap
Maybe I’ll need it later though...
2025-03-29 00:06:20 +03:00

131 lines
2.8 KiB
Rust

use crate::anim::{self, SphereParams};
use crate::trace::{self, Tracer, TracerData};
use glam::{mat3, uvec2, vec3, UVec2, Vec3};
use std::f32::consts::PI;
struct CamLoc {
eye: Vec3,
forward: Vec3,
right: Vec3,
}
fn make_viewport(w: u32, h: u32) -> trace::Viewport {
let size = uvec2(w, h).as_vec2();
let size = size.normalize();
trace::Viewport {
corner: vec3(size.x, size.y, 1.),
}
}
fn convert_location(cam: CamLoc) -> trace::CameraLocation {
let fwd = cam.forward.normalize();
let up = cam.right.cross(fwd).normalize();
let right = up.cross(fwd).normalize();
trace::CameraLocation {
eye: cam.eye,
view: mat3(right, up, fwd),
}
}
const N_SPHERES: u32 = 100;
const CAMERA_LAG: f32 = 0.03;
pub struct Renderer {
tracer: Tracer,
}
impl Renderer {
pub fn new(device: &wgpu::Device) -> Self {
let hdr_format = wgpu::TextureFormat::Rgba16Float;
let tracer = Tracer::new(&device, hdr_format);
Self { tracer }
}
}
pub struct SceneParams {
pub spheres: Vec<SphereParams>,
pub camera: SphereParams,
pub target: SphereParams,
}
impl SceneParams {
pub fn new(n_spheres: u32) -> Self {
let mut rng = rand_pcg::Pcg32::new(42, 0);
let spheres: Vec<_> = {
let distr = anim::distr();
(0..n_spheres).map(|_| distr(&mut rng)).collect()
};
let camera = {
let mut p = anim::distr()(&mut rng);
p.amplitudes *= 2.0;
p.frequencies *= 0.1;
p
};
let target = {
let mut p = spheres[0];
p.phases -= 2. * PI * CAMERA_LAG * p.frequencies;
p
};
Self {
spheres,
camera,
target,
}
}
}
impl Default for SceneParams {
fn default() -> Self {
Self::new(N_SPHERES)
}
}
pub struct RenderPass<'encoder>(wgpu::RenderPass<'encoder>);
impl Renderer {
pub fn prepare<'encoder>(
&self,
encoder: &'encoder mut wgpu::CommandEncoder,
target: &wgpu::TextureView,
) -> RenderPass<'encoder> {
RenderPass(self.tracer.prepare(encoder, target))
}
pub fn render_frame(
&self,
device: &wgpu::Device,
render_pass: &mut RenderPass,
size: UVec2,
scene: &SceneParams,
time: f32,
seed: u32,
) {
let target = scene.target.to_sphere(time).center;
let eye = scene.camera.to_sphere(time).center;
let right = scene.camera.deriv(time);
let forward = target - eye;
let viewport = make_viewport(size.x, size.y);
let location = convert_location(CamLoc { eye, forward, right });
let spheres: Vec<_> = scene.spheres.iter().map(|p| p.to_sphere(time)).collect();
let data = TracerData::new(&device, &self.tracer, &spheres);
self.tracer.render(
&mut render_pass.0,
&data,
trace::Params {
max_reflections: 3,
min_strength: 0.1,
sphere_count: N_SPHERES,
seed,
},
viewport,
trace::Aperture {
radius: 0.0003,
focal_distance: std::f32::INFINITY,
glare_strength: 0.1,
glare_radius: 0.1,
},
location,
);
}
}