     return a2 / denom;
 }
 
-float GeometrySchlickGGX(float NdotV, float roughness) {
+float GeometrySchlickGGX(float NdotV, float NdotL, float roughness) {
     const float r = (roughness + 1.0);
     const float k = (r * r) / 8.0;
 
-    const float denom = NdotV * (1.0 - k) + k;
-
-    return NdotV / denom;
-}
-
-float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
-    const float NdotV = max(dot(N, V), 0.0);
-    const float NdotL = max(dot(N, L), 0.0);
-    const float ggx2 = GeometrySchlickGGX(NdotV, roughness);
-    const float ggx1 = GeometrySchlickGGX(NdotL, roughness);
-
-    return ggx1 * ggx2;
+    const float GL = NdotL / (NdotL * (1.0 - k) + k);
+    const float GV = NdotV / (NdotV * (1.0 - k) + k);
+
+    return GL * GV;
 }
 
 //////////////////////////////////////////////////////////////////////////////

    return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}

float DistributionGGX(vec3 N, vec3 H, float roughness) {
    const float a = roughness * roughness;
    const float a2 = a * a;
    const float NdotH = max(dot(N, H), 0.0);
    const float NdotH2 = NdotH * NdotH;

    float denom = (NdotH2 * (a2 - 1.0) + 1.0);

    const vec3 textureValue = texture(textureMetallicRoughness, TEXTURE_METALLIC_ROUGHNESS_UV).rgb;

    const float metallic = material.metallic * textureValue.b;
    const float roughness = max(material.roughness * textureValue.g, 0.05);
    # else
    const float metallic = material.metallic;
    const float roughness = max(material.roughness, 0.05);
    #endif

    //////////////////////////////////////////////////////////////////////
