diff --git a/src/bin/minitracer/anim.rs b/src/bin/minitracer/anim.rs index bd57b6e..3c20fad 100644 --- a/src/bin/minitracer/anim.rs +++ b/src/bin/minitracer/anim.rs @@ -45,6 +45,10 @@ impl SphereParams { glossiness, } } + + pub fn deriv(&self, time: f32) -> Vec3 { + self.frequencies * self.amplitudes * (self.frequencies * time + self.phases).map(|x| x.cos()) + } } trait VecDistribution { diff --git a/src/bin/minitracer/main.rs b/src/bin/minitracer/main.rs index 9ae0074..faa3b8f 100644 --- a/src/bin/minitracer/main.rs +++ b/src/bin/minitracer/main.rs @@ -16,22 +16,29 @@ mod trace; pub use trace::Sphere; -fn make_viewport(eye: Vec3, w: u32, h: u32) -> [Vertex; 4] { +struct CamLoc { + eye: Vec3, + forward: Vec3, + right: Vec3, +} + +fn make_viewport(cam: CamLoc, w: u32, h: u32) -> [Vertex; 4] { let size = uvec2(w, h).as_vec2(); let size = size.normalize(); 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 up = Vec3::Z; - let fwd = -eye.normalize(); - let right = eye.cross(up).normalize(); - let up = eye.cross(right).normalize(); + let eye = cam.eye; + let fwd = cam.forward.normalize(); + let up = cam.right.cross(fwd).normalize(); + let right = up.cross(fwd); + 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: eye + m * (world_coord[k]), + world: eye + m * world_coord[k], screen: screen_coord[k], }) } @@ -61,6 +68,14 @@ fn main() { }; let camera_params = { let mut p = anim::distr()(&mut rng); + p.amplitudes *= 2.0; + p.frequencies *= 0.1; + p + }; + let target_params = { + let mut p = anim::distr()(&mut rng); + p.origin = Vec3::splat(0.0); + p.amplitudes *= 0.5; p.frequencies *= 0.1; p }; @@ -131,8 +146,13 @@ 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 eye = camera_params.to_sphere(time).center; + let right = camera_params.deriv(time); + let forward = target_params.to_sphere(time).center - eye; + tracer.set_view( + &queue, + &make_viewport(CamLoc { eye, forward, right }, 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(