From c24761cfaf0d4c510504e6ddc08f6a8399295cac Mon Sep 17 00:00:00 2001 From: ladevieq Date: Wed, 29 Sep 2021 00:30:13 +0200 Subject: Functions that fill triangle structure from id --- shaders/compute.comp | 74 +++++++++++++++++---------------------------------- 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; } -- cgit v1.3