diff options
Diffstat (limited to 'shaders')
| -rw-r--r-- | shaders/compute.comp | 130 |
1 files changed, 74 insertions, 56 deletions
diff --git a/shaders/compute.comp b/shaders/compute.comp index a6fd9e4..b11a296 100644 --- a/shaders/compute.comp +++ b/shaders/compute.comp @@ -61,9 +61,8 @@ struct camera { struct bvh_node { aabb bb; int left; - int right; int sphere_id; - uint padding; + uint[2] padding; }; layout(set = 0, binding = 0) buffer Inputs { @@ -80,7 +79,8 @@ layout(set = 0, binding = 0) buffer Inputs { uint sample_index; uint spheres_count; - uint[3] padding; + bool debug_bvh; + uint[2] padding; }; layout(set = 0, binding = 1, rgba32f) uniform writeonly image2D output_image; @@ -103,9 +103,7 @@ uint wang_hash(inout uint seed) float rand(inout uint seed) { - float r = wang_hash(seed) * (1.0 / 4294967296.0); - // seed += 10; - return r; + return float(wang_hash(seed)) / 4294967296.0; } vec3 unit_vec(inout uint seed) { @@ -133,13 +131,13 @@ bool hit_aabb(aabb b, ray r, float min_t, float max_t) { if (inv_dir < 0.f) { float temp = t0; t0 = t1; - t1 = t0; + t1 = temp; } - min_t = max(t0, min_t); - max_t = min(t1, max_t); + min_t = t0 > min_t ? t0 : min_t; + max_t = t1 < max_t ? t1 : max_t; - if (max_t < min_t) { + if (max_t <= min_t) { return false; } } @@ -147,45 +145,59 @@ bool hit_aabb(aabb b, ray r, float min_t, float max_t) { return true; } -bool hit_node(bvh_node node, ray r, float min_t, float max_t, out hit_info info) { - if (!hit_aabb(node.bb, r, min_t, max_t)) { - return false; - } - - int stack_id = -1; - int stack[64]; - bvh_node current_node = node; - - while(true) { - bool hit_left = hit_aabb(nodes[current_node.left - 1].bb, r, min_t, max_t); - bool hit_right = hit_aabb(nodes[current_node.right - 1].bb, r, min_t, max_t); - - if (hit_left && hit_right) { - stack_id++; - stack[stack_id] = current_node.left - 1; +uint hit_aabbs(ray r, float min_t, float max_t) { + uint hit_count = 0; + for (uint idx = 0; idx <= spheres_count * 2; idx++) { + hit_count += uint(hit_aabb(nodes[idx].bb, r, min_t, max_t)); - current_node = nodes[current_node.right - 1]; - } else if (hit_left) { - current_node = nodes[current_node.left - 1]; - } else if (hit_right) { - current_node = nodes[current_node.right - 1]; - } else { - if (stack_id >= 0) { - current_node = nodes[stack[stack_id]]; - stack_id--; - } else { - return false; - } - } - - // Reached a leaf - if (current_node.left == -1 && current_node.right == -1) { - return true; + if (nodes[idx].sphere_id >= 0) { + hit_count += uint(hit_aabb(spheres[nodes[idx].sphere_id].bb, r, min_t, max_t)); } } + return hit_count; } +// bool hit_node(ray r, float min_t, float max_t, out hit_info info) { +// if (!hit_aabb(nodes[0].bb, r, min_t, max_t)) { +// return false; +// } +// return true; +// +// int stack_id = -1; +// int stack[64]; +// bvh_node current_node = nodes[0]; +// +// while(true) { +// bool hit_left = hit_aabb(nodes[current_node.left - 1].bb, r, min_t, max_t); +// bool hit_right = hit_aabb(nodes[current_node.right - 1].bb, r, min_t, max_t); +// +// if (hit_left && hit_right) { +// stack_id++; +// stack[stack_id] = current_node.left - 1; +// +// current_node = nodes[current_node.right - 1]; +// } else if (hit_left) { +// current_node = nodes[current_node.left - 1]; +// } else if (hit_right) { +// current_node = nodes[current_node.right - 1]; +// } else { +// if (stack_id >= 0) { +// current_node = nodes[stack[stack_id]]; +// stack_id--; +// } else { +// return false; +// } +// } +// +// // Reached a leaf +// if (current_node.left == -1 && current_node.right == -1) { +// return true; +// } +// } +// +// } + bool hit_sphere(sphere s, ray r, float min_t, float max_t, out hit_info info) { vec3 origin_center = r.origin - s.position.xyz; @@ -299,20 +311,20 @@ vec4 ray_color(ray r, uint seed) { // Russian Roulette // As the throughput gets smaller, the ray is more likely to get terminated early. // Survivors have their value boosted to make up for fewer samples being in the average. - { - float p = max(throughput.r, max(throughput.g, throughput.b)); - if (rand(seed) > p) { - break; - } + // { + // float p = max(throughput.r, max(throughput.g, throughput.b)); + // if (rand(seed) > p) { + // break; + // } - // Add the energy we 'lose' by randomly terminating paths - throughput *= 1.0 / p; - } + // // Add the energy we 'lose' by randomly terminating paths + // throughput *= 1.0 / p; + // } } bounces++; } - return final_color; + return throughput; } void main() { @@ -322,16 +334,22 @@ void main() { vec2 uv = vec2(float(x) / (width - 1), 1.0 - (float(y) / (height - 1))); uint seed = uint(x * uint(1973) + y * uint(9277) + sample_index * uint(26699)) | uint(1); - vec2 rand_disk = disk_vec(seed); - vec2 jittered_uvs = uv + vec2(rand_disk.x / (width - 1), rand_disk.y / (height - 1)); - vec2 lens_disk = rand_disk * cam.lens_radius; - vec3 offset = lens_disk.x * cam.right.xyz + lens_disk.y * cam.up.xyz; + // vec2 rand_disk = disk_vec(seed); + // vec2 jittered_uvs = uv + vec2(rand(seed) / (width - 1), rand(seed) / (height - 1)); + vec2 jittered_uvs = uv; + // vec2 lens_disk = rand_disk * cam.lens_radius; + // vec3 offset = lens_disk.x * cam.right.xyz + lens_disk.y * cam.up.xyz; + vec3 offset = vec3(0.0); vec4 proj_plane_pos = cam.first_pixel + jittered_uvs.x * cam.horizontal + jittered_uvs.y * cam.vertical; ray r = ray(cam.position.xyz + offset, proj_plane_pos.xyz - cam.position.xyz - offset); 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); + } + float spp_scale = (1.0 / sample_index); vec4 acc_color = imageLoad(accumulation_image, ivec2(x, y)); imageStore(output_image, ivec2(x, y), vec4(mix(acc_color, out_color, spp_scale))); |
