LYGIA Shader Library

pbrGlass (lygia/lighting/pbrGlass)

Simple glass shading model

Dependencies:

Use:

<vec4> glass(<Material> material)

Check it on Github







#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_PBRGLASS
#define FNC_PBRGLASS

vec4 pbrGlass(const Material mat, ShadingData shadingData) {
    // Shading Data
    // ------------
#if defined(SCENE_BACK_SURFACE)
    vec3 No     = normalize(mat.normal - mat.normal_back); // Normal out is the difference between the front and back normals
#else
    vec3 No     = mat.normal;                            // Normal out
#endif
    vec3 eta    = ior2eta(mat.ior);
    vec3 f0     = vec3(0.04, 0.04, 0.04);
    shadingData.N = mat.normal;
    shadingData.R = reflection(shadingData.V,  shadingData.N, mat.roughness);
    shadingData.roughness = mat.roughness; 
    shadingData.linearRoughness = mat.roughness;
    shadingData.specularColor = mat.albedo.rgb;
    shadingData.NoV = dot(No, shadingData.V);

    // Indirect Lights ( Image Based Lighting )
    // ----------------------------------------
    vec3 E = envBRDFApprox(shadingData);
    vec3 Gi = envMap(mat, shadingData) * E;

    #if defined(SHADING_MODEL_IRIDESCENCE)
    vec3 Fr = vec3(0.0, 0.0, 0.0);
    Gi  += fresnelIridescentReflection(mat.normal, -shadingData.V, f0, vec3(IOR_AIR),
        mat.ior, mat.thickness, mat.roughness, Fr);
    #else
    vec3 Fr = fresnel(f0, shadingData.NoV);
    Gi  += fresnelReflection(shadingData.R, Fr) * (1.0-mat.roughness);
    #endif

    vec4 color  = vec4(0.0, 0.0, 0.0, 1.0);

    // Refraction
    color.rgb   += transparent(No, -shadingData.V, Fr, eta, mat.roughness);
    color.rgb   += Gi * IBL_LUMINANCE * mat.ambientOcclusion;

    // TODO: RaG
    //  - Add support for multiple lights
    // 
    {
        #if defined(LIGHT_DIRECTION)
        LightDirectional L = LightDirectionalNew();
        #elif defined(LIGHT_POSITION)
        LightPoint L = LightPointNew();
        #endif

        #if defined(LIGHT_DIRECTION) || defined(LIGHT_POSITION)

        shadingData.L = L.direction;
        shadingData.H = normalize(L.direction + shadingData.V);
        shadingData.NoL = saturate(dot(shadingData.N, L.direction));
        shadingData.NoH = saturate(dot(shadingData.N, shadingData.H));
        vec3 spec = specular(shadingData);

        color.rgb += L.color * spec;
        #endif
    }

    return color;
}

vec4 pbrGlass(const in Material mat) {
    ShadingData shadingData = shadingDataNew();
    shadingData.V = normalize(CAMERA_POSITION - mat.position);
    return pbrGlass(mat, shadingData);
}

#endif

Dependencies:

Use:

<float4> glass(<Material> material)

Check it on Github







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

#ifndef IBL_LUMINANCE
#define IBL_LUMINANCE   1.0
#endif

#ifndef FNC_PBRGLASS
#define FNC_PBRGLASS

float4 pbrGlass(const Material mat, ShadingData shadingData) {
    // Shading Data
    // ------------
#if defined(SCENE_BACK_SURFACE)
    float3 No     = normalize(mat.normal - mat.normal_back); // Normal out is the difference between the front and back normals
#else
    float3 No     = mat.normal;                            // Normal out
#endif
    float3 eta    = ior2eta(mat.ior);
    float3 f0     = float3(0.04, 0.04, 0.04);
    shadingData.N = mat.normal;
    shadingData.R = reflection(shadingData.V,  shadingData.N, mat.roughness);
    shadingData.roughness = mat.roughness; 
    shadingData.linearRoughness = mat.roughness;
    shadingData.specularColor = mat.albedo.rgb;
    shadingData.NoV = dot(No, shadingData.V);

    // Indirect Lights ( Image Based Lighting )
    // ----------------------------------------
    float3 E = envBRDFApprox(shadingData);

    float3 Gi = envMap(mat, shadingData) * E;

    #if defined(SHADING_MODEL_IRIDESCENCE)
    float3 Fr = float3(0.0, 0.0, 0.0);
    Gi  += fresnelIridescentReflection(mat.normal, -shadingData.V, f0, float3(IOR_AIR),
        mat.ior, mat.thickness, mat.roughness, Fr);
    #else
    float3 Fr = fresnel(f0, shadingData.NoV);
    Gi  += fresnelReflection(shadingData.R, Fr) * (1.0-mat.roughness);
    #endif

    float4 color  = float4(0.0, 0.0, 0.0, 1.0);

    // Refraction
    color.rgb   += transparent(No, -shadingData.V, Fr, eta, mat.roughness);
    color.rgb   += Gi * IBL_LUMINANCE * mat.ambientOcclusion;

    // TODO: RaG
    //  - Add support for multiple lights
    // 
    {
        #if defined(LIGHT_DIRECTION)
        LightDirectional L = LightDirectionalNew();
        #elif defined(LIGHT_POSITION)
        LightPoint L = LightPointNew();
        #endif

        #if defined(LIGHT_DIRECTION) || defined(LIGHT_POSITION)

        shadingData.L = L.direction;
        shadingData.H = normalize(L.direction + shadingData.V);
        shadingData.NoL = saturate(dot(shadingData.N, L.direction));
        shadingData.NoH = saturate(dot(shadingData.N, shadingData.H));
        float3 spec = specular(shadingData);

        color.rgb += L.color * spec;

        #endif
    }

    return color;
}

float4 pbrGlass(const in Material mat) {
    ShadingData shadingData = shadingDataNew();
    shadingData.V = normalize(CAMERA_POSITION - mat.position);
    return pbrGlass(mat, shadingData);
}

#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