diff --git a/src/main.rs b/src/main.rs index 72a535a..da50183 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use crate::{ }; mod camera; +mod ray; mod render; mod trace; @@ -141,8 +142,10 @@ impl MainWindow { position_yaw: 0.0, position_pitch: PI / 3., distance: 1.0, - diameter: 0.25, + radius: 0.125, + spread: 0.125, }; + let contour: Vec = loop_list(source.contour(17)) .map(|pos| Vertex { pos, @@ -152,6 +155,25 @@ impl MainWindow { self.pipeline .render(&mut pass, [&Mesh::new(&self.device, &contour)]); + let mut prng = rand_pcg::Pcg64::new(42, 0); + let rays: Vec = (0..1000) + .flat_map(|_| { + let ray = source.make_ray(&mut prng); + [ + Vertex { + pos: ray.base, + color: vec3(0., 0., 0.), + }, + Vertex { + pos: ray.base + 0.1 * ray.dir, + color: vec3(1., 1., 1.), + }, + ] + }) + .collect(); + self.pipeline + .render(&mut pass, [&Mesh::new(&self.device, &rays)]); + drop(pass); self.queue.submit(std::iter::once(encoder.finish())); } diff --git a/src/ray.rs b/src/ray.rs new file mode 100644 index 0000000..265dd96 --- /dev/null +++ b/src/ray.rs @@ -0,0 +1,6 @@ +use glam::Vec3; + +pub struct Ray { + pub base: Vec3, + pub dir: Vec3, +} diff --git a/src/trace.rs b/src/trace.rs index dc33510..196dc67 100644 --- a/src/trace.rs +++ b/src/trace.rs @@ -1,8 +1,9 @@ use std::f32::consts::PI; -use glam::{Mat4, Vec3, vec3}; +use glam::{Mat4, Vec2, Vec3, vec3}; +use rand_distr::Distribution; -use crate::camera::OrbitalCamera; +use crate::{camera::OrbitalCamera, ray::Ray}; #[derive(Debug, Clone)] pub struct Source { @@ -16,7 +17,9 @@ pub struct Source { pub distance: f32, /// Disc diameter. - pub diameter: f32, + pub radius: f32, + + pub spread: f32, } impl Source { @@ -44,12 +47,27 @@ impl Source { pub fn contour(&self, n: usize) -> impl Iterator { let step = 2. * PI / n as f32; - let r = 0.5 * self.diameter; let m = self.transform(); (0..n).map(move |k| { let angle = (k as f32) * step; let (x, y) = angle.sin_cos(); - m.transform_point3(r * vec3(x, y, 0.)) + m.transform_point3(self.radius * vec3(x, y, 0.)) }) } + + pub fn make_ray(&self, rng: &mut impl rand::Rng) -> Ray { + let base: Vec2 = rand_distr::UnitDisc.sample(rng).into(); + let off: f32 = rand_distr::StandardUniform.sample(rng); + let side: Vec2 = rand_distr::UnitCircle.sample(rng).into(); + + let m = self.transform(); + let base = Vec3::from((self.radius * base, 0.)); + let fwd = 1. - self.spread * off; + let side_scale = (1. - fwd.powi(2)).sqrt(); + let dir = Vec3::from((side_scale * side, fwd)); + Ray { + base: m.transform_point3(base), + dir: m.transform_vector3(dir), + } + } }