aboutsummaryrefslogtreecommitdiffstats
path: root/shaders/compute.comp
diff options
context:
space:
mode:
Diffstat (limited to 'shaders/compute.comp')
-rw-r--r--shaders/compute.comp130
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)));