library: render: take advantage of cosine-weighted
This commit is contained in:
parent
311b7cd03b
commit
7567b93f9c
|
@ -48,7 +48,7 @@ impl BidirectionalPathtracer {
|
||||||
|
|
||||||
res.push_point(p);
|
res.push_point(p);
|
||||||
|
|
||||||
let (new_direction, _) = sample_hemisphere(normal);
|
let new_direction = sample_hemisphere(normal);
|
||||||
// Calculate the incoming light along the new ray
|
// Calculate the incoming light along the new ray
|
||||||
origin = hit_pos + new_direction.as_ref() * 0.001;
|
origin = hit_pos + new_direction.as_ref() * 0.001;
|
||||||
direction = new_direction;
|
direction = new_direction;
|
||||||
|
|
|
@ -110,8 +110,7 @@ impl Pathtracer {
|
||||||
let brdf = properties.diffuse;
|
let brdf = properties.diffuse;
|
||||||
// Pick a new direction
|
// Pick a new direction
|
||||||
let normal = obj.shape.normal(&hit_pos);
|
let normal = obj.shape.normal(&hit_pos);
|
||||||
let (new_direction, weight) = sample_hemisphere(normal);
|
let new_direction = sample_hemisphere(normal);
|
||||||
let cos_new_ray = new_direction.dot(&normal);
|
|
||||||
// Calculate the incoming light along the new ray
|
// Calculate the incoming light along the new ray
|
||||||
let new_ray = Ray::new(hit_pos + new_direction.as_ref() * 0.001, new_direction);
|
let new_ray = Ray::new(hit_pos + new_direction.as_ref() * 0.001, new_direction);
|
||||||
let incoming = self
|
let incoming = self
|
||||||
|
@ -120,7 +119,8 @@ impl Pathtracer {
|
||||||
self.radiance(new_ray, t, obj, limit - 1)
|
self.radiance(new_ray, t, obj, limit - 1)
|
||||||
});
|
});
|
||||||
// Put it all together
|
// Put it all together
|
||||||
properties.emitted + (brdf * incoming * cos_new_ray * weight)
|
// The weight of the sample and the cosine of the new ray cancel each other out
|
||||||
|
properties.emitted + (brdf * incoming)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_ray(&self, ray: Ray) -> Option<(f32, &Object)> {
|
fn cast_ray(&self, ray: Ray) -> Option<(f32, &Object)> {
|
||||||
|
|
|
@ -70,9 +70,9 @@ impl RefractionInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a random ray in the hemisphere described by a normal unit-vector, and the probability
|
/// Returns a random ray in the hemisphere described by a normal unit-vector
|
||||||
/// to have picked that direction.
|
/// It is cosine-sampled, which is convenient for path-tracing.
|
||||||
pub fn sample_hemisphere(normal: Unit<Vector>) -> (Unit<Vector>, f32) {
|
pub fn sample_hemisphere(normal: Unit<Vector>) -> Unit<Vector> {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let azimuth = rng.gen::<f32>() * std::f32::consts::PI * 2.;
|
let azimuth = rng.gen::<f32>() * std::f32::consts::PI * 2.;
|
||||||
// Cosine weighted importance sampling
|
// Cosine weighted importance sampling
|
||||||
|
@ -93,15 +93,13 @@ pub fn sample_hemisphere(normal: Unit<Vector>) -> (Unit<Vector>, f32) {
|
||||||
let normal_b = normal.cross(&normal_t);
|
let normal_b = normal.cross(&normal_t);
|
||||||
|
|
||||||
// Perform the matrix calculation by hand...
|
// Perform the matrix calculation by hand...
|
||||||
let scattered = Unit::new_normalize(Vector::new(
|
// The probability to have picked the ray is inversely proportional to cosine of the angle with
|
||||||
|
// the normal
|
||||||
|
Unit::new_normalize(Vector::new(
|
||||||
x * normal_b.x + y * normal.x + z * normal_t.x,
|
x * normal_b.x + y * normal.x + z * normal_t.x,
|
||||||
x * normal_b.y + y * normal.y + z * normal_t.y,
|
x * normal_b.y + y * normal.y + z * normal_t.y,
|
||||||
x * normal_b.z + y * normal.z + z * normal_t.z,
|
x * normal_b.z + y * normal.z + z * normal_t.z,
|
||||||
));
|
))
|
||||||
|
|
||||||
// The probability to have picked the ray is inversely proportional to cosine of the angle with
|
|
||||||
// the normal
|
|
||||||
(scattered, (1. / scattered.dot(&normal)).min(f32::MAX))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_to_image(buffer: &[LinearColor], passes: u32, width: u32, height: u32) -> RgbImage {
|
pub fn buffer_to_image(buffer: &[LinearColor], passes: u32, width: u32, height: u32) -> RgbImage {
|
||||||
|
|
Loading…
Reference in a new issue