From 96b5ac2200457ad7f2edef466ff58b6fcc02b4ff Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 30 Dec 2024 16:46:25 +0300 Subject: [PATCH] Split camera location and viewport --- src/bin/minitracer/main.rs | 25 +++++++++++++++---------- src/bin/minitracer/trace.rs | 20 +++++++++++++------- src/bin/minitracer/trace.wgsl | 8 ++++++-- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/bin/minitracer/main.rs b/src/bin/minitracer/main.rs index 83c9c87..f6780a3 100644 --- a/src/bin/minitracer/main.rs +++ b/src/bin/minitracer/main.rs @@ -1,6 +1,6 @@ use std::error::Error; -use glam::{mat3, uvec2, Vec3}; +use glam::{mat3, uvec2, vec3, Vec3}; use image::ImageReader; use present::Presenter; use trace::{Tracer, TracerData, TracerEnv}; @@ -22,18 +22,21 @@ struct CamLoc { right: Vec3, } -fn make_viewport(cam: CamLoc, w: u32, h: u32) -> trace::CameraLocation { +fn make_viewport(w: u32, h: u32) -> trace::Viewport { let size = uvec2(w, h).as_vec2(); let size = size.normalize(); - let (w, h, d) = (size.x, size.y, 1.); - - let fwd = d * cam.forward.normalize(); - let up = h * cam.right.cross(fwd).normalize(); - let right = w * up.cross(fwd).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(fwd, right, up), + view: mat3(right, up, fwd), } } @@ -143,7 +146,8 @@ fn main() { let eye = camera_params.to_sphere(time).center; let right = camera_params.deriv(time); let forward = target_params.to_sphere(time).center - eye; - let view = make_viewport(CamLoc { eye, forward, right }, size.width, size.height); + let viewport = make_viewport(size.width, size.height); + let location = convert_location(CamLoc { eye, forward, right }); let spheres: Vec<_> = sphere_params.iter().map(|p| p.to_sphere(time)).collect(); let data = TracerData::new(&device, &tracer, &spheres); tracer.render( @@ -156,7 +160,8 @@ fn main() { sphere_count: N_SPHERES, seed: frame, }, - view, + viewport, + location, ); } } diff --git a/src/bin/minitracer/trace.rs b/src/bin/minitracer/trace.rs index 9eef951..f19deab 100644 --- a/src/bin/minitracer/trace.rs +++ b/src/bin/minitracer/trace.rs @@ -13,6 +13,11 @@ pub struct Params { pub seed: u32, } +#[derive(Debug, Clone, Copy)] +pub struct Viewport { + pub corner: Vec3, +} + #[derive(Debug, Clone, Copy)] pub struct CameraLocation { pub eye: Vec3, @@ -39,13 +44,13 @@ struct CameraData { pad4: f32, } -impl From for CameraData { - fn from(value: CameraLocation) -> Self { +impl From<(Viewport, CameraLocation)> for CameraData { + fn from(value: (Viewport, CameraLocation)) -> Self { CameraData { - u: value.view.x_axis, - v: value.view.y_axis, - w: value.view.z_axis, - eye: value.eye, + u: value.0.corner.x * value.1.view.x_axis, + v: value.0.corner.y * value.1.view.y_axis, + w: value.0.corner.z * value.1.view.z_axis, + eye: value.1.eye, pad1: 0., pad2: 0., pad3: 0., @@ -222,6 +227,7 @@ impl Tracer { data: &TracerData, env: &TracerEnv, params: Params, + viewport: Viewport, camera: CameraLocation, ) { pass.set_pipeline(&self.pipeline); @@ -230,7 +236,7 @@ impl Tracer { 0, bytes_of(&ParamsData { params, - camera: camera.into(), + camera: (viewport, camera).into(), }), ); pass.set_vertex_buffer(0, self.view_buf.slice(..)); diff --git a/src/bin/minitracer/trace.wgsl b/src/bin/minitracer/trace.wgsl index 9bc320f..bd22c1c 100644 --- a/src/bin/minitracer/trace.wgsl +++ b/src/bin/minitracer/trace.wgsl @@ -3,7 +3,10 @@ struct Params { min_strength: f32, sphere_count: i32, seed: u32, - view: mat3x3f, + + right: vec3f, + up: vec3f, + forward: vec3f, eye: vec3f, } @@ -31,7 +34,8 @@ var params: Params; @vertex fn on_vertex(in: Vertex) -> Varying { - return Varying(params.view * vec3(1.0, in.screen), vec4(in.screen, 0.0, 1.0)); + let m = mat3x3(params.right, params.up, params.forward); + return Varying(m * vec3(in.screen, 1.0), vec4(in.screen, 0.0, 1.0)); } @fragment