LYGIA Shader Library

pbr (lygia/lighting/pbr)

Simple PBR shading model

Dependencies:

Use:

<vec4> pbr( <Material> _material )

Check it on Github




#if defined(RAYMARCH_AO)
#endif


#ifndef CAMERA_POSITION
#define CAMERA_POSITION vec3(0.0, 0.0, -10.0)
#endif

#ifndef IBL_LUMINANCE
#define IBL_LUMINANCE   1.0
#endif

#ifndef FNC_PBR
#define FNC_PBR

vec4 pbr(const in Material _mat) {
    // Calculate Color
    vec3    diffuseColor = _mat.albedo.rgb * (vec3(1.0) - _mat.f0) * (1.0 - _mat.metallic);
    vec3    specularColor = mix(_mat.f0, _mat.albedo.rgb, _mat.metallic);

    // Cached
    Material M  = _mat;
    M.V         = normalize(CAMERA_POSITION - M.position);  // View
    M.NoV       = dot(M.normal, M.V);                       // Normal . View
    M.R         = reflection(M.V, M.normal, M.roughness);   // Reflection

    // Ambient Occlusion
    // ------------------------
    float ao = 1.0;

    #if defined(RAYMARCH_AO)
    ao = raymarchAO(M.position, M.normal);
    #endif

// #if defined(FNC_SSAO) && defined(SCENE_DEPTH) && defined(RESOLUTION) && defined(CAMERA_NEAR_CLIP) && defined(CAMERA_FAR_CLIP)
//     vec2 pixel = 1.0/RESOLUTION;
//     ao = ssao(SCENE_DEPTH, gl_FragCoord.xy*pixel, pixel, 1.);
// #endif 

    // Global Ilumination ( Image Based Lighting )
    // ------------------------
    vec3 E = envBRDFApprox(specularColor, M);
    float diffuseAO = min(M.ambientOcclusion, ao);

    vec3 Fr = vec3(0.0, 0.0, 0.0);
    Fr  = envMap(M) * E;
    #if !defined(PLATFORM_RPI)
    Fr  += fresnelReflection(M);
    #endif
    Fr  *= specularAO(M, diffuseAO);

    vec3 Fd = diffuseColor;
    #if defined(SCENE_SH_ARRAY)
    Fd  *= tonemap( sphericalHarmonics(M.normal) );
    #else
    Fd *= envMap(M.normal, 0.8); // a roughness of 0.8 visually matches the factors returned by Unity's ShadeSH9
    #endif
    Fd  *= diffuseAO;
    Fd  *= (1.0 - E);

    // Local Ilumination
    // ------------------------
    vec3 lightDiffuse = vec3(0.0, 0.0, 0.0);
    vec3 lightSpecular = vec3(0.0, 0.0, 0.0);

    {
        #if defined(LIGHT_DIRECTION)
        LightDirectional L = LightDirectionalNew();
        lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);
        #elif defined(LIGHT_POSITION)
        LightPoint L = LightPointNew();
        lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);
        #endif

        #if defined(LIGHT_POINTS) && defined(LIGHT_POINTS_TOTAL)
        for (int i = 0; i < LIGHT_POINTS_TOTAL; i++) {
            LightPoint L = LIGHT_POINTS[i];
            lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);
        }
        #endif
    }


    // Final Sum
    // ------------------------
    vec4 color  = vec4(0.0, 0.0, 0.0, 1.0);

    // Diffuse
    color.rgb  += Fd * IBL_LUMINANCE;
    color.rgb  += lightDiffuse;

    // Specular
    color.rgb  += Fr * IBL_LUMINANCE;
    color.rgb  += lightSpecular;    
    color.rgb  *= M.ambientOcclusion;
    color.rgb  += M.emissive;
    color.a     = M.albedo.a;

    return color;
}
#endif

Dependencies:

Use:

<float4> pbr( <Material> _material )

Check it on Github

#ifndef CAMERA_POSITION
#if defined(UNITY_COMPILER_HLSL)
#define CAMERA_POSITION _WorldSpaceCameraPos
#else
#define CAMERA_POSITION float3(0.0, 0.0, -10.0)
#endif
#endif

#ifndef LIGHT_DIRECTION
#if defined(UNITY_COMPILER_HLSL)
#define LIGHT_DIRECTION _WorldSpaceLightPos0.xyz
#else
#define LIGHT_DIRECTION float3(0.0, 10.0, -50.0)
#endif
#endif

#ifndef LIGHT_COLOR
#if defined(UNITY_COMPILER_HLSL)
#define LIGHT_COLOR     _LightColor0.rgb
#else
#define LIGHT_COLOR     float3(0.5, 0.5, 0.5)
#endif
#endif

#ifndef IBL_LUMINANCE
#define IBL_LUMINANCE   1.0
#endif




#if defined(RAYMARCH_AO)
#endif


#ifndef FNC_PBR
#define FNC_PBR

float4 pbr(const Material _mat) {
    // Calculate Color
    float3 diffuseColor = _mat.albedo.rgb * (float3(1.0, 1.0, 1.0) - _mat.f0) * (1.0 - _mat.metallic);
    float3 specularColor = lerp(_mat.f0, _mat.albedo.rgb, _mat.metallic);

    // Cached
    Material M = _mat;
    M.V = normalize(CAMERA_POSITION - M.position); // View
    M.NoV = dot(M.normal, M.V); // Normal . View
    M.R = reflection(M.V, M.normal, M.roughness); // Reflection

    // Ambient Occlusion
    // ------------------------
    float ao = 1.0;

    #if defined(RAYMARCH_AO)
    ao = raymarchAO(M.position, M.normal);
    #endif

// #if defined(FNC_SSAO) && defined(SCENE_DEPTH) && defined(RESOLUTION) && defined(CAMERA_NEAR_CLIP) && defined(CAMERA_FAR_CLIP)
//     vec2 pixel = 1.0/RESOLUTION;
//     ao = ssao(SCENE_DEPTH, gl_FragCoord.xy*pixel, pixel, 1.);
// #endif 

    // Global Ilumination ( Image Based Lighting )
    // ------------------------
    float3 E = envBRDFApprox(specularColor, M);
    float diffuseAO = min(M.ambientOcclusion, ao);

    float3 Fr = float3(0.0, 0.0, 0.0);
    Fr = envMap(M) * E;
    #if !defined(PLATFORM_RPI)
    Fr  += fresnelReflection(M);
    #endif
    Fr  *= specularAO(M, diffuseAO);

    float3 Fd = diffuseColor;
    #if defined(SCENE_SH_ARRAY)
    Fd  *= tonemap( sphericalHarmonics(M.normal) );
    //#elif defined(UNITY_COMPILER_HLSL)
    // Fd *= ShadeSH9(half4(M.normal,1));
    #else
    Fd *= envMap(M.normal, 0.8); // a roughness of 0.8 visually matches the factors returned by Unity's ShadeSH9
    #endif
    Fd  *= diffuseAO;
    Fd  *= (1.0 - E);

    // Local Ilumination
    // ------------------------
    float3 lightDiffuse = float3(0.0, 0.0, 0.0);
    float3 lightSpecular = float3(0.0, 0.0, 0.0);

    {
        #if defined(LIGHT_DIRECTION)
        LightDirectional L = LightDirectionalNew();
        lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);
        #elif defined(LIGHT_POSITION)
        LightPoint L = LightPointNew();
        lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);
        #endif

        #if defined(LIGHT_POINTS) && defined(LIGHT_POINTS_TOTAL)
        for (int i = 0; i < LIGHT_POINTS_TOTAL; i++) {
            LightPoint L = LIGHT_POINTS[i];
            lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);
        }
        #endif
    }

    // Final Sum
    // ------------------------
    float4 color = float4(0.0, 0.0, 0.0, 1.0);

    // Diffuse
    color.rgb += Fd * IBL_LUMINANCE;
    color.rgb += lightDiffuse;

    // Specular
    color.rgb += Fr * IBL_LUMINANCE;
    color.rgb += lightSpecular;
    color.rgb *= M.ambientOcclusion;
    color.rgb += M.emissive;
    color.a = M.albedo.a;

    return color;
}
#endif

Examples

Licenses

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