diff --git a/src/bin/minitracer/main.rs b/src/bin/minitracer/main.rs index c50571c..e5d8aab 100644 --- a/src/bin/minitracer/main.rs +++ b/src/bin/minitracer/main.rs @@ -165,6 +165,8 @@ fn main() { trace::Aperture { radius: 0.001, focal_distance: forward.length(), + glare_strength: 0.1, + glare_radius: 0.1, }, location, ); diff --git a/src/bin/minitracer/trace.rs b/src/bin/minitracer/trace.rs index f55a324..e95c7ed 100644 --- a/src/bin/minitracer/trace.rs +++ b/src/bin/minitracer/trace.rs @@ -18,9 +18,12 @@ pub struct Viewport { pub corner: Vec3, } +#[derive(Debug, Clone, Copy)] pub struct Aperture { pub radius: f32, pub focal_distance: f32, // from 0 (exclusive) to +∞ (inclusive) + pub glare_strength: f32, + pub glare_radius: f32, // at distance 1 } #[derive(Debug, Clone, Copy)] @@ -47,6 +50,8 @@ struct CameraData { aperture: f32, eye: Vec3, antifocal: f32, + glare_strength: f32, + glare_radius: f32, } impl From<(Viewport, CameraLocation, Aperture)> for CameraData { @@ -60,6 +65,8 @@ impl From<(Viewport, CameraLocation, Aperture)> for CameraData { height: value.0.corner.y / value.0.corner.z, aperture: value.2.radius, antifocal: 1. / value.2.focal_distance, + glare_strength: value.2.glare_strength, + glare_radius: value.2.glare_radius, } } } diff --git a/src/bin/minitracer/trace.wgsl b/src/bin/minitracer/trace.wgsl index f3fce09..247b5c1 100644 --- a/src/bin/minitracer/trace.wgsl +++ b/src/bin/minitracer/trace.wgsl @@ -12,6 +12,9 @@ struct Params { aperture: f32, eye: vec3f, antifocal: f32, + + glare_strength: f32, + glare_radius: f32, } struct Sphere { @@ -81,7 +84,13 @@ fn trace_fragment(in: Varying) -> vec3f { 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)); - let dir = in.dir + off_w * off_px; + var dir = in.dir + off_w * off_px; + if (rand_float() < params.glare_strength) { + let p = rand_float(); + let d = params.glare_radius * pow(p, 3.); + let glare_off = d * rand_disc(); + dir += view_mtx * vec3(glare_off, 0.); + } ray = normalize(dir - params.antifocal * aperture_offset_abs); for (var k = 0; k < params.max_reflections; k++) {