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:
parent
e9b05ff849
commit
6a04888a3c
|
@ -6,11 +6,12 @@
|
|||
const float kPi = 3.1415926;
|
||||
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
|
||||
|
||||
#ifndef BRDF_GLTF2
|
||||
#ifdef BRDF_COMPARE
|
||||
#include "brdf.h"
|
||||
#else
|
||||
struct MaterialProperties {
|
||||
|
@ -108,8 +109,9 @@ material = f_diffuse + f_specular
|
|||
out_diffuse = vec3(0.);
|
||||
out_specular = vec3(0.);
|
||||
|
||||
//if (g_mat_gltf2) {
|
||||
#ifdef BRDF_GLTF2
|
||||
#ifdef BRDF_COMPARE
|
||||
if (g_mat_gltf2) {
|
||||
#endif
|
||||
const float alpha = material.roughness * material.roughness;
|
||||
const float a2 = alpha * alpha;
|
||||
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 vec3 fresnel = vec3(1.) * fresnel_factor + f0 * (1. - fresnel_factor);
|
||||
|
||||
out_diffuse = (vec3(1.) - fresnel) * kOneOverPi * diffuse_color;
|
||||
out_specular = fresnel * ggxD(a2, h_dot_n) * ggxV(a2, l_dot_n, h_dot_l, n_dot_v, h_dot_v);
|
||||
//} else {
|
||||
#else
|
||||
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) * l_dot_n;
|
||||
#ifdef BRDF_COMPARE
|
||||
} else {
|
||||
// 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
|
||||
//if (data.Vbackfacing || data.Lbackfacing) return vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Eval specular and diffuse BRDFs
|
||||
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);
|
||||
|
||||
// Combine specular and diffuse layers
|
||||
|
@ -152,7 +157,7 @@ material = f_diffuse + f_specular
|
|||
// Specular is already multiplied by F, just attenuate diffuse
|
||||
out_diffuse *= vec3(1.) - data.F;
|
||||
#endif
|
||||
//}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,9 @@ void main() {
|
|||
material.metalness = material_data.g;
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue