vk: rt: fix artifacts due to missing dot(N,L) term

We missed it because BRDF model of glTF 2.0 expects this term to be in
the rendering equation integral, and not in the BRDF function itself.

Boksajak's `brdf.h` model does include this term in the BRDF because the
cancel out for some usages beautifully.

Also, add comparison macro so we can see old-vs-new PBR model.
This commit is contained in:
Ivan Avdeev 2024-01-04 09:56:04 -05:00
parent e9b05ff849
commit 6a04888a3c
2 changed files with 20 additions and 13 deletions

View File

@ -6,11 +6,12 @@
const float kPi = 3.1415926; const float kPi = 3.1415926;
const float kOneOverPi = 1. / kPi; const float kOneOverPi = 1. / kPi;
// bool g_mat_gltf2 = true; #define BRDF_COMPARE
#ifdef BRDF_COMPARE
bool g_mat_gltf2 = true;
#endif
#define BRDF_GLTF2 #ifdef BRDF_COMPARE
#ifndef BRDF_GLTF2
#include "brdf.h" #include "brdf.h"
#else #else
struct MaterialProperties { struct MaterialProperties {
@ -108,8 +109,9 @@ material = f_diffuse + f_specular
out_diffuse = vec3(0.); out_diffuse = vec3(0.);
out_specular = vec3(0.); out_specular = vec3(0.);
//if (g_mat_gltf2) { #ifdef BRDF_COMPARE
#ifdef BRDF_GLTF2 if (g_mat_gltf2) {
#endif
const float alpha = material.roughness * material.roughness; const float alpha = material.roughness * material.roughness;
const float a2 = alpha * alpha; const float a2 = alpha * alpha;
const vec3 H = normalize(L + V); const vec3 H = normalize(L + V);
@ -133,18 +135,21 @@ material = f_diffuse + f_specular
const float fresnel_factor = pow(1. - abs(h_dot_v), 5.); const float fresnel_factor = pow(1. - abs(h_dot_v), 5.);
const vec3 fresnel = vec3(1.) * fresnel_factor + f0 * (1. - fresnel_factor); const vec3 fresnel = vec3(1.) * fresnel_factor + f0 * (1. - fresnel_factor);
out_diffuse = (vec3(1.) - fresnel) * kOneOverPi * diffuse_color; out_diffuse = (vec3(1.) - fresnel) * kOneOverPi * diffuse_color * l_dot_n;
out_specular = fresnel * ggxD(a2, h_dot_n) * ggxV(a2, l_dot_n, h_dot_l, n_dot_v, h_dot_v); out_specular = fresnel * ggxD(a2, h_dot_n) * ggxV(a2, l_dot_n, h_dot_l, n_dot_v, h_dot_v) * l_dot_n;
//} else { #ifdef BRDF_COMPARE
#else } else {
// Prepare data needed for BRDF evaluation - unpack material properties and evaluate commonly used terms (e.g. Fresnel, NdotL, ...) // Prepare data needed for BRDF evaluation - unpack material properties and evaluate commonly used terms (e.g. Fresnel, NdotL, ...)
const BrdfData data = prepareBRDFData(N, L, V, material); BrdfData data = prepareBRDFData(N, L, V, material);
// Ignore V and L rays "below" the hemisphere // Ignore V and L rays "below" the hemisphere
//if (data.Vbackfacing || data.Lbackfacing) return vec3(0.0f, 0.0f, 0.0f); //if (data.Vbackfacing || data.Lbackfacing) return vec3(0.0f, 0.0f, 0.0f);
// Eval specular and diffuse BRDFs // Eval specular and diffuse BRDFs
out_specular = evalSpecular(data); out_specular = evalSpecular(data);
// Our renderer mixes base_color into diffuse component later in denoiser/smesitel
data.diffuseReflectance = baseColorToDiffuseReflectance(vec3(1.), material.metalness);
out_diffuse = evalDiffuse(data); out_diffuse = evalDiffuse(data);
// Combine specular and diffuse layers // Combine specular and diffuse layers
@ -152,7 +157,7 @@ material = f_diffuse + f_specular
// Specular is already multiplied by F, just attenuate diffuse // Specular is already multiplied by F, just attenuate diffuse
out_diffuse *= vec3(1.) - data.F; out_diffuse *= vec3(1.) - data.F;
#endif #endif
//} }
#endif #endif
} }

View File

@ -40,7 +40,9 @@ void main() {
material.metalness = material_data.g; material.metalness = material_data.g;
material.roughness = material_data.r; material.roughness = material_data.r;
//g_mat_gltf2 = pix.y > ubo.ubo.res.y / 2.; #ifdef BRDF_COMPARE
g_mat_gltf2 = pix.x > ubo.ubo.res.x / 2.;
#endif
const vec4 pos_t = imageLoad(position_t, pix); const vec4 pos_t = imageLoad(position_t, pix);