lygia
/lighting
/pbr
)Simple PBR shading model
Dependencies:
lygia
/math
/saturate
.glsl
lygia
/color
/tonemap
.glsl
lygia
/lighting
/material
.glsl
lygia
/lighting
/envMap
.glsl
lygia
/lighting
/fresnelReflection
.glsl
lygia
/lighting
/sphericalHarmonics
.glsl
lygia
/lighting
/light
/new
.glsl
lygia
/lighting
/light
/resolve
.glsl
lygia
/lighting
/reflection
.glsl
lygia
/lighting
/common
/specularAO
.glsl
lygia
/lighting
/common
/envBRDFApprox
.glsl
lygia
/lighting
/raymarch
/ao
.glsl
Use:
<vec4> pbr( <Material> _material )
#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:
lygia
/lighting
/UnityLightingCommon
.glsl
lygia
/color
/tonemap
.glsl
lygia
/lighting
/material
.glsl
lygia
/lighting
/envMap
.glsl
lygia
/lighting
/fresnelReflection
.glsl
lygia
/lighting
/sphericalHarmonics
.glsl
lygia
/lighting
/light
/new
.glsl
lygia
/lighting
/light
/resolve
.glsl
lygia
/lighting
/reflection
.glsl
lygia
/lighting
/common
/specularAO
.glsl
lygia
/lighting
/common
/envBRDFApprox
.glsl
lygia
/lighting
/raymarch
/ao
.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_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
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