Created
June 1, 2018 20:25
-
-
Save romainguy/39d4c1c6aac56623399dcd1e8da68337 to your computer and use it in GitHub Desktop.
Anisotropic BRDF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
float D_GGX_Anisotropic(float at, float ab, float ToH, float BoH, float NoH) { | |
// Burley 2012, "Physically-Based Shading at Disney" | |
float a2 = at * ab; | |
vec3 d = vec3(ab * ToH, at * BoH, a2 * NoH); | |
return saturateMediump(a2 * sq(a2 / dot(d, d)) * (1.0 / PI)); | |
} | |
float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float ToV, float BoV, | |
float ToL, float BoL, float NoV, float NoL) { | |
// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs" | |
// TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function | |
float lambdaV = NoL * length(vec3(at * ToV, ab * BoV, NoL)); | |
float lambdaL = NoV * length(vec3(at * ToL, ab * BoL, NoV)); | |
float v = 0.5 / (lambdaV + lambdaL); | |
return saturateMediump(v); | |
} | |
vec3 F_Schlick(const vec3 f0, float f90, float VoH) { | |
// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering" | |
float f = pow5(1.0 - VoH); | |
return f + f0 * (f90 - f); | |
} | |
float distributionAnisotropic(float at, float ab, float ToH, float BoH, float NoH) { | |
return D_GGX_Anisotropic(at, ab, ToH, BoH, NoH); | |
} | |
float visibilityAnisotropic(float linearRoughness, float at, float ab, | |
float ToV, float BoV, float ToL, float BoL, float NoV, float NoL) { | |
return V_SmithGGXCorrelated_Anisotropic(at, ab, ToV, BoV, ToL, BoL, NoV, NoL); | |
} | |
vec3 fresnel(const vec3 f0, float LoH) { | |
return F_Schlick(f0, 1.0, LoH); | |
} | |
vec3 anisotropicLobe(const PixelParams pixel, const Light light, const vec3 h, | |
float NoV, float NoL, float NoH, float LoH) { | |
vec3 l = light.l; | |
vec3 t = pixel.anisotropicT; | |
vec3 b = pixel.anisotropicB; | |
vec3 v = shading_view; | |
float ToV = dot(t, v); | |
float BoV = dot(b, v); | |
float ToL = dot(t, l); | |
float BoL = dot(b, l); | |
float ToH = dot(t, h); | |
float BoH = dot(b, h); | |
// Anisotropic parameters: at and ab are the roughness along the tangent and bitangent | |
// to simplify materials, we derive them from a single roughness parameter | |
// Kulla 2017, "Revisiting Physically Based Shading at Imageworks" | |
float at = max(pixel.linearRoughness * (1.0 + pixel.anisotropy), MIN_LINEAR_ROUGHNESS); | |
float ab = max(pixel.linearRoughness * (1.0 - pixel.anisotropy), MIN_LINEAR_ROUGHNESS); | |
// specular anisotropic BRDF | |
float D = distributionAnisotropic(at, ab, ToH, BoH, NoH); | |
float V = visibilityAnisotropic(pixel.linearRoughness, at, ab, ToV, BoV, ToL, BoL, NoV, NoL); | |
vec3 F = fresnel(pixel.f0, LoH); | |
return (D * V) * F; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment