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 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,
);
}
}

View File

@ -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<CameraLocation> 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(..));

View File

@ -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<push_constant> 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