Add next event estimation
This commit is contained in:
parent
534a7d7097
commit
7d69122e8c
13 changed files with 317 additions and 21 deletions
|
|
@ -6,5 +6,6 @@ edition = "2021"
|
|||
[dependencies]
|
||||
miette = { version = "7.2.0", features = ["fancy"] }
|
||||
nom = "7.1.3"
|
||||
rand = "0.8.5"
|
||||
ray-tracing-core = { path = "../ray-tracing-core" }
|
||||
ray-tracing-material = { path = "../ray-tracing-material" }
|
||||
|
|
|
|||
|
|
@ -52,4 +52,13 @@ impl<R: Rng> Scene<R> for BasicScene {
|
|||
|
||||
intersection
|
||||
}
|
||||
|
||||
fn sample_light(
|
||||
&self,
|
||||
_w_in: Dir3,
|
||||
_intersection: &Intersection<'_, R>,
|
||||
_rng: &mut R,
|
||||
) -> Option<ray_tracing_core::scene::LightSample<'_, R>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ pub fn cornell2<R: Rng + Debug>() -> ExampleScene<R> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let scene = dbg!(TriangleBVH::new(obj.vertices, triangles, materials));
|
||||
let scene = TriangleBVH::new(obj.vertices, triangles, materials);
|
||||
|
||||
ExampleScene {
|
||||
scene,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use rand::seq::SliceRandom;
|
||||
use ray_tracing_core::{
|
||||
prelude::*,
|
||||
scene::{Intersection, Scene},
|
||||
scene::{Intersection, LightSample, Scene},
|
||||
};
|
||||
use sampling::sample_triangle;
|
||||
|
||||
type Index = u32;
|
||||
|
||||
|
|
@ -11,6 +13,7 @@ pub struct TriangleBVH<R: Rng> {
|
|||
triangles: Vec<Triangle>,
|
||||
materials: Vec<BVHMaterial<R>>,
|
||||
bvh: Vec<Node>,
|
||||
lights: Vec<Triangle>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -211,20 +214,29 @@ impl<R: Rng> TriangleBVH<R> {
|
|||
}];
|
||||
let aabb = calculate_aabb(&vertices, &triangles);
|
||||
build_bvh(&vertices, &mut triangles, &mut bvh, 0, aabb);
|
||||
let lights: Vec<_> = triangles
|
||||
.iter()
|
||||
.filter(|f| materials[f.material as usize].light.is_some())
|
||||
.map(Triangle::clone)
|
||||
.collect();
|
||||
Self {
|
||||
vertices,
|
||||
bvh,
|
||||
triangles,
|
||||
materials,
|
||||
lights,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_vertices(&self, triangle: Index) -> [Pos3; 3] {
|
||||
let t = self.triangles[triangle as usize];
|
||||
fn get_vertices_from_index(&self, triangle: Index) -> [Pos3; 3] {
|
||||
self.get_vertices(&self.triangles[triangle as usize])
|
||||
}
|
||||
|
||||
fn get_vertices(&self, triangle: &Triangle) -> [Pos3; 3] {
|
||||
[
|
||||
self.vertices[t.vertices[0] as usize],
|
||||
self.vertices[t.vertices[1] as usize],
|
||||
self.vertices[t.vertices[2] as usize],
|
||||
self.vertices[triangle.vertices[0] as usize],
|
||||
self.vertices[triangle.vertices[1] as usize],
|
||||
self.vertices[triangle.vertices[2] as usize],
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +290,7 @@ impl<R: Rng> TriangleBVH<R> {
|
|||
Node::Leaf { start, count } => {
|
||||
let mut intersection = None;
|
||||
for i in start..(start + count) {
|
||||
if let Some(t) = triangle_intersection(ray, self.get_vertices(i)) {
|
||||
if let Some(t) = triangle_intersection(ray, self.get_vertices_from_index(i)) {
|
||||
if min <= t && t <= max && !intersection.is_some_and(|(_, old_t)| t > old_t)
|
||||
{
|
||||
intersection.replace((i, t));
|
||||
|
|
@ -304,7 +316,7 @@ impl<R: Rng> Scene<R> for TriangleBVH<R> {
|
|||
let triangle = self.triangles[i as usize];
|
||||
let material = &self.materials[triangle.material as usize];
|
||||
|
||||
let n = triangle_normal(self.get_vertices(i)).normalize();
|
||||
let n = triangle_normal(self.get_vertices_from_index(i)).normalize();
|
||||
|
||||
Some(Intersection::new(
|
||||
t,
|
||||
|
|
@ -313,4 +325,34 @@ impl<R: Rng> Scene<R> for TriangleBVH<R> {
|
|||
material.light.as_deref(),
|
||||
))
|
||||
}
|
||||
|
||||
fn sample_light(
|
||||
&self,
|
||||
_w_in: Dir3,
|
||||
_intersection: &Intersection<'_, R>,
|
||||
rng: &mut R,
|
||||
) -> Option<ray_tracing_core::scene::LightSample<'_, R>> {
|
||||
let t = self.lights.choose(rng);
|
||||
|
||||
if let Some(t) = t {
|
||||
let light = self.materials[t.material as usize]
|
||||
.light
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.as_ref();
|
||||
let b = sample_triangle(rng.gen());
|
||||
|
||||
let n = triangle_normal(self.get_vertices(t));
|
||||
let area = n.length() * 0.5;
|
||||
|
||||
Some(LightSample::new(
|
||||
Pos3::from_barycentric(self.get_vertices(t), b),
|
||||
1.0 / ((self.lights.len() as Float) * area),
|
||||
n.normalize(),
|
||||
light,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue