Add non-zero aperture

This commit is contained in:
numzero 2024-12-30 17:00:17 +03:00
parent 44ce47612a
commit fe998585b4
3 changed files with 35 additions and 9 deletions

View File

@ -161,6 +161,10 @@ fn main() {
seed: frame, seed: frame,
}, },
viewport, viewport,
trace::Aperture {
radius: 0.001,
focal_distance: std::f32::INFINITY,
},
location, location,
); );
} }

View File

@ -18,6 +18,11 @@ pub struct Viewport {
pub corner: Vec3, pub corner: Vec3,
} }
pub struct Aperture {
pub radius: f32,
pub focal_distance: f32, // from 0 (exclusive) to +∞ (inclusive)
}
#[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 {
v: Vec3, v: Vec3,
height: f32, height: f32,
w: Vec3, w: Vec3,
pad3: f32, aperture: f32,
eye: Vec3, eye: Vec3,
pad4: f32, antifocal: f32,
} }
impl From<(Viewport, CameraLocation)> for CameraData { impl From<(Viewport, CameraLocation, Aperture)> for CameraData {
fn from(value: (Viewport, CameraLocation)) -> Self { fn from(value: (Viewport, CameraLocation, Aperture)) -> Self {
CameraData { CameraData {
u: value.1.view.x_axis, u: value.1.view.x_axis,
v: value.1.view.y_axis, v: value.1.view.y_axis,
@ -53,8 +58,8 @@ impl From<(Viewport, CameraLocation)> for CameraData {
eye: value.1.eye, eye: value.1.eye,
width: value.0.corner.x / value.0.corner.z, width: value.0.corner.x / value.0.corner.z,
height: value.0.corner.y / value.0.corner.z, height: value.0.corner.y / value.0.corner.z,
pad3: 0., aperture: value.2.radius,
pad4: 0., antifocal: 1. / value.2.focal_distance,
} }
} }
} }
@ -228,6 +233,7 @@ impl Tracer {
env: &TracerEnv, env: &TracerEnv,
params: Params, params: Params,
viewport: Viewport, viewport: Viewport,
aperture: Aperture,
camera: CameraLocation, camera: CameraLocation,
) { ) {
pass.set_pipeline(&self.pipeline); pass.set_pipeline(&self.pipeline);
@ -236,7 +242,7 @@ impl Tracer {
0, 0,
bytes_of(&ParamsData { bytes_of(&ParamsData {
params, params,
camera: (viewport, camera).into(), camera: (viewport, camera, aperture).into(),
}), }),
); );
pass.set_vertex_buffer(0, self.view_buf.slice(..)); pass.set_vertex_buffer(0, self.view_buf.slice(..));

View File

@ -9,7 +9,9 @@ struct Params {
up: vec3f, up: vec3f,
height: f32, height: f32,
forward: vec3f, forward: vec3f,
aperture: f32,
eye: vec3f, eye: vec3f,
antifocal: f32,
} }
struct Sphere { struct Sphere {
@ -73,10 +75,14 @@ fn trace_fragment(in: Varying) -> vec3f {
var result = vec3(0.); var result = vec3(0.);
var color = vec3(1.); var color = vec3(1.);
pos = params.eye; let view_mtx = mat3x3(params.right, params.up, params.forward);
let aperture_offset_rel = params.aperture * rand_disc();
let aperture_offset_abs = view_mtx * vec3(aperture_offset_rel, 0.);
pos = params.eye + aperture_offset_abs;
let off_px = vec2(rand_float(), rand_float()) - .5; let off_px = vec2(rand_float(), rand_float()) - .5;
let off_w = mat2x3(dpdx(in.dir), dpdy(in.dir)); let off_w = mat2x3(dpdx(in.dir), dpdy(in.dir));
ray = normalize(in.dir + off_w * off_px); let dir = in.dir + off_w * off_px;
ray = normalize(dir - params.antifocal * aperture_offset_abs);
for (var k = 0; k < params.max_reflections; k++) { for (var k = 0; k < params.max_reflections; k++) {
var sphere = -1; var sphere = -1;
@ -140,6 +146,16 @@ fn rand_float() -> f32 {
return f32(rand_next()) / 0x1p32; return f32(rand_next()) / 0x1p32;
} }
fn rand_disc() -> vec2f {
for (var k = 0; k < 16; k++) {
let v = vec2f(rand_float(), rand_float()) - 0.5;
if (length(v) <= 0.5) {
return 2. * v;
}
}
return vec2f(0.0); // safeguard
}
fn rand_sphere() -> vec3f { fn rand_sphere() -> vec3f {
for (var k = 0; k < 16; k++) { for (var k = 0; k < 16; k++) {
let v = vec3f(rand_float(), rand_float(), rand_float()) - 0.5; let v = vec3f(rand_float(), rand_float(), rand_float()) - 0.5;