#pragma glslify: beckmannDistribution = require(glsl-specular-beckmann/distribution) float cookTorranceSpecular( vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal, float roughness, float fresnel) { float VdotN = max(dot(viewDirection, surfaceNormal), 0.0); float LdotN = max(dot(lightDirection, surfaceNormal), 0.0); //Half angle vector vec3 H = normalize(lightDirection + viewDirection); //Geometric term float NdotH = max(dot(surfaceNormal, H), 0.0); float VdotH = max(dot(viewDirection, H), 0.0001); float LdotH = max(dot(lightDirection, H), 0.0001); float G1 = (2.0 * NdotH * VdotN) / VdotH; float G2 = (2.0 * NdotH * LdotN) / LdotH; float G = min(1.0, min(G1, G2)); //Distribution term float D = beckmannDistribution(NdotH, roughness); //Fresnel term float F = pow(1.0 - VdotN, fresnel); //Multiply terms and done return G * F * D / (3.14159265 * VdotN); } #pragma glslify: export(cookTorranceSpecular)