diff options
| -rw-r--r-- | shaders/compute.comp | 74 | ||||
| -rw-r--r-- | shaders/include/ray.h | 73 |
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;
}
|
