TriVoxel: Burley + (EON, Gotanda, Chan) Diffuse Models
This commit is contained in:
@ -88,6 +88,199 @@ vec3 lambertDiffuseBRDF(const vec3 albedo, const float nl) {
|
||||
return albedo * INV_PI * nl;
|
||||
}
|
||||
|
||||
#ifdef _BurleyDiffuse
|
||||
vec3 burleyDiffuseBRDF(const vec3 albedo, const float roughness,
|
||||
const float dotNL, const float dotNV, const float dotVH) {
|
||||
float nl = clamp(dotNL, 0.0, 1.0);
|
||||
float nv = clamp(dotNV, 0.0, 1.0);
|
||||
float energyBias = mix(0.0, 0.5, roughness);
|
||||
float energyFactor = mix(1.0, 1.0 / 1.51, roughness);
|
||||
float fd90 = energyBias + 2.0 * roughness * dotVH * dotVH;
|
||||
float lightScatter = 1.0 + (fd90 - 1.0) * pow(1.0 - nl, 5.0);
|
||||
float viewScatter = 1.0 + (fd90 - 1.0) * pow(1.0 - nv, 5.0);
|
||||
return albedo * INV_PI * lightScatter * viewScatter * energyFactor * nl;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EONDiffuse
|
||||
const float constant1_FON = 0.5 - 2.0 / (3.0 * PI);
|
||||
const float constant2_FON = 2.0 / 3.0 - 28.0 / (15.0 * PI);
|
||||
|
||||
float E_FON_approx(float mu, float r) {
|
||||
float mucomp = 1.0 - mu;
|
||||
const float g1 = 0.0571085289;
|
||||
const float g2 = 0.491881867;
|
||||
const float g3 = -0.332181442;
|
||||
const float g4 = 0.0714429953;
|
||||
float GoverPi = mucomp * (g1 + mucomp * (g2 + mucomp * (g3 + mucomp * g4)));
|
||||
return (1.0 + r * GoverPi) / (1.0 + constant1_FON * r);
|
||||
}
|
||||
|
||||
vec3 eonDiffuseBRDF(const vec3 albedo, const float roughness,
|
||||
const float dotNL, const float dotNV, const float dotVH) {
|
||||
float r = roughness;
|
||||
float mu_i = clamp(dotNL, 0.0, 1.0);
|
||||
float mu_o = clamp(dotNV, 0.0, 1.0);
|
||||
if (mu_i < 1.0e-7 || mu_o < 1.0e-7) return vec3(0.0);
|
||||
float dotLV = 2.0 * dotVH * dotVH - 1.0;
|
||||
float s = dotLV - mu_i * mu_o;
|
||||
float sovertF = s > 0.0 ? s / max(mu_i, mu_o) : s;
|
||||
float AF = 1.0 / (1.0 + constant1_FON * r);
|
||||
vec3 f_ss = (albedo * INV_PI) * AF * (1.0 + r * sovertF);
|
||||
float EFo = E_FON_approx(mu_o, r);
|
||||
float EFi = E_FON_approx(mu_i, r);
|
||||
float avgEF = AF * (1.0 + constant2_FON * r);
|
||||
vec3 rho_ms = (albedo * albedo) * avgEF
|
||||
/ max(vec3(1.0) - albedo * (1.0 - avgEF), vec3(1.0e-7));
|
||||
const float eps = 1.0e-7;
|
||||
vec3 f_ms = (rho_ms * INV_PI)
|
||||
* max(eps, 1.0 - EFo)
|
||||
* max(eps, 1.0 - EFi)
|
||||
/ max(eps, 1.0 - avgEF);
|
||||
return (f_ss + f_ms) * mu_i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _GotandaDiffuse
|
||||
vec3 gotandaDiffuseBRDF(const vec3 albedo, const float roughness, const vec3 f0,
|
||||
const float dotNL, const float dotNV, const float dotVH) {
|
||||
float nl = clamp(dotNL, 0.0, 1.0);
|
||||
float nv = clamp(dotNV, 0.0, 1.0);
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float dotLV = 2.0 * dotVH * dotVH - 1.0;
|
||||
float Cosri = dotLV - nv * nl;
|
||||
float a2_13 = a2 + 1.36053;
|
||||
float Fr = (1.0 - (0.542026 * a2 + 0.303573 * a) / a2_13)
|
||||
* (1.0 - pow(1.0 - nv, 5.0 - 4.0 * a2) / a2_13)
|
||||
* ((-0.733996 * a2 * a + 1.50912 * a2 - 1.16402 * a)
|
||||
* pow(1.0 - nv, 1.0 + 1.0 / (39.0 * a2 * a2 + 1.0)) + 1.0);
|
||||
float Lm = (max(1.0 - 2.0 * a, 0.0) * (1.0 - pow(1.0 - nl, 5.0))
|
||||
+ min(2.0 * a, 1.0)) * (1.0 - 0.5 * a * (nl - 1.0)) * nl;
|
||||
float Vd = (a2 / ((a2 + 0.09) * (1.31072 + 0.995584 * nv)))
|
||||
* (1.0 - pow(1.0 - nl,
|
||||
(1.0 - 0.3726732 * nv * nv)
|
||||
/ (0.188566 + 0.38841 * nv)));
|
||||
float Bp = Cosri < 0.0 ? 1.4 * nv * nl * Cosri : Cosri;
|
||||
vec3 Lr = (21.0 / 20.0) * (1.0 - f0) * (Fr * Lm + Vd + Bp);
|
||||
return max(albedo * INV_PI * Lr, vec3(0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _ChanDiffuse
|
||||
vec3 chanDiffuseBRDF(const vec3 albedo, const float roughness,
|
||||
const float dotNL, const float dotNV, const float dotVH) {
|
||||
float nl = clamp(dotNL, 0.0, 1.0);
|
||||
float nv = clamp(dotNV, 0.0, 1.0);
|
||||
float vh = clamp(dotVH, 0.0, 1.0);
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float g = clamp((1.0 / 18.0) * log2(2.0 / max(a2, 1e-7) - 1.0), 0.0, 1.0);
|
||||
float dotNH = clamp((nl + nv) / max(2.0 * vh, 1e-5), 0.0, 1.0);
|
||||
float F0 = vh + pow(1.0 - vh, 5.0);
|
||||
float FdV = 1.0 - 0.75 * pow(1.0 - nv, 5.0);
|
||||
float FdL = 1.0 - 0.75 * pow(1.0 - nl, 5.0);
|
||||
float Fd = mix(F0, FdV * FdL, clamp(2.2 * g - 0.5, 0.0, 1.0));
|
||||
float Fb = ((34.5 * g - 59.0) * g + 24.5) * vh
|
||||
* exp2(-max(73.2 * g - 21.2, 8.9) * sqrt(dotNH));
|
||||
float Lobe = clamp(Fd + Fb, 0.0, 1.0);
|
||||
return albedo * INV_PI * Lobe * nl;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 diffuseBRDF(const vec3 albedo, const float roughness, const vec3 f0,
|
||||
const float dotNL, const float dotNV, const float dotVH) {
|
||||
#ifdef _BurleyDiffuse
|
||||
return burleyDiffuseBRDF(albedo, roughness, dotNL, dotNV, dotVH);
|
||||
#elif defined(_EONDiffuse)
|
||||
return eonDiffuseBRDF(albedo, roughness, dotNL, dotNV, dotVH);
|
||||
#elif defined(_GotandaDiffuse)
|
||||
return gotandaDiffuseBRDF(albedo, roughness, f0, dotNL, dotNV, dotVH);
|
||||
#elif defined(_ChanDiffuse)
|
||||
return chanDiffuseBRDF(albedo, roughness, dotNL, dotNV, dotVH);
|
||||
#else
|
||||
return lambertDiffuseBRDF(albedo, dotNL);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 lambertDiffuseIBL(const vec3 albedo) {
|
||||
return albedo;
|
||||
}
|
||||
|
||||
#ifdef _BurleyDiffuse
|
||||
vec3 burleyDiffuseIBL(const vec3 albedo, const float roughness, const float dotNV) {
|
||||
float nv = clamp(dotNV, 0.0, 1.0);
|
||||
float energyBias = mix(0.0, 0.5, roughness);
|
||||
float energyFactor = mix(1.0, 1.0 / 1.51, roughness);
|
||||
float fd90 = energyBias + 2.0 * roughness * nv * nv;
|
||||
float viewScatter = 1.0 + (fd90 - 1.0) * pow(1.0 - nv, 5.0);
|
||||
return albedo * viewScatter * energyFactor;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EONDiffuse
|
||||
vec3 eonDiffuseIBL(const vec3 albedo, const float roughness, const float dotNV) {
|
||||
float r = roughness;
|
||||
float AF = 1.0 / (1.0 + constant1_FON * r);
|
||||
float EF = E_FON_approx(clamp(dotNV, 0.0, 1.0), r);
|
||||
float avgEF = AF * (1.0 + constant2_FON * r);
|
||||
vec3 rho_ms = (albedo * albedo) * avgEF
|
||||
/ max(vec3(1.0) - albedo * (1.0 - avgEF), vec3(1.0e-7));
|
||||
return max(albedo * EF + rho_ms * (1.0 - EF), vec3(0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _GotandaDiffuse
|
||||
vec3 gotandaDiffuseIBL(const vec3 albedo, const float roughness, const vec3 f0, const float dotNV) {
|
||||
float nv = clamp(dotNV, 0.0, 1.0);
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float a2_13 = a2 + 1.36053;
|
||||
float Fr = (1.0 - (0.542026 * a2 + 0.303573 * a) / a2_13)
|
||||
* (1.0 - pow(1.0 - nv, 5.0 - 4.0 * a2) / a2_13)
|
||||
* ((-0.733996 * a2 * a + 1.50912 * a2 - 1.16402 * a)
|
||||
* pow(1.0 - nv, 1.0 + 1.0 / (39.0 * a2 * a2 + 1.0)) + 1.0);
|
||||
float Lm = (max(1.0 - 2.0 * a, 0.0) * (1.0 - pow(1.0 - nv, 5.0))
|
||||
+ min(2.0 * a, 1.0)) * (1.0 - 0.5 * a * (nv - 1.0)) * nv;
|
||||
float Vd = (a2 / ((a2 + 0.09) * (1.31072 + 0.995584 * nv)))
|
||||
* (1.0 - pow(1.0 - nv,
|
||||
(1.0 - 0.3726732 * nv * nv)
|
||||
/ (0.188566 + 0.38841 * nv)));
|
||||
float Cosri = 1.0 - nv * nv;
|
||||
float Bp = Cosri;
|
||||
vec3 Lr = (21.0 / 20.0) * (1.0 - f0) * (Fr * Lm + Vd + Bp);
|
||||
return max(albedo * Lr, vec3(0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _ChanDiffuse
|
||||
vec3 chanDiffuseIBL(const vec3 albedo, const float roughness, const float dotNV) {
|
||||
float nv = clamp(dotNV, 0.0, 1.0);
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float g = clamp((1.0 / 18.0) * log2(2.0 / max(a2, 1e-7) - 1.0), 0.0, 1.0);
|
||||
float FdV = 1.0 - 0.75 * pow(1.0 - nv, 5.0);
|
||||
float Fd = mix(1.0, FdV * FdV, clamp(2.2 * g - 0.5, 0.0, 1.0));
|
||||
float Fb = ((34.5 * g - 59.0) * g + 24.5)
|
||||
* exp2(-max(73.2 * g - 21.2, 8.9) * sqrt(nv));
|
||||
return albedo * clamp(Fd + Fb, 0.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 diffuseIBL(const vec3 albedo, const float roughness, const vec3 f0, const float dotNV) {
|
||||
#ifdef _BurleyDiffuse
|
||||
return burleyDiffuseIBL(albedo, roughness, dotNV);
|
||||
#elif defined(_EONDiffuse)
|
||||
return eonDiffuseIBL(albedo, roughness, dotNV);
|
||||
#elif defined(_GotandaDiffuse)
|
||||
return gotandaDiffuseIBL(albedo, roughness, f0, dotNV);
|
||||
#elif defined(_ChanDiffuse)
|
||||
return chanDiffuseIBL(albedo, roughness, dotNV);
|
||||
#else
|
||||
return lambertDiffuseIBL(albedo);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 surfaceAlbedo(const vec3 baseColor, const float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
@ -131,15 +131,15 @@ vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV
|
||||
#ifdef _Anisotropy
|
||||
if (abs(anisotropy) > 0.001 && dot(tangent, tangent) > 0.001) {
|
||||
vec3 bitangent = normalize(cross(n, tangent));
|
||||
standard = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
standard = diffuseBRDF(albedo, rough, f0, dotNL, dotNV, dotVH) +
|
||||
anisotropicBRDF(f0, rough, anisotropy, anisoRot,
|
||||
tangent, bitangent, n, l, v, dotNL, dotNV) * spec;
|
||||
} else {
|
||||
standard = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
standard = diffuseBRDF(albedo, rough, f0, dotNL, dotNV, dotVH) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
}
|
||||
#else
|
||||
standard = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
standard = diffuseBRDF(albedo, rough, f0, dotNL, dotNV, dotVH) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#endif
|
||||
|
||||
|
||||
@ -83,16 +83,16 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
|
||||
vec3 direct;
|
||||
if (abs(anisotropy) > 0.001 && dot(tangent, tangent) > 0.001) {
|
||||
vec3 bitangent = normalize(cross(n, tangent));
|
||||
direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
direct = diffuseBRDF(albedo, rough, f0, dotNL, dotNV, dotVH) +
|
||||
anisotropicBRDF(f0, rough, anisotropy, anisoRot,
|
||||
tangent, bitangent, n, l, v, dotNL, dotNV) * spec;
|
||||
} else {
|
||||
direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
direct = diffuseBRDF(albedo, rough, f0, dotNL, dotNV, dotVH) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
}
|
||||
#else
|
||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
vec3 direct = diffuseBRDF(albedo, rough, f0, dotNL, dotNV, dotVH) +
|
||||
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#endif
|
||||
|
||||
#ifdef _ExtBRDF
|
||||
|
||||
Reference in New Issue
Block a user