diff options
Diffstat (limited to 'shaders/compute.comp')
| -rw-r--r-- | shaders/compute.comp | 79 |
1 files changed, 21 insertions, 58 deletions
diff --git a/shaders/compute.comp b/shaders/compute.comp index 2c56fbf..2f6c5f5 100644 --- a/shaders/compute.comp +++ b/shaders/compute.comp @@ -60,7 +60,7 @@ struct camera { struct bvh_node { aabb bb; - int left; + int next_id; int sphere_id; uint[2] padding; }; @@ -121,26 +121,17 @@ vec2 disk_vec(inout uint seed) { } bool hit_aabb(aabb b, ray r, float min_t, float max_t) { - for (int axis_index = 0; axis_index < 3; axis_index++) { - float inv_dir = 1.f / r.direction[axis_index]; - float t0 = (b.min[axis_index] - r.origin[axis_index]) * inv_dir; - float t1 = (b.max[axis_index] - r.origin[axis_index]) * inv_dir; + const vec3 invdir = 1.0 / r.direction; + const vec3 f = (b.max.xyz - r.origin.xyz) * invdir; + const vec3 n = (b.min.xyz - r.origin.xyz) * invdir; - if (inv_dir < 0.f) { - float temp = t0; - t0 = t1; - t1 = temp; - } - - min_t = t0 > min_t ? t0 : min_t; - max_t = t1 < max_t ? t1 : max_t; + const vec3 tmax = max(f, n); + const vec3 tmin = min(f, n); - if (max_t <= min_t) { - return false; - } - } + const float t1 = min(tmax.x, min(tmax.y, tmax.z)); + const float t0 = max(max(tmin.x, max(tmin.y, tmin.z)), 0.0f); - return true; + return t1 >= t0; } uint hit_aabbs(ray r, float min_t, float max_t) { @@ -192,56 +183,28 @@ bool hit_sphere(sphere s, ray r, float min_t, float max_t, out hit_info info) { bool hit_node(ray r, float min_t, float max_t, out hit_info info) { hit_info temp_info; float closest_t = max_t; - - if (!hit_aabb(nodes[0].bb, r, min_t, max_t)) { - return false; - } - - int stack_id = -1; - int stack[512]; - bvh_node current_node = nodes[0]; bool hit = false; + int id = 0; - while(true) { - // Reached a leaf - if (current_node.sphere_id != -1) { - if (hit_sphere(spheres[current_node.sphere_id], r, min_t, closest_t, temp_info)) { + while(id != -1) { + // Leafs + if (nodes[id].sphere_id != -1) { + if (hit_sphere(spheres[nodes[id].sphere_id], r, min_t, closest_t, temp_info)) { info = temp_info; closest_t = temp_info.t; hit = true; } - - if (stack_id >= 0) { - current_node = nodes[stack[stack_id]]; - stack_id--; - continue; - } - - return hit; - } - - bool hit_left = hit_aabb(nodes[current_node.left].bb, r, min_t, max_t); - bool hit_right = hit_aabb(nodes[current_node.left + 1].bb, r, min_t, max_t); - - if (hit_left && hit_right) { - stack_id++; - stack[stack_id] = current_node.left; - - current_node = nodes[current_node.left + 1]; - } else if (hit_left) { - current_node = nodes[current_node.left]; - } else if (hit_right) { - current_node = nodes[current_node.left + 1]; - } else { - if (stack_id >= 0) { - current_node = nodes[stack[stack_id]]; - stack_id--; + id = nodes[id].next_id; + } else { // Internal nodes + if (hit_aabb(nodes[id].bb, r, min_t, closest_t)) { + id++; } else { - return hit; + id = nodes[id].next_id; } } } + return hit; } bool hit_spheres(ray r, float min_t, float max_t, out hit_info info) { @@ -351,7 +314,7 @@ void main() { vec4 out_color = ray_color(r, seed); if (debug_bvh) { - out_color -= hit_aabbs(r, 0.001, 1e15) * vec4(0.0, 0.05, 0.05, 0.0); + out_color -= hit_aabbs(r, 0.001, 1e15) * vec4(0.0, 0.025, 0.025, 0.0); } float spp_scale = (1.0 / sample_index); |
