aboutsummaryrefslogtreecommitdiffstats
path: root/shaders/compute.comp
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2021-09-01 00:18:04 +0200
committerladevieq <ladevie.quentin@gmail.com>2021-09-01 00:18:04 +0200
commitbf512216323f3df55627421bb0187ed364d58340 (patch)
tree2ae215cdf1bacf925efb7a52975d49351274cf30 /shaders/compute.comp
parentd071fc5c947689eca7726803a420013c519acdd9 (diff)
White furnace test on gltf scenes & load normals
Diffstat (limited to 'shaders/compute.comp')
-rw-r--r--shaders/compute.comp103
1 files changed, 69 insertions, 34 deletions
diff --git a/shaders/compute.comp b/shaders/compute.comp
index 7454589..0d5c525 100644
--- a/shaders/compute.comp
+++ b/shaders/compute.comp
@@ -25,8 +25,7 @@ const uint DIFFUSE = 1;
const uint SPECULAR = 2;
struct material {
- vec4 albedo;
- vec4 emissive;
+ vec4 base_color;
float metalness;
float roughness;
uint[2] padding;
@@ -35,7 +34,8 @@ struct material {
struct hit_info {
float t;
vec3 point;
- vec3 normal;
+ vec3 geometry_normal;
+ vec3 shading_normal;
material mat;
};
@@ -48,6 +48,7 @@ struct sphere {
struct vertex {
vec4 position;
+ vec4 normal;
};
struct triangle {
@@ -93,8 +94,8 @@ layout(buffer_reference) readonly buffer scene_metadata {
};
layout(buffer_reference) readonly buffer primitives_array {
- sphere[] spheres;
- // triangle triangles[];
+ // sphere[] spheres;
+ triangle triangles[];
};
layout(buffer_reference) readonly buffer nodes_array {
@@ -232,12 +233,12 @@ bool hit_sphere(sphere s, ray r, out hit_info info) {
}
info.t = root;
- info.point = at(r, info.t);
+ // info.point = at(r, info.t);
- vec3 outward_normal = (info.point - s.position.xyz) / s.radius;
- bool front_face = dot(outward_normal, r.direction) < 0.0;
- info.normal = front_face ? outward_normal : -outward_normal;
- info.mat = s.mat;
+ // vec3 outward_normal = (info.point - s.position.xyz) / s.radius;
+ // bool front_face = dot(outward_normal, r.direction) < 0.0;
+ // info.normal = front_face ? outward_normal : -outward_normal;
+ // info.mat = s.mat;
return true;
}
@@ -259,7 +260,7 @@ bool hit_triangle(triangle tri, ray r, out hit_info info) {
}
info.t = t;
- info.normal = normal;
+ info.geometry_normal = normalize(normal);
return true;
}
@@ -272,16 +273,16 @@ bool hit_node(ray r, out hit_info info) {
while(id != -1) {
// Leafs
if (bufs.bvh.nodes[id].primitive_id != -1) {
- if (hit_sphere(bufs.geometry.spheres[bufs.bvh.nodes[id].primitive_id], r, temp_info)) {
- info = temp_info;
- r.max_t = temp_info.t;
- hit = true;
- }
- // if (hit_triangle(bufs.geometry.triangles[bufs.bvh.nodes[id].primitive_id], r, temp_info)) {
+ // if (hit_sphere(bufs.geometry.spheres[bufs.bvh.nodes[id].primitive_id], r, temp_info)) {
// info = temp_info;
// r.max_t = temp_info.t;
// hit = true;
// }
+ if (hit_triangle(bufs.geometry.triangles[bufs.bvh.nodes[id].primitive_id], r, temp_info)) {
+ info = temp_info;
+ r.max_t = temp_info.t;
+ hit = true;
+ }
id = bufs.bvh.nodes[id].next_id;
} else if (hit_aabb(bufs.bvh.nodes[id].min, bufs.bvh.nodes[id].max, r)) {
id++;
@@ -294,12 +295,12 @@ bool hit_node(ray r, out hit_info info) {
return hit;
}
-vec3 albedo_to_specular_F0(vec3 albedo, float metalness) {
- return mix(vec3(MIN_DIELECTRICS_F0), albedo, metalness);
+vec3 base_color_to_specular_F0(vec3 base_color, float metalness) {
+ return mix(vec3(MIN_DIELECTRICS_F0), base_color, metalness);
}
-vec3 albedo_to_diffuse_reflectance(vec3 albedo, float metalness) {
- return albedo * (1.0f - metalness);
+vec3 base_color_to_diffuse_reflectance(vec3 base_color, float metalness) {
+ return base_color * (1.0f - metalness);
}
// Schlick's approximation to Fresnel term
@@ -325,12 +326,12 @@ float shadowed_F90(vec3 F0) {
return min(1.f, t * luminance(F0));
}
-float get_brdf_probability(material mat, vec3 view, vec3 shadingNormal) {
+float get_brdf_probability(material mat, vec3 view, vec3 shading_normal) {
// Evaluate Fresnel term using the shading normal
// Note: we use the shading normal instead of the microfacet normal (half-vector) for Fresnel term here. That's suboptimal for rough surfaces at grazing angles, but half-vector is yet unknown at this point
- vec3 specular_F0 = vec3(luminance(albedo_to_specular_F0(mat.albedo.rgb, mat.metalness)));
- float diffuse_reflectance = luminance(albedo_to_diffuse_reflectance(mat.albedo.rgb, mat.metalness));
- float fresnel = clamp(luminance(eval_fresnel(specular_F0, shadowed_F90(specular_F0), max(0.0f, dot(view, shadingNormal)))), 0.0, 1.0);
+ vec3 specular_F0 = vec3(luminance(base_color_to_specular_F0(mat.base_color.rgb, mat.metalness)));
+ float diffuse_reflectance = luminance(base_color_to_diffuse_reflectance(mat.base_color.rgb, mat.metalness));
+ float fresnel = clamp(luminance(eval_fresnel(specular_F0, shadowed_F90(specular_F0), max(0.0f, dot(view, shading_normal)))), 0.0, 1.0);
// Approximate relative contribution of BRDFs using the Fresnel term
float specular = fresnel;
@@ -352,34 +353,68 @@ vec3 ray_color(ray r, uint seed) {
if (!hit_node(r, info))
return throughput * vec3(1.0);
- // uint brdf_type;
+ vec3 v = -r.direction;
+
+ 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;
+
+ uint brdf_type;
// if (info.mat.metalness == 1.f && info.mat.metalness == 0.f) {
// brdf_type = SPECULAR;
// } else {
- // float brdf_probability = get_brdf_probability(info.mat, -r.direction, );
+ // float brdf_probability = get_brdf_probability(info.mat, -r.direction, info.shading_normal);
// if (rand(seed) < brdf_probability) {
// brdf_type = SPECULAR;
+ // throughput /= brdf_probability;
// } else {
// brdf_type = DIFFUSE;
+ // throughput /= (1.0 - brdf_probability);
// }
// }
+ brdf_type = DIFFUSE;
+
+ // Ignore ray coming from below the hemisphere
+ // if (dot(info.shading_normal, v) <= 0.f) break;
+
// Move to tangent space
- vec4 rotation_to_z = rotation_to_z_axis(info.normal);
+ vec4 rotation_to_z = rotation_to_z_axis(info.geometry_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 = sample_hemisphere(seed);
+ vec3 ray_dir_local;
+ vec3 brdf_weight;
+
+ if (brdf_type == DIFFUSE) {
+ ray_dir_local = sample_hemisphere(seed);
- float NdotL = dot(normal_local, ray_dir_local);
- float pdf = NdotL / PI;
- vec3 brdf = albedo_to_diffuse_reflectance(info.mat.albedo.xyz, info.mat.metalness) / PI;
- throughput *= brdf / pdf;
+ float NdotL = dot(normal_local, ray_dir_local);
+ float pdf = NdotL / PI;
+ // vec3 brdf = base_color_to_diffuse_reflectance(info.mat.base_color.xyz, info.mat.metalness) / PI;
+ vec3 brdf = (vec3(1.0) * NdotL) / PI;
+ brdf_weight = brdf / pdf;
+ } else if (brdf_type == SPECULAR) {
+ // alpha = info.mat.roughness * info.mat.roughness;
+
+ // vec3 half_local;
+ // if (alpha == 0.0f) {
+ // // Fast path for zero roughness (perfect reflection), also prevents NaNs appearing due to divisions by zeroes
+ // half_local = vec3(0.0f, 0.0f, 1.0f);
+ // } else {
+ // // For non-zero roughness, this calls VNDF sampling for GG-X distribution or Walter's sampling for Beckmann distribution
+ // half_local = sampleSpecularHalfVector(view_local, vec2(alpha));
+ // }
+ }
+
+ throughput *= brdf_weight;
// Move to global space
vec4 rotation_from_z = invert_rotation(rotation_to_z);
vec3 ray_dir = rotate_point(rotation_from_z, ray_dir_local);
- r = ray(info.point, normalize(info.normal + ray_dir), 0.001f, 1e15);
+ if (dot(info.geometry_normal, ray_dir) <= 0.0f) break;
+
+ r = ray(info.point, ray_dir, 0.001f, 1e15);
// Russian Roulette
// As the throughput gets smaller, the ray is more likely to get terminated early.