Implement acceleration tree

This commit is contained in:
hodasemi 2019-04-15 20:05:22 +02:00
parent f44716e2c4
commit 636dc6450b
4 changed files with 66 additions and 76 deletions

View file

@ -1,4 +1,4 @@
use cgmath::{vec2, vec3, Vector2, Vector3, Zero}; use cgmath::{vec3, Vector2, Vector3, Zero};
use std::f32::{MAX, MIN}; use std::f32::{MAX, MIN};
@ -38,10 +38,59 @@ impl<'a> AccelerationData<'a> {
} }
pub fn find_closest_hit(&self, ray: &Ray) -> Option<Intersection> { pub fn find_closest_hit(&self, ray: &Ray) -> Option<Intersection> {
let mut closest_index = -1;
let mut closest_distance = MAX;
let mut barycentric = Vector2::zero();
self.traverse_tree(|_, aabb| {
if aabb.intersect(ray) {
// check if node is a leaf
if aabb.start_index != -1 {
for i in aabb.start_index..aabb.end_index {
let mut t = 0.0;
let mut tmp_bary = Vector2::zero();
if self.triangles[i as usize].intersect_mt(ray, &mut t, &mut tmp_bary) {
if t < closest_distance {
closest_index = i as i32;
closest_distance = t;
barycentric = tmp_bary;
}
}
}
}
true
} else {
false
}
});
if closest_index == -1 {
None None
} else {
Some(Intersection::new(
closest_distance,
self.triangles[closest_index as usize].clone(),
barycentric,
))
}
} }
pub fn print_tree(&self) { pub fn print_tree(&self) {
self.traverse_tree(|index, aabb| {
print_aabb(index, aabb);
true
})
}
}
// private
impl<'a> AccelerationData<'a> {
fn traverse_tree<F>(&self, mut f: F)
where
F: FnMut(usize, &AABB) -> bool,
{
let mut discovered = vec![false; 1024]; let mut discovered = vec![false; 1024];
let mut stack = Vec::new(); let mut stack = Vec::new();
@ -57,8 +106,7 @@ impl<'a> AccelerationData<'a> {
discovered[v] = true; discovered[v] = true;
print_aabb(v, self.data[v]); if (f)(v, &self.data[v]) {
let left_child = self.data[v].left_child; let left_child = self.data[v].left_child;
if left_child != -1 { if left_child != -1 {
if !discovered[left_child as usize] { if !discovered[left_child as usize] {
@ -74,10 +122,8 @@ impl<'a> AccelerationData<'a> {
} }
} }
} }
} }
// private
impl<'a> AccelerationData<'a> {
fn create_leaf_nodes(input_data: &[Triangle], triangles_per_as: u32) -> Vec<AABB> { fn create_leaf_nodes(input_data: &[Triangle], triangles_per_as: u32) -> Vec<AABB> {
let mut acceleration_data = Vec::new(); let mut acceleration_data = Vec::new();
@ -178,6 +224,6 @@ impl<'a> AccelerationData<'a> {
} }
} }
fn print_aabb(index: usize, aabb: AABB) { fn print_aabb(index: usize, aabb: &AABB) {
println!("({}):\t{:?}", index, aabb); println!("({}):\t{:?}", index, aabb);
} }

View file

@ -1,9 +1,7 @@
use cgmath::{vec2, vec3, Vector2, Vector3, Zero}; use cgmath::Vector2;
use crate::triangle::Triangle; use crate::triangle::Triangle;
use std::f32::MAX;
pub struct Intersection { pub struct Intersection {
pub distance: f32, pub distance: f32,
pub triangle: Triangle, pub triangle: Triangle,
@ -18,12 +16,4 @@ impl Intersection {
barycentric, barycentric,
} }
} }
pub fn zero() -> Intersection {
Intersection {
distance: MAX,
triangle: Triangle::zero(),
barycentric: Vector2::zero(),
}
}
} }

View file

@ -49,7 +49,6 @@ fn generate_grid(width: u32, height: u32) -> Vec<Triangle> {
fn main() { fn main() {
let input_data = generate_grid(5, 5); let input_data = generate_grid(5, 5);
/*
let camera = Camera::new( let camera = Camera::new(
vec3(0.0, -4.0, 4.0), vec3(0.0, -4.0, 4.0),
vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0),
@ -57,15 +56,6 @@ fn main() {
45.0, 45.0,
1280.0 / 720.0, 1280.0 / 720.0,
); );
*/
let camera = Camera::new(
vec3(0.0, 0.0, 3.0),
vec3(0.0, 0.0, 0.0),
vec3(0.0, 1.0, 1.0),
45.0,
1280.0 / 720.0,
);
debug_raytracer_camera(1280, 720, &camera, &input_data); debug_raytracer_camera(1280, 720, &camera, &input_data);
} }
@ -95,29 +85,6 @@ fn debug_raytracer_camera(dim_x: u32, dim_y: u32, camera: &Camera, data: &[Trian
fn pixel_color(ray: &Ray, acceleration_data: &AccelerationData) -> Vector3<f32> { fn pixel_color(ray: &Ray, acceleration_data: &AccelerationData) -> Vector3<f32> {
let mut final_color = vec3(0.0, 1.0, 0.0); let mut final_color = vec3(0.0, 1.0, 0.0);
/*
let mut closest_value = MAX;
let mut closest_index = -1;
let mut barycentric = Vector2::zero();
for accel in acceleration_data.iter() {
if accel.intersect(ray) {
for i in accel.start_index..accel.end_index {
let mut t = 0.0;
let mut tmp_bary = Vector2::zero();
if data[i].intersect_mt(ray, &mut t, &mut tmp_bary) {
if t < closest_value {
closest_index = i as i32;
closest_value = t;
barycentric = tmp_bary;
}
}
}
}
}
*/
if let Some(intersection) = acceleration_data.find_closest_hit(ray) { if let Some(intersection) = acceleration_data.find_closest_hit(ray) {
let triangle = intersection.triangle; let triangle = intersection.triangle;

View file

@ -1,4 +1,4 @@
use cgmath::{InnerSpace, Vector2, Vector3, Zero}; use cgmath::{InnerSpace, Vector2, Vector3};
use super::ray::Ray; use super::ray::Ray;
@ -15,15 +15,9 @@ impl Vertex {
texture_coordinate, texture_coordinate,
} }
} }
pub fn zero() -> Vertex {
Vertex {
position: Vector3::zero(),
texture_coordinate: Vector2::zero(),
}
}
} }
#[derive(Clone)]
pub struct Triangle { pub struct Triangle {
pub vertices: [Vertex; 3], pub vertices: [Vertex; 3],
pub color: Vector3<f32>, pub color: Vector3<f32>,
@ -37,13 +31,6 @@ impl Triangle {
} }
} }
pub fn zero() -> Triangle {
Triangle {
vertices: [Vertex::zero(); 3],
color: Vector3::zero(),
}
}
// source: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/moller-trumbore-ray-triangle-intersection // source: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/moller-trumbore-ray-triangle-intersection
pub fn intersect_mt(&self, ray: &Ray, t: &mut f32, barycentric: &mut Vector2<f32>) -> bool { pub fn intersect_mt(&self, ray: &Ray, t: &mut f32, barycentric: &mut Vector2<f32>) -> bool {
let v0v1 = self.vertices[1].position - self.vertices[0].position; let v0v1 = self.vertices[1].position - self.vertices[0].position;