pex-renderer
Version:
Physically Based Renderer for Pex
75 lines (62 loc) • 2.71 kB
JavaScript
module.exports = /* glsl */ `
uniform float uClearCoat;
uniform float uClearCoatRoughness;
uniform sampler2D uClearCoatNormalMap;
uniform float uClearCoatNormalMapScale;
uniform mat3 uClearCoatNormalMapTexCoordTransform;
void getClearCoatNormal(inout PBRData data) {
vec2 texCoord = getTextureCoordinates(data, CLEAR_COAT_NORMAL_MAP_TEX_COORD_INDEX, uClearCoatNormalMapTexCoordTransform);
vec2 texCoord = getTextureCoordinates(data, CLEAR_COAT_NORMAL_MAP_TEX_COORD_INDEX);
vec3 normalMap = texture2D(uClearCoatNormalMap, texCoord).rgb * 2.0 - 1.0;
normalMap.y *= uClearCoatNormalMapScale;
normalMap = normalize(normalMap);
vec3 N = normalize(data.normalView);
vec3 V = normalize(data.eyeDirView);
vec3 normalView;
vec3 bitangent = cross(N, data.tangentView.xyz) * sign(data.tangentView.w);
mat3 TBN = mat3(data.tangentView.xyz, bitangent, N);
normalView = normalize(TBN * normalMap);
normalMap.xy *= float(gl_FrontFacing) * 2.0 - 1.0;
// make the output normalView match glTF expected right handed orientation
normalMap.y *= -1.0;
normalView = perturb(normalMap, N, V, texCoord);
data.clearCoatNormal = normalize(vec3(data.inverseViewMatrix * vec4(normalView, 0.0)));
}
void getClearCoatNormal(inout PBRData data) {
// geometric normal without perturbation from normalMap
// this normal is in world space
data.clearCoatNormal = normalize(vec3(data.inverseViewMatrix * vec4(normalize(data.normalView), 0.0)));
}
// IOR = 1.5, F0 = 0.04
// as material is no longer in contact with air we calculate new IOR on the
// clear coat and material interface
vec3 f0ClearCoatToSurface(const vec3 f0) {
return saturate(f0 * (f0 * (0.941892 - 0.263008 * f0) + 0.346479) - 0.0285998);
}
float clearCoatBRDF(const PBRData data, const vec3 h, float NoH, float LoH, out float Fcc) {
float clearCoatNoH = saturate(dot(data.clearCoatNormal, h));
float clearCoatNoH = NoH;
float D = D_GGX(data.clearCoatLinearRoughness, clearCoatNoH, h, data.normalWorld);
float V = V_Kelemen(LoH);
// air-polyurethane interface has IOR = 1.5 -> F0 = 0.04
float F = F_Schlick(0.04, 1.0, LoH) * uClearCoat;
Fcc = F;
return D * V * F;
}
`