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,
},
viewport,
trace::Aperture {
radius: 0.001,
focal_distance: std::f32::INFINITY,
},
location,
);
}

View File

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

View File

@ -9,7 +9,9 @@ struct Params {
up: vec3f,
height: f32,
forward: vec3f,
aperture: f32,
eye: vec3f,
antifocal: f32,
}
struct Sphere {
@ -73,10 +75,14 @@ fn trace_fragment(in: Varying) -> vec3f {
var result = vec3(0.);
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_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++) {
var sphere = -1;
@ -140,6 +146,16 @@ fn rand_float() -> f32 {
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 {
for (var k = 0; k < 16; k++) {
let v = vec3f(rand_float(), rand_float(), rand_float()) - 0.5;