LYGIA Shader Library

cookTorrance (lygia/lighting/specular/cookTorrance)

Dependencies:

Check it on Github


#ifndef SPECULAR_POW
#if defined(TARGET_MOBILE) || defined(PLATFORM_RPI) || defined(PLATFORM_WEBGL)
#define SPECULAR_POW(A,B) powFast(A,B)
#else
#define SPECULAR_POW(A,B) pow(A,B)
#endif
#endif

#ifndef SPECULAR_COOKTORRANCE_DIFFUSE_FNC
#if defined(PLATFORM_RPI)
#define SPECULAR_COOKTORRANCE_DIFFUSE_FNC beckmann
#else
#define SPECULAR_COOKTORRANCE_DIFFUSE_FNC GGX
#endif
#endif 

#ifndef FNC_SPECULAR_COOKTORRANCE
#define FNC_SPECULAR_COOKTORRANCE
// https://github.com/glslify/glsl-specular-cook-torrance
float specularCookTorrance(const in vec3 _L, const in vec3 _N, const in vec3 _V, const in float _NoV, const in float _NoL, const in float _roughness, const in float _fresnel) {
    float NoV = max(_NoV, 0.0);
    float NoL = max(_NoL, 0.0);

    // Half angle vector
    vec3 H = normalize(_L + _V);

    // Geometric term
    float NoH = max(dot(_N, H), 0.0);
    float VoH = max(dot(_V, H), 0.000001);

    float x = 2.0 * NoH / VoH;
    float G = min(1.0, min(x * NoV, x * NoL));

    // Distribution term
    float D = SPECULAR_COOKTORRANCE_DIFFUSE_FNC(_N, H, NoH, _roughness);

    // Fresnel term
    float F = SPECULAR_POW(1.0 - NoV, _fresnel);

    // Multiply terms and done
    return max(G * F * D / max(PI * NoV * NoL, 0.00001), 0.0);
}

float specularCookTorrance(vec3 L, vec3 N, vec3 V, float roughness, float fresnel) {
    return specularCookTorrance(L, N, V, dot(N, V), dot(N, L), roughness, fresnel);
}

float specularCookTorrance(vec3 L, vec3 N, vec3 V, float roughness) {
    return specularCookTorrance(L, N, V, roughness, 0.04);
}

#endif

Dependencies:

Check it on Github



#ifndef SPECULAR_POW
#if defined(TARGET_MOBILE) || defined(PLATFORM_RPI) || defined(PLATFORM_WEBGL)
#define SPECULAR_POW(A,B) powFast(A,B)
#else
#define SPECULAR_POW(A,B) pow(A,B)
#endif
#endif

#ifndef FNC_SPECULAR_COOKTORRANCE
#define FNC_SPECULAR_COOKTORRANCE

// https://github.com/stackgl/glsl-specular-cook-torrance
float specularCookTorrance(float3 _L, float3 _N, float3 _V, float _NoV, float _NoL, float _roughness, float _fresnel) {
    float NoV = max(_NoV, 0.0);
    float NoL = max(_NoL, 0.0);

    //Half angle vector
    float3 H = normalize(_L + _V);

    //Geometric term
    float NoH = max(dot(_N, H), 0.0);
    float VoH = max(dot(_V, H), 0.000001);
    float LoH = max(dot(_L, H), 0.000001);

    float x = 2.0 * NoH / VoH;
    float G = min(1.0, min(x * NoV, x * NoL));

    //Distribution term
    float D = beckmann(NoH, _roughness);

    //Fresnel term
    float F = SPECULAR_POW(1.0 - NoV, _fresnel);

    //Multiply terms and done
    return  max(G * F * D / max(PI * NoV * NoL, 0.000001), 0.0);
}

// https://github.com/glslify/glsl-specular-cook-torrance
float specularCookTorrance(float3 L, float3 N, float3 V, float roughness, float fresnel) {
    float NoV = max(dot(N, V), 0.0);
    float NoL = max(dot(N, L), 0.0);
    return specularCookTorrance(L, N, V, NoV, NoL, roughness, fresnel);
}

float specularCookTorrance(float3 L, float3 N, float3 V, float roughness) {
    return specularCookTorrance(L, N, V, roughness, 0.04);
}

#endif

Dependencies:

Check it on Github


fn specularCookTorrance(L: vec3f, N: vec3f, V: vec3f, NoV: f32, NoL: f32, roughness: f32, fresnel: f32) -> f32 {
    // Half angle vector
    let H = normalize(L + V);

    // Geometric term
    let NoH = max(dot(N, H), 0.0);
    let VoH = max(dot(V, H), 0.000001);

    let x = 2.0 * NoH / VoH;
    let G = min(1.0, min(x * NoV, x * NoL));

    // Distribution term
    let D = GGX(N, H, NoH, roughness);

    // Fresnel term
    let F = pow(1.0 - NoV, fresnel);

    // Multiply terms and done
    return max(G * F * D / max(PI * NoV * NoL, 0.00001), 0.0);
}

License

LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.

Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).

It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository