lygia
/v1.1.6
/lighting
/pbr
)simple PBR shading model
Dependencies:
lygia
/v1.1.6
/math
/saturate
.glsl
lygia
/v1.1.6
/color
/tonemap
.glsl
lygia
/v1.1.6
/lighting
/material
.glsl
lygia
/v1.1.6
/lighting
/envMap
.glsl
lygia
/v1.1.6
/lighting
/fresnelReflection
.glsl
lygia
/v1.1.6
/lighting
/light
/new
.glsl
lygia
/v1.1.6
/lighting
/light
/resolve
.glsl
lygia
/v1.1.6
/lighting
/reflection
.glsl
lygia
/v1.1.6
/lighting
/common
/specularAO
.glsl
lygia
/v1.1.6
/lighting
/common
/envBRDFApprox
.glsl
Use:
<vec4> pbr( <Material> _material )
#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 ssao = 1.0;
// #if defined(FNC_SSAO) && defined(SCENE_DEPTH) && defined(RESOLUTION) && defined(CAMERA_NEAR_CLIP) && defined(CAMERA_FAR_CLIP)
// vec2 pixel = 1.0/RESOLUTION;
// ssao = 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, ssao);
vec3 Fr = vec3(0.0, 0.0, 0.0);
Fr = envMap(M) * E * 2.0;
#if !defined(PLATFORM_RPI)
Fr += tonemap( fresnelReflection(M) ) * M.metallic * (1.0-M.roughness) * 0.2;
#endif
Fr *= specularAO(M, diffuseAO);
vec3 Fd = diffuseColor;
#if defined(SCENE_SH_ARRAY)
Fd *= tonemap( sphericalHarmonics(M.normal) );
#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);
// TODO:
// - Add support for multiple lights
//
{
#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
}
// 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:
lygia
/v1.1.6
/lighting
/material
.glsl
lygia
/v1.1.6
/lighting
/fresnelReflection
.glsl
lygia
/v1.1.6
/lighting
/light
/point
.glsl
lygia
/v1.1.6
/lighting
/light
/directional
.glsl
lygia
/v1.1.6
/lighting
/reflection
.glsl
lygia
/v1.1.6
/lighting
/common
/specularAO
.glsl
lygia
/v1.1.6
/lighting
/common
/envBRDFApprox
.glsl
lygia
/v1.1.6
/lighting
/envMap
.glsl
lygia
/v1.1.6
/lighting
/UnityLightingCommon
.glsl
Use:
<float4> pbr( <Material> _material )
#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_POSITION
#if defined(UNITY_COMPILER_HLSL)
#define LIGHT_POSITION _WorldSpaceLightPos0.xyz
#else
#define LIGHT_POSITION 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
#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);
float3 N = _mat.normal; // Normal
float3 V = normalize(CAMERA_POSITION - _mat.position); // View
float NoV = dot(N, V); // Normal . View
float f0 = max(_mat.f0.r, max(_mat.f0.g, _mat.f0.b));
float roughness = _mat.roughness;
float3 R = reflection(V, N, roughness);
// Ambient Occlusion
// ------------------------
float ssao = 1.0;
// #if defined(FNC_SSAO) && defined(SCENE_DEPTH) && defined(RESOLUTION) && defined(CAMERA_NEAR_CLIP) && defined(CAMERA_FAR_CLIP)
// float2 pixel = 1.0/RESOLUTION;
// ssao = ssao(SCENE_DEPTH, gl_FragCoord.xy*pixel, pixel, 1.);
// #endif
float diffAO = min(_mat.ambientOcclusion, ssao);
float specAO = specularAO(NoV, diffAO, roughness);
// Global Ilumination ( mage Based Lighting )
// ------------------------
float3 E = envBRDFApprox(specularColor, NoV, roughness);
// This is a bit of a hack to pop the metalics
float specIntensity = (2.0 * _mat.metallic) *
saturate(-1.1 + NoV + _mat.metallic) * // Fresnel
(_mat.metallic + (.95 - _mat.roughness) * 2.0); // make smaller highlights brighter
float3 Fr = float3(0.0, 0.0, 0.0);
Fr = tonemap( envMap(R, roughness, _mat.metallic) ) * E * specIntensity;
Fr += tonemap( fresnelReflection(R, _mat.f0, NoV) ) * _mat.metallic * (1.0-roughness) * 0.2;
Fr *= specAO;
float3 Fd = float3(0.0, 0.0, 0.0);
Fd = diffuseColor;
#if defined(UNITY_COMPILER_HLSL)
Fd *= ShadeSH9(half4(N,1));
#elif defined(SCENE_SH_ARRAY)
Fd *= tonemap( sphericalHarmonics(N) );
#endif
Fd *= diffAO;
Fd *= (1.0 - E);
// Local Ilumination
// ------------------------
float3 lightDiffuse = float3(0.0, 0.0, 0.0);
float3 lightSpecular = float3(0.0, 0.0, 0.0);
{
#ifdef LIGHT_DIRECTION
lightDirectional(diffuseColor, specularColor, N, V, NoV, roughness, f0, _mat.shadow, lightDiffuse, lightSpecular);
#elif defined(LIGHT_POSITION)
lightPoint(diffuseColor, specularColor, N, V, NoV, roughness, f0, _mat.shadow, lightDiffuse, lightSpecular);
#endif
}
// Final Sum
// ------------------------
float4 color = float4(0.0, 0.0, 0.0, 1.0);
color.rgb += Fd * IBL_LUMINANCE + lightDiffuse; // Diffuse
color.rgb += Fr * IBL_LUMINANCE + lightSpecular; // Specular
color.rgb *= _mat.ambientOcclusion;
color.rgb += _mat.emissive;
color.a = _mat.albedo.a;
return color;
}
#endif
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.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository