LYGIA Shader Library

ggx (lygia/lighting/specular/ggx)

Dependencies:

Check it on Github


#ifndef FNC_SPECULAR_GGX
#define FNC_SPECULAR_GGX

float specularGGX(const in vec3 _L, const in vec3 _N, const in vec3 _V, float _NoV, float _NoL, float _roughness, float _fresnel) {
    float NoV = max(_NoV, 0.0);
    float NoL = max(_NoL, 0.0);

    vec3 H = normalize(_L + _V);
    float LoH = saturate(dot(_L, H));
    float NoH = saturate(dot(_N, H));

    // float NoV, float NoL, float roughness
    float linearRoughness =  _roughness * _roughness;
    float D = GGX(NoH, linearRoughness);

#if defined(PLATFORM_RPI)
    float V = smithGGXCorrelated_Fast(_NoV, NoL,linearRoughness);
#else
    float V = smithGGXCorrelated(_NoV, NoL,linearRoughness);
#endif

    float F = fresnel(vec3(_fresnel), LoH).r;

    return (D * V) * F;
}

float specularGGX(vec3 L, vec3 N, vec3 V, float roughness, float fresnel) {
    float NoV = max(dot(N, V), 0.0);
    float NoL = max(dot(N, L), 0.0);
    return specularGGX(L, N, V, NoV, NoL, roughness, fresnel);
}

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

#endif

Dependencies:

Check it on Github

// #include "../common/ggx.hlsl"

#ifndef FNC_SPECULAR_GGX
#define FNC_SPECULAR_GGX

float commonGGX(float NoH, float linearRoughness) {
    float oneMinusNoHSquared = 1.0 - NoH * NoH;
    float a = NoH * linearRoughness;
    float k = linearRoughness / (oneMinusNoHSquared + a * a);
    float d = k * k * INV_PI;
    return saturateMediump(d);
}

float specularGGX(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);

    float3 H = normalize(_L + _V);
    float LoH = saturate(dot(_L, H));
    float NoH = saturate(dot(_N, H));

    // float NoV, float NoL, float roughness
    float linearRoughness =  _roughness * _roughness;
    float D = commonGGX(NoH, linearRoughness);
    float V = smithGGXCorrelated(_NoV, NoL,linearRoughness);
    float F = fresnel(float3(_fresnel, _fresnel, _fresnel), LoH).r;

    return (D * V) * F;
}

float specularGGX(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 specularGGX(L, N, V, NoV, NoL, roughness, fresnel);
}

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

#endif

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