library: light: point_light: add sample_ray method
This commit is contained in:
parent
7eefd7b574
commit
bb7fa79fc3
|
@ -1,7 +1,9 @@
|
||||||
use super::{Light, SpatialLight};
|
use super::{Light, SpatialLight};
|
||||||
use crate::core::LinearColor;
|
use crate::core::LinearColor;
|
||||||
use crate::{Point, Vector};
|
use crate::{Point, Vector};
|
||||||
|
use beevee::ray::Ray;
|
||||||
use nalgebra::Unit;
|
use nalgebra::Unit;
|
||||||
|
use rand::{distributions::Uniform, Rng};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
/// Represent a light emanating from a point in space, following the square distance law.
|
/// Represent a light emanating from a point in space, following the square distance law.
|
||||||
|
@ -29,6 +31,36 @@ impl PointLight {
|
||||||
pub fn new(position: Point, color: LinearColor) -> Self {
|
pub fn new(position: Point, color: LinearColor) -> Self {
|
||||||
PointLight { position, color }
|
PointLight { position, color }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Uniformly sample a ray from the point-light in a random direction.
|
||||||
|
///
|
||||||
|
/// # Examles
|
||||||
|
///
|
||||||
|
///```
|
||||||
|
/// # use pathtracer::light::PointLight;
|
||||||
|
/// # use pathtracer::core::color::LinearColor;
|
||||||
|
/// # use pathtracer::Point;
|
||||||
|
/// #
|
||||||
|
/// let dir_light = PointLight::new(
|
||||||
|
/// Point::origin(),
|
||||||
|
/// LinearColor::new(1.0, 0.0, 1.0),
|
||||||
|
/// );
|
||||||
|
/// let sampled = dir_light.sample_ray();
|
||||||
|
/// ```
|
||||||
|
pub fn sample_ray(&self) -> Ray {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
// Sample sphere uniformly
|
||||||
|
// See <https://mathworld.wolfram.com/SpherePointPicking.html>
|
||||||
|
let theta = rng.gen_range(0., std::f32::consts::PI * 2.);
|
||||||
|
let y = rng.sample(Uniform::new(-1., 1.)); // Inclusive for the poles
|
||||||
|
let dir = Unit::new_unchecked(Vector::new(
|
||||||
|
// this vector is already of unit length
|
||||||
|
f32::sqrt(1. - y * y) * f32::cos(theta),
|
||||||
|
y,
|
||||||
|
f32::sqrt(1. - y * y) * f32::sin(theta),
|
||||||
|
));
|
||||||
|
Ray::new(self.position, dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Light for PointLight {
|
impl Light for PointLight {
|
||||||
|
|
Loading…
Reference in a new issue