Implemented occlusion rays.
This is prep for lighting support: occlusion rays are useful for speedier shadow tests.
This commit is contained in:
parent
6f6807009b
commit
3b85b60a62
|
@ -192,6 +192,7 @@ impl BVH {
|
|||
match self.nodes[i_stack[stack_ptr]] {
|
||||
BVHNode::Internal { bounds_range: br, second_child_index, split_axis } => {
|
||||
let part = partition(&mut rays[..ray_i_stack[stack_ptr]], |r| {
|
||||
(!r.is_done()) &&
|
||||
lerp_slice(&self.bounds[br.0..br.1], r.time).intersect_accel_ray(r)
|
||||
});
|
||||
if part > 0 {
|
||||
|
@ -210,6 +211,7 @@ impl BVH {
|
|||
|
||||
BVHNode::Leaf { bounds_range: br, object_range } => {
|
||||
let part = partition(&mut rays[..ray_i_stack[stack_ptr]], |r| {
|
||||
(!r.is_done()) &&
|
||||
lerp_slice(&self.bounds[br.0..br.1], r.time).intersect_accel_ray(r)
|
||||
});
|
||||
if part > 0 {
|
||||
|
|
|
@ -76,7 +76,7 @@ impl Camera {
|
|||
1.0)
|
||||
.normalized();
|
||||
|
||||
Ray::new(orig * transform, dir * transform, time)
|
||||
Ray::new(orig * transform, dir * transform, time, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
43
src/ray.rs
43
src/ray.rs
|
@ -5,6 +5,9 @@ use std;
|
|||
use float4::Float4;
|
||||
use math::{Vector, Point, Matrix4x4};
|
||||
|
||||
const OCCLUSION_FLAG: u32 = 1;
|
||||
const DONE_FLAG: u32 = 1 << 1;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Ray {
|
||||
pub orig: Point,
|
||||
|
@ -15,13 +18,23 @@ pub struct Ray {
|
|||
}
|
||||
|
||||
impl Ray {
|
||||
pub fn new(orig: Point, dir: Vector, time: f32) -> Ray {
|
||||
Ray {
|
||||
orig: orig,
|
||||
dir: dir,
|
||||
max_t: std::f32::INFINITY,
|
||||
time: time,
|
||||
flags: 0,
|
||||
pub fn new(orig: Point, dir: Vector, time: f32, is_occ: bool) -> Ray {
|
||||
if !is_occ {
|
||||
Ray {
|
||||
orig: orig,
|
||||
dir: dir,
|
||||
max_t: std::f32::INFINITY,
|
||||
time: time,
|
||||
flags: 0,
|
||||
}
|
||||
} else {
|
||||
Ray {
|
||||
orig: orig,
|
||||
dir: dir,
|
||||
max_t: 1.0,
|
||||
time: time,
|
||||
flags: OCCLUSION_FLAG,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +42,10 @@ impl Ray {
|
|||
self.orig = self.orig * *mat;
|
||||
self.dir = self.dir * *mat;
|
||||
}
|
||||
|
||||
pub fn is_occlusion(&self) -> bool {
|
||||
(self.flags & OCCLUSION_FLAG) != 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,4 +80,16 @@ impl AccelRay {
|
|||
self.orig = wr.orig * *mat;
|
||||
self.dir_inv = Vector { co: Float4::new(1.0, 1.0, 1.0, 1.0) / (wr.dir * *mat).co };
|
||||
}
|
||||
|
||||
pub fn is_occlusion(&self) -> bool {
|
||||
(self.flags & OCCLUSION_FLAG) != 0
|
||||
}
|
||||
|
||||
pub fn is_done(&self) -> bool {
|
||||
(self.flags & DONE_FLAG) != 0
|
||||
}
|
||||
|
||||
pub fn mark_done(&mut self) {
|
||||
self.flags |= DONE_FLAG;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,14 +78,19 @@ impl Surface for TriangleMesh {
|
|||
let tri = (tri.0 * mat_inv, tri.1 * mat_inv, tri.2 * mat_inv);
|
||||
if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(wr, tri) {
|
||||
if t < r.max_t {
|
||||
isects[r.id as usize] = SurfaceIntersection::Hit {
|
||||
t: t,
|
||||
pos: wr.orig + (wr.dir * t),
|
||||
nor: Normal::new(0.0, 0.0, 0.0), // TODO
|
||||
local_space: mat_space,
|
||||
uv: (tri_u, tri_v),
|
||||
};
|
||||
r.max_t = t;
|
||||
if r.is_occlusion() {
|
||||
isects[r.id as usize] = SurfaceIntersection::Occlude;
|
||||
r.mark_done();
|
||||
} else {
|
||||
isects[r.id as usize] = SurfaceIntersection::Hit {
|
||||
t: t,
|
||||
pos: wr.orig + (wr.dir * t),
|
||||
nor: Normal::new(0.0, 0.0, 0.0), // TODO
|
||||
local_space: mat_space,
|
||||
uv: (tri_u, tri_v),
|
||||
};
|
||||
r.max_t = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user