Implement acceleration tree
This commit is contained in:
parent
f44716e2c4
commit
636dc6450b
4 changed files with 66 additions and 76 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
33
src/main.rs
33
src/main.rs
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue