aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shaders/compute.comp74
-rw-r--r--shaders/include/ray.h73
2 files changed, 83 insertions, 64 deletions
diff --git a/shaders/compute.comp b/shaders/compute.comp
index 2663592..c8257cf 100644
--- a/shaders/compute.comp
+++ b/shaders/compute.comp
@@ -43,9 +43,10 @@ struct vertex {
};
struct triangle {
- vertex v1;
- vertex v2;
- vertex v3;
+ vertex v1;
+ vertex v2;
+ vertex v3;
+ material mat;
};
struct camera {
@@ -141,60 +142,35 @@ vec3 ray_color(ray r, uint seed) {
// TODO: Interpolation function & indices decoding function
- uint id1 = bufs.indices_arr.indices[info.id * 3] & 0x00ffffff;
- uint id2 = bufs.indices_arr.indices[info.id * 3 + 1] & 0x00ffffff;
- uint id3 = bufs.indices_arr.indices[info.id * 3 + 2] & 0x00ffffff;
- uint mat_id = (bufs.indices_arr.indices[info.id * 3] & 0xff000000) >> 8
- | (bufs.indices_arr.indices[info.id * 3 + 1] & 0xff000000) >> 16
- | (bufs.indices_arr.indices[info.id * 3 + 2] & 0xff000000) >> 24;
-
- vec3 p1 = vec3(bufs.positions_arr.positions[id1 * 3], bufs.positions_arr.positions[id1 * 3 + 1], bufs.positions_arr.positions[id1 * 3 + 2]);
- vec3 p2 = vec3(bufs.positions_arr.positions[id2 * 3], bufs.positions_arr.positions[id2 * 3 + 1], bufs.positions_arr.positions[id2 * 3 + 2]);
- vec3 p3 = vec3(bufs.positions_arr.positions[id3 * 3], bufs.positions_arr.positions[id3 * 3 + 1], bufs.positions_arr.positions[id3 * 3 + 2]);
-
- vec3 n1 = vec3(bufs.normals_arr.normals[id1 * 3], bufs.normals_arr.normals[id1 * 3 + 1], bufs.normals_arr.normals[id1 * 3 + 2]);
- vec3 n2 = vec3(bufs.normals_arr.normals[id2 * 3], bufs.normals_arr.normals[id2 * 3 + 1], bufs.normals_arr.normals[id2 * 3 + 2]);
- vec3 n3 = vec3(bufs.normals_arr.normals[id3 * 3], bufs.normals_arr.normals[id3 * 3 + 1], bufs.normals_arr.normals[id3 * 3 + 2]);
-
- vec2 uv1 = vec2(bufs.uvs_arr.uvs[id1 * 2], bufs.uvs_arr.uvs[id1 * 2 + 1]);
- vec2 uv2 = vec2(bufs.uvs_arr.uvs[id2 * 2], bufs.uvs_arr.uvs[id2 * 2 + 1]);
- vec2 uv3 = vec2(bufs.uvs_arr.uvs[id3 * 2], bufs.uvs_arr.uvs[id3 * 2 + 1]);
+ triangle tri = get_triangle(info.primitive_id);
- vertex v1 = vertex(p1, n1, uv1);
- vertex v2 = vertex(p2, n2, uv2);
- vertex v3 = vertex(p3, n3, uv3);
+ vec3 shading_normal = normalize(tri.v1.normal * info.barycentrics.x + tri.v2.normal * info.barycentrics.y + tri.v3.normal * info.barycentrics.z);
+ vec2 uv = tri.v1.uv * info.barycentrics.x + tri.v2.uv * info.barycentrics.y + tri.v3.uv * info.barycentrics.z;
- triangle tri = triangle(v1, v2, v3);
-
- info.shading_normal = normalize(tri.v1.normal * info.barycentrics.x + tri.v2.normal * info.barycentrics.y + tri.v3.normal * info.barycentrics.z);
- info.uv = tri.v1.uv * info.barycentrics.x + tri.v2.uv * info.barycentrics.y + tri.v3.uv * info.barycentrics.z;
-
- material mat = bufs.materials_arr.materials[mat_id];
- info.color = srgb_to_linear(texture(
+ vec3 diffuse_color = srgb_to_linear(texture(
sampler2D(
- textures[nonuniformEXT(mat.base_color_texture.texture_id)],
- samplers[nonuniformEXT(mat.base_color_texture.sampler_id)]
- ), info.uv
- ).xyz) * mat.base_color.xyz;
- info.metalness_roughness = texture(
+ textures[nonuniformEXT(tri.mat.base_color_texture.texture_id)],
+ samplers[nonuniformEXT(tri.mat.base_color_texture.sampler_id)]
+ ), uv
+ ).xyz) * tri.mat.base_color.xyz;
+ vec2 metalness_roughness = texture(
sampler2D(
- textures[nonuniformEXT(mat.metallic_roughness_texture.texture_id)],
- samplers[nonuniformEXT(mat.metallic_roughness_texture.sampler_id)]
- ), info.uv
- ).xy * vec2(mat.metalness, mat.roughness);
+ textures[nonuniformEXT(tri.mat.metallic_roughness_texture.texture_id)],
+ samplers[nonuniformEXT(tri.mat.metallic_roughness_texture.sampler_id)]
+ ), uv
+ ).xy * vec2(tri.mat.metalness, tri.mat.roughness);
if (dot(info.geometry_normal, v) < 0.f) info.geometry_normal = -info.geometry_normal;
-
- if (dot(info.geometry_normal, info.shading_normal) < 0.0f) info.shading_normal = -info.shading_normal;
+ if (dot(info.geometry_normal, shading_normal) < 0.0f) shading_normal = -shading_normal;
uint brdf_type;
- if (info.metalness_roughness.x == 1.f && info.metalness_roughness.y == 0.f) {
+ if (metalness_roughness.x == 1.f && metalness_roughness.y == 0.f) {
brdf_type = SPECULAR;
} else {
- float brdf_probability = get_brdf_probability(info.color, info.metalness_roughness.x, -r.direction, info.shading_normal);
+ float brdf_probability = get_brdf_probability(diffuse_color, metalness_roughness.x, -r.direction, shading_normal);
if (rand(seed) < brdf_probability) {
brdf_type = SPECULAR;
throughput /= brdf_probability;
@@ -205,10 +181,10 @@ vec3 ray_color(ray r, uint seed) {
}
// Ignore ray coming from below the hemisphere
- if (dot(info.shading_normal, v) <= 0.f) break;
+ if (dot(shading_normal, v) <= 0.f) break;
// Move to tangent space
- vec4 rotation_to_z = rotation_to_z_axis(info.shading_normal);
+ vec4 rotation_to_z = rotation_to_z_axis(shading_normal);
vec3 view_local = rotate_point(rotation_to_z, -r.direction);
vec3 normal_local = vec3(0.0, 0.0, 1.0);
vec3 ray_dir_local;
@@ -217,9 +193,9 @@ vec3 ray_color(ray r, uint seed) {
if (brdf_type == DIFFUSE) { // Lambertian diffuse
vec2 r = vec2(rand(seed), rand(seed));
ray_dir_local = sample_hemisphere(r);
- sample_weight = base_color_to_diffuse_reflectance(info.color, info.metalness_roughness.x);
+ sample_weight = base_color_to_diffuse_reflectance(diffuse_color, metalness_roughness.x);
} else if (brdf_type == SPECULAR) {
- float alpha = info.metalness_roughness.y * info.metalness_roughness.y;
+ float alpha = metalness_roughness.y * metalness_roughness.y;
float alpha_squared = alpha * alpha;
vec3 half_local;
@@ -234,7 +210,7 @@ vec3 ray_color(ray r, uint seed) {
// Reflect view direction to obtain light vector
vec3 light_local = reflect(-view_local, half_local);
- vec3 specular_F0 = base_color_to_diffuse_reflectance(info.color, info.metalness_roughness.x);
+ vec3 specular_F0 = base_color_to_diffuse_reflectance(diffuse_color, metalness_roughness.x);
// Note: HdotL is same as HdotV here
// Clamp dot products here to small value to prevent numerical instability.
diff --git a/shaders/include/ray.h b/shaders/include/ray.h
index 38e5c16..3732c42 100644
--- a/shaders/include/ray.h
+++ b/shaders/include/ray.h
@@ -13,14 +13,61 @@ struct hit_info {
vec3 point;
vec3 barycentrics;
vec3 geometry_normal;
- vec3 shading_normal;
- vec3 color;
- vec2 metalness_roughness;
- vec2 uv;
float t;
- uint id;
+ uint primitive_id;
};
+uvec4 decode_triangle_indices(uint triangle_id) {
+ uint id1 = bufs.indices_arr.indices[triangle_id * 3] & 0x00ffffff;
+ uint id2 = bufs.indices_arr.indices[triangle_id * 3 + 1] & 0x00ffffff;
+ uint id3 = bufs.indices_arr.indices[triangle_id * 3 + 2] & 0x00ffffff;
+
+ uint mat_id = (bufs.indices_arr.indices[triangle_id * 3] & 0xff000000) >> 8
+ | (bufs.indices_arr.indices[triangle_id * 3 + 1] & 0xff000000) >> 16
+ | (bufs.indices_arr.indices[triangle_id * 3 + 2] & 0xff000000) >> 24;
+
+ return uvec4(id1, id2, id3, mat_id);
+}
+
+vec3[3] get_triangle_positions(uvec3 indices) {
+ return vec3[3](
+ vec3(bufs.positions_arr.positions[indices[0] * 3], bufs.positions_arr.positions[indices[0] * 3 + 1], bufs.positions_arr.positions[indices[0] * 3 + 2]),
+ vec3(bufs.positions_arr.positions[indices[1] * 3], bufs.positions_arr.positions[indices[1] * 3 + 1], bufs.positions_arr.positions[indices[1] * 3 + 2]),
+ vec3(bufs.positions_arr.positions[indices[2] * 3], bufs.positions_arr.positions[indices[2] * 3 + 1], bufs.positions_arr.positions[indices[2] * 3 + 2])
+ );
+}
+
+vec3[3] get_triangle_normals(uvec3 indices) {
+ return vec3[3](
+ vec3(bufs.normals_arr.normals[indices[0] * 3], bufs.normals_arr.normals[indices[0] * 3 + 1], bufs.normals_arr.normals[indices[0] * 3 + 2]),
+ vec3(bufs.normals_arr.normals[indices[1] * 3], bufs.normals_arr.normals[indices[1] * 3 + 1], bufs.normals_arr.normals[indices[1] * 3 + 2]),
+ vec3(bufs.normals_arr.normals[indices[2] * 3], bufs.normals_arr.normals[indices[2] * 3 + 1], bufs.normals_arr.normals[indices[2] * 3 + 2])
+ );
+}
+
+vec2[3] get_triangle_uvs(uvec3 indices) {
+ return vec2[3](
+ vec2(bufs.uvs_arr.uvs[indices[0] * 2], bufs.uvs_arr.uvs[indices[0] * 2 + 1]),
+ vec2(bufs.uvs_arr.uvs[indices[1] * 2], bufs.uvs_arr.uvs[indices[1] * 2 + 1]),
+ vec2(bufs.uvs_arr.uvs[indices[2] * 2], bufs.uvs_arr.uvs[indices[2] * 2 + 1])
+ );
+}
+
+triangle get_triangle(uint triangle_id) {
+ uvec4 indices = decode_triangle_indices(triangle_id);
+ vec3 positions[3] = get_triangle_positions(indices.xyz);
+ vec3 normals[3] = get_triangle_normals(indices.xyz);
+ vec2 uvs[3] = get_triangle_uvs(indices.xyz);
+
+ vertex v1 = vertex(positions[0], normals[0], uvs[0]);
+ vertex v2 = vertex(positions[1], normals[1], uvs[1]);
+ vertex v3 = vertex(positions[2], normals[2], uvs[2]);
+ return triangle(
+ v1, v2, v3,
+ bufs.materials_arr.materials[indices.w]
+ );
+}
+
bool hit_aabb(vec3 minimum, vec3 maximum, ray r) {
const vec3 invdir = 1.0 / r.direction;
const vec3 f = (maximum.xyz - r.origin.xyz) * invdir;
@@ -93,18 +140,14 @@ bool hit_sphere(sphere s, ray r, out hit_info info) {
}
bool hit_triangle(uint id, ray r, out hit_info info) {
- uint id1 = bufs.indices_arr.indices[id * 3] & 0x00ffffff;
- uint id2 = bufs.indices_arr.indices[id * 3 + 1] & 0x00ffffff;
- uint id3 = bufs.indices_arr.indices[id * 3 + 2] & 0x00ffffff;
+ uvec4 indices = decode_triangle_indices(id);
- vec3 p1 = vec3(bufs.positions_arr.positions[id1 * 3], bufs.positions_arr.positions[id1 * 3 + 1], bufs.positions_arr.positions[id1 * 3 + 2]);
- vec3 p2 = vec3(bufs.positions_arr.positions[id2 * 3], bufs.positions_arr.positions[id2 * 3 + 1], bufs.positions_arr.positions[id2 * 3 + 2]);
- vec3 p3 = vec3(bufs.positions_arr.positions[id3 * 3], bufs.positions_arr.positions[id3 * 3 + 1], bufs.positions_arr.positions[id3 * 3 + 2]);
+ vec3 positions[3] = get_triangle_positions(indices.xyz);
- vec3 v2v1 = p2 - p1;
- vec3 v3v1 = p3 - p1;
+ vec3 v2v1 = positions[1] - positions[0];
+ vec3 v3v1 = positions[2] - positions[0];
- vec3 originv1 = r.origin - p1;
+ vec3 originv1 = r.origin - positions[0];
vec3 normal = cross(v2v1, v3v1);
vec3 q = cross(originv1, r.direction);
float d = 1.0 / dot(r.direction, normal);
@@ -119,7 +162,7 @@ bool hit_triangle(uint id, ray r, out hit_info info) {
info.t = t;
info.barycentrics = vec3(1 - u - v, u, v);
info.geometry_normal = normalize(normal);
- info.id = id;
+ info.primitive_id = id;
return true;
}