 
 uniform samplerCube skybox;
 uniform sampler2D   skysphere;
+
+float saturate(float v) { return clamp(v, 0.0, 1.0); }
+vec3 saturate(vec3 v) { return clamp(v, 0.0, 1.0); }
 
 struct Material
 {

    float roughness    = material.roughness;
    float reflectivity = material.fresnel;
    float metallic     = material.metallic;
    float NdotL        = max(dot(normal, lightDir), 0.0);

    // Calculate visibility
    float visibility = 1.0 - shadowFactor;

vec3 BRDF(vec3 N, vec3 L, vec3 V, vec3 baseColor, float metallic, float roughness, float reflectivity)
{
    vec3  H     = normalize(L + V);
    float NdotL = saturate(dot(N, L));
    float NdotH = max(1e-5, dot(N, H));
    float NdotV = max(1e-5, dot(N, V));
    float VdotH = clamp(dot(V, H), 1e-5, 1.0);

    // Specular vs Diffuse
    vec3 C0 = baseColor * metallic + vec3(1.0) * (1.0 - metallic);
