From db48a786ac8c033c6d6d4b4f9cf65dac03ecefa8 Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 30 Dec 2024 03:02:04 +0300 Subject: [PATCH] Move camera! --- src/bin/minitracer/main.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/bin/minitracer/main.rs b/src/bin/minitracer/main.rs index 8bc2d86..9ae0074 100644 --- a/src/bin/minitracer/main.rs +++ b/src/bin/minitracer/main.rs @@ -1,6 +1,6 @@ use std::error::Error; -use glam::{uvec2, vec2, vec3}; +use glam::{mat3, uvec2, vec2, vec3, Vec3}; use image::ImageReader; use present::Presenter; use trace::{Tracer, TracerData, TracerEnv, Vertex}; @@ -16,17 +16,22 @@ mod trace; pub use trace::Sphere; -fn make_viewport(w: u32, h: u32) -> [Vertex; 4] { +fn make_viewport(eye: Vec3, w: u32, h: u32) -> [Vertex; 4] { let size = uvec2(w, h).as_vec2(); let size = size.normalize(); - let (w, h) = (size.x, size.y); - let r = 1.0f32; + let (w, h, d) = (size.x, size.y, 1.); let screen_coord = [vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)]; - let eye = vec3(-r, 0., 0.); - let world_coord = [vec3(0., -w, -h), vec3(0., w, -h), vec3(0., -w, h), vec3(0., w, h)]; + + let up = Vec3::Z; + let fwd = -eye.normalize(); + let right = eye.cross(up).normalize(); + let up = eye.cross(right).normalize(); + let m = mat3(fwd, right, up); + + let world_coord = [vec3(d, -w, -h), vec3(d, w, -h), vec3(d, -w, h), vec3(d, w, h)]; [0, 1, 2, 3].map(|k| Vertex { eye, - world: world_coord[k], + world: eye + m * (world_coord[k]), screen: screen_coord[k], }) } @@ -49,11 +54,16 @@ fn main() { let output_format = wgpu::TextureFormat::Bgra8UnormSrgb; let hdr_format = wgpu::TextureFormat::Rgba16Float; let mut tracer = Tracer::new(&device, hdr_format); + let mut rng = rand_pcg::Pcg32::new(42, 0); let sphere_params: Vec<_> = { - let mut rng = rand_pcg::Pcg32::new(42, 0); let distr = anim::distr(); (0..N_SPHERES).map(|_| distr(&mut rng)).collect() }; + let camera_params = { + let mut p = anim::distr()(&mut rng); + p.frequencies *= 0.1; + p + }; let tracer_env = TracerEnv::new(&device, &tracer, &envmap); let presenter = Presenter::new(&device, output_format); @@ -80,7 +90,6 @@ fn main() { desired_maximum_frame_latency: 2, }, ); - tracer.set_view(&queue, &make_viewport(physical_size.width, physical_size.height)); surface_configured = true; } WindowEvent::RedrawRequested => { @@ -122,6 +131,8 @@ fn main() { for _ in 0..RAYS_PER_PIXEL { frame += 1; let time = frame as f32 / (60. * RAYS_PER_PIXEL as f32); + let camera_pos = camera_params.to_sphere(time).center; + tracer.set_view(&queue, &make_viewport(camera_pos, size.width, size.height)); let spheres: Vec<_> = sphere_params.iter().map(|p| p.to_sphere(time)).collect(); let data = TracerData::new(&device, &tracer, &spheres); tracer.render(