From 738c765557df281f4980b543172a3363a485b592 Mon Sep 17 00:00:00 2001 From: Anton Ljungdahl Date: Sun, 11 May 2025 14:42:33 +0200 Subject: [PATCH] fastish build of SAH BVH --- src/rayt_base.odin | 34 ++------- src/rayt_bvh.odin | 186 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 169 insertions(+), 51 deletions(-) diff --git a/src/rayt_base.odin b/src/rayt_base.odin index bbaa3a9..756f99b 100644 --- a/src/rayt_base.odin +++ b/src/rayt_base.odin @@ -51,7 +51,8 @@ Viewport :: struct { Ray :: struct { origin : Vec3, - direction : Vec3 + direction : Vec3, + inv_dir : Vec3 } HitRecord :: struct { @@ -108,6 +109,7 @@ ray_get :: proc(x : f32, y : f32) -> Ray { out.direction = ray_direction out.origin = camera.center + out.inv_dir = Vec3{1.0/out.direction.x, 1.0/out.direction.y, 1.0/out.direction.z} return out } @@ -116,29 +118,6 @@ rayt_cpu_main :: proc() { rand.reset(RAND_SEED) load_triangles() - - // Random triangles - //{ - // center_shift := Vec3{5.0, 5.0, 5.0} - // // Generate triangles inside a box - // for i in 0.. b32 { - tx1 : f32 = (bmin.x - ray.origin.x) / ray.direction.x - tx2 : f32 = (bmax.x - ray.origin.x) / ray.direction.x + tx1 : f32 = (bmin.x - ray.origin.x) * ray.inv_dir.x + tx2 : f32 = (bmax.x - ray.origin.x) * ray.inv_dir.x tmin : f32 = math.min(tx1, tx2) tmax : f32 = math.max(tx1, tx2) - ty1 : f32 = (bmin.y - ray.origin.y) / ray.direction.y - ty2 : f32 = (bmax.y - ray.origin.y) / ray.direction.y + ty1 : f32 = (bmin.y - ray.origin.y) * ray.inv_dir.y + ty2 : f32 = (bmax.y - ray.origin.y) * ray.inv_dir.y tmin = math.max(tmin, math.min(ty1, ty2)) tmax = math.min(tmax, math.max(ty1, ty2)) - tz1 : f32 = (bmin.z - ray.origin.z) / ray.direction.z - tz2 : f32 = (bmax.z - ray.origin.z) / ray.direction.z + tz1 : f32 = (bmin.z - ray.origin.z) * ray.inv_dir.z + tz2 : f32 = (bmax.z - ray.origin.z) * ray.inv_dir.z tmin = math.max(tmin, math.min(tz1, tz2)) tmax = math.min(tmax, math.max(tz1, tz2)) @@ -51,6 +66,40 @@ intersect_aabb :: proc(ray : ^Ray, bmin : Vec3, bmax : Vec3, closest_so_far : f3 return out } + +aabb_area :: proc(aabb_min : Vec3, aabb_max : Vec3) -> f32 { + e := aabb_max - aabb_min + return e.x * e.y + e.y * e.z + e.z * e.x +} + +aabb_grow :: proc(aabb_min : Vec3, aabb_max : Vec3, p_min : Vec3, p_max : Vec3) -> (Vec3, Vec3) { + out_aabb_min := aabb_min + out_aabb_max := aabb_max + if(p_min.x < math.F32_MAX) { + out_aabb_min = linalg.min(out_aabb_min, p_min) + out_aabb_max = linalg.max(out_aabb_max, p_min) + out_aabb_min = linalg.min(out_aabb_min, p_max) + out_aabb_max = linalg.max(out_aabb_max, p_max) + } + return out_aabb_min, out_aabb_max +} + +aabb_min_triangle :: proc(aabb_min : Vec3, tri : ^Entity) -> Vec3 { + out_aabb_min := aabb_min + out_aabb_min = linalg.min(out_aabb_min, tri.v0) + out_aabb_min = linalg.min(out_aabb_min, tri.v1) + out_aabb_min = linalg.min(out_aabb_min, tri.v2) + return out_aabb_min +} + +aabb_max_triangle :: proc(aabb_max : Vec3, tri : ^Entity) -> Vec3 { + out_aabb_max := aabb_max + out_aabb_max = linalg.max(out_aabb_max, tri.v0) + out_aabb_max = linalg.max(out_aabb_max, tri.v1) + out_aabb_max = linalg.max(out_aabb_max, tri.v2) + return out_aabb_max +} + bvh_update_bounds :: proc(node_idx : u32) { node : ^BVHNode = &bvh.nodes[node_idx] @@ -61,28 +110,113 @@ bvh_update_bounds :: proc(node_idx : u32) { for i in 0.. f32 { + best_cost : f32 = math.F32_MAX + + // Loop over each axis + for axis in 0..<3 { + bounds_min : f32 = math.F32_MAX + bounds_max : f32 = -math.F32_MAX + // Find the bounds of all the primitive centers in the node + for i in 0..= node_split_cost) { return; } - extent := node.aabb_max - node.aabb_min - axis : u32 = 0 - if(extent.y > extent.x) {axis = 1} - if(extent.z > extent[axis]) {axis = 2} - split_pos : f32 = node.aabb_min[axis] + extent[axis] * 0.5 - + i : u32 = node.left_first j : u32 = node.tri_count + i - 1 @@ -150,8 +284,9 @@ bvh_build :: proc() { num_triangles : u32 = cast(u32)len(tri_indices) bvh.max_num_nodes = 2 * num_triangles - 1 bvh.nodes = make([]BVHNode, bvh.max_num_nodes) - bvh.used_nodes = 2 // We skip first two nodes, for some reason. TODO comment this, read the tutorial - bvh.num_leaf_entities = 2 + bvh.used_nodes = 2 // We skip first two nodes, for some reason. + //TODO comment this, read the tutorial + bvh.num_leaf_entities = 4 bvh.root_index = 0 // Init root node @@ -184,5 +319,6 @@ bvh_stats :: proc() { fmt.printf("Total number of leaf nodes: %i \n", num_leaf_nodes) fmt.printf("Total number of triangles in BVH: %i \n", total_triangles_in_bvh) } + assert(cast(int)total_triangles_in_bvh == len(tri_indices)) bvh.num_leaf_nodes = num_leaf_nodes } \ No newline at end of file