Split camera location and viewport

This commit is contained in:
numzero 2024-12-30 16:46:25 +03:00
parent 750dc8d744
commit 96b5ac2200
3 changed files with 34 additions and 19 deletions

View File

@ -1,6 +1,6 @@
use std::error::Error; use std::error::Error;
use glam::{mat3, uvec2, Vec3}; use glam::{mat3, uvec2, vec3, Vec3};
use image::ImageReader; use image::ImageReader;
use present::Presenter; use present::Presenter;
use trace::{Tracer, TracerData, TracerEnv}; use trace::{Tracer, TracerData, TracerEnv};
@ -22,18 +22,21 @@ struct CamLoc {
right: Vec3, 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 = uvec2(w, h).as_vec2();
let size = size.normalize(); let size = size.normalize();
let (w, h, d) = (size.x, size.y, 1.); trace::Viewport {
corner: vec3(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();
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 { trace::CameraLocation {
eye: cam.eye, 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 eye = camera_params.to_sphere(time).center;
let right = camera_params.deriv(time); let right = camera_params.deriv(time);
let forward = target_params.to_sphere(time).center - eye; 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 spheres: Vec<_> = sphere_params.iter().map(|p| p.to_sphere(time)).collect();
let data = TracerData::new(&device, &tracer, &spheres); let data = TracerData::new(&device, &tracer, &spheres);
tracer.render( tracer.render(
@ -156,7 +160,8 @@ fn main() {
sphere_count: N_SPHERES, sphere_count: N_SPHERES,
seed: frame, seed: frame,
}, },
view, viewport,
location,
); );
} }
} }

View File

@ -13,6 +13,11 @@ pub struct Params {
pub seed: u32, pub seed: u32,
} }
#[derive(Debug, Clone, Copy)]
pub struct Viewport {
pub corner: Vec3,
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct CameraLocation { pub struct CameraLocation {
pub eye: Vec3, pub eye: Vec3,
@ -39,13 +44,13 @@ struct CameraData {
pad4: f32, pad4: f32,
} }
impl From<CameraLocation> for CameraData { impl From<(Viewport, CameraLocation)> for CameraData {
fn from(value: CameraLocation) -> Self { fn from(value: (Viewport, CameraLocation)) -> Self {
CameraData { CameraData {
u: value.view.x_axis, u: value.0.corner.x * value.1.view.x_axis,
v: value.view.y_axis, v: value.0.corner.y * value.1.view.y_axis,
w: value.view.z_axis, w: value.0.corner.z * value.1.view.z_axis,
eye: value.eye, eye: value.1.eye,
pad1: 0., pad1: 0.,
pad2: 0., pad2: 0.,
pad3: 0., pad3: 0.,
@ -222,6 +227,7 @@ impl Tracer {
data: &TracerData, data: &TracerData,
env: &TracerEnv, env: &TracerEnv,
params: Params, params: Params,
viewport: Viewport,
camera: CameraLocation, camera: CameraLocation,
) { ) {
pass.set_pipeline(&self.pipeline); pass.set_pipeline(&self.pipeline);
@ -230,7 +236,7 @@ impl Tracer {
0, 0,
bytes_of(&ParamsData { bytes_of(&ParamsData {
params, params,
camera: camera.into(), camera: (viewport, camera).into(),
}), }),
); );
pass.set_vertex_buffer(0, self.view_buf.slice(..)); pass.set_vertex_buffer(0, self.view_buf.slice(..));

View File

@ -3,7 +3,10 @@ struct Params {
min_strength: f32, min_strength: f32,
sphere_count: i32, sphere_count: i32,
seed: u32, seed: u32,
view: mat3x3f,
right: vec3f,
up: vec3f,
forward: vec3f,
eye: vec3f, eye: vec3f,
} }
@ -31,7 +34,8 @@ var<push_constant> params: Params;
@vertex @vertex
fn on_vertex(in: Vertex) -> Varying { 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 @fragment