Skip to content

Commit

Permalink
Merge pull request #153 from shadielhajj/port/pbrclearcoat
Browse files Browse the repository at this point in the history
  • Loading branch information
patriciogonzalezvivo authored Jul 6, 2024
2 parents 5dfdf1a + f2f2247 commit 0168bbb
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 175 deletions.
38 changes: 0 additions & 38 deletions lighting/light/directional.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,6 @@ license:
- Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license
*/

#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)
#include <UnityLightingCommon.cginc>
#define LIGHT_COLOR _LightColor0.rgb
#else
#define LIGHT_COLOR float3(0.5, 0.5, 0.5)
#endif
#endif

#ifndef LIGHT_INTENSITY
#define LIGHT_INTENSITY 1.0
#endif

#ifndef STR_LIGHT_DIRECTIONAL
#define STR_LIGHT_DIRECTIONAL
struct LightDirectional
Expand All @@ -51,23 +30,6 @@ struct LightDirectional
#ifndef FNC_LIGHT_DIRECTIONAL
#define FNC_LIGHT_DIRECTIONAL

void lightDirectional(float3 _diffuseColor, float3 _specularColor, float3 _N, float3 _V, float _NoV, float _roughness, float _f0, float _shadow, inout float3 _diffuse, inout float3 _specular) {
#ifdef LIGHT_DIRECTION
float3 s = normalize(LIGHT_DIRECTION);
#else
float3 s = normalize(LIGHT_POSITION);
#endif
float NoL = dot(_N, s);
float dif = diffuseOrenNayar(s, _N, _V, _NoV, NoL, _roughness);
float spec = specularCookTorrance(s, _N, _V, _NoV, NoL, _roughness, _f0);
_diffuse += max(0.0, LIGHT_INTENSITY * (_diffuseColor * LIGHT_COLOR * dif) * _shadow);
_specular += max(0.0, LIGHT_INTENSITY * (_specularColor * LIGHT_COLOR * spec) * _shadow);
}

// void lightDirectional(float3 _diffuseColor, float3 _specularColor, float3 _N, float3 _V, float _NoV, float _roughness, float _f0, inout float3 _diffuse, inout float3 _specular) {
// return lightDirectional(_diffuseColor, _specularColor, _N, _V, _NoV, _roughness, _f0, 1.0, _diffuse, _specular);
// }

void lightDirectional(
const in float3 _diffuseColor, const in float3 _specularColor,
const in float3 _V,
Expand Down
53 changes: 0 additions & 53 deletions lighting/light/point.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,6 @@ license:
#include "../diffuse.hlsl"
#include "falloff.hlsl"

#ifndef SURFACE_POSITION
#define SURFACE_POSITION float(0.0, 0.0, 0.0)
#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)
#include <UnityLightingCommon.cginc>
#define LIGHT_COLOR _LightColor0.rgb
#else
#define LIGHT_COLOR float3(0.5, 0.5, 0.5)
#endif
#endif

#ifndef LIGHT_INTENSITY
#define LIGHT_INTENSITY 1.0
#endif

#ifndef LIGHT_FALLOFF
#define LIGHT_FALLOFF 0.0
#endif

#ifndef STR_LIGHT_POINT
#define STR_LIGHT_POINT
struct LightPoint
Expand All @@ -61,30 +32,6 @@ struct LightPoint
#ifndef FNC_LIGHT_POINT
#define FNC_LIGHT_POINT

void lightPoint(float3 _diffuseColor, float3 _specularColor, float3 _N, float3 _V, float _NoV, float _roughness, float _f0, float _shadow, inout float3 _diffuse, inout float3 _specular) {
float3 toLight = LIGHT_POSITION - (SURFACE_POSITION).xyz;
float toLightLength = length(toLight);
float3 s = toLight/toLightLength;

float NoL = dot(_N, s);

float dif = diffuse(s, _N, _V, _NoV, NoL, _roughness);// * INV_PI;
float spec = specular(s, _N, _V, _NoV, NoL, _roughness, _f0);

float3 lightContribution = LIGHT_COLOR * LIGHT_INTENSITY * _shadow;
#ifdef LIGHT_FALLOFF
if (LIGHT_FALLOFF > 0.0)
lightContribution *= falloff(toLightLength, LIGHT_FALLOFF);
#endif

_diffuse += _diffuseColor * lightContribution * dif;
_specular += _specularColor * lightContribution * spec;
}

void lightPoint(float3 _diffuseColor, float3 _specularColor, float3 _N, float3 _V, float _NoV, float _roughness, float _f0, inout float3 _diffuse, inout float3 _specular) {
lightPoint(_diffuseColor, _specularColor, _N, _V, _NoV, _roughness, _f0, 1.0, _diffuse, _specular);
}

void lightPoint(
const in float3 _diffuseColor, const in float3 _specularColor,
const in float3 _V,
Expand Down
2 changes: 1 addition & 1 deletion lighting/pbrClearCoat.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ vec4 pbrClearCoat(const Material _mat) {
float specAO = specularAO(M, diffAO);

vec3 Fr = vec3(0.0, 0.0, 0.0);
Fr = envMap(M) * E * 2.0;
Fr = envMap(M) * E;
#if !defined(PLATFORM_RPI)
Fr += fresnelReflection(M);
#endif
Expand Down
166 changes: 83 additions & 83 deletions lighting/pbrClearCoat.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,28 @@ license:
#ifndef FNC_PBRCLEARCOAT
#define FNC_PBRCLEARCOAT

float4 pbrClearCoat(const Material _mat) {
float4 pbrClearCoat(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 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 = saturate(dot(N, V)); // Normal . View
float3 f0 = ior2f0(_mat.ior);
float3 R = reflection(V, N, _mat.roughness);
// 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

float3 f0 = ior2f0(M.ior);
float3 R = reflection(M.V, M.normal, M.roughness);

#if defined(MATERIAL_HAS_NORMAL) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// We want to use the geometric normal for the clear coat layer
float clearCoatNoV = clampNoV(dot(_mat.clearCoatNormal, V));
float3 clearCoatNormal = _mat.clearCoatNormal;
float clearCoatNoV = clampNoV(dot(M.clearCoatNormal, M.V));
float3 clearCoatNormal = M.clearCoatNormal;
#else
float clearCoatNoV = NoV;
float3 clearCoatNormal = N;
float clearCoatNoV = M.NoV;
float3 clearCoatNormal = M.normal;
#endif

// Ambient Occlusion
Expand All @@ -89,113 +93,109 @@ float4 pbrClearCoat(const Material _mat) {
// float2 pixel = 1.0/RESOLUTION;
// ssao = ssao(SCENE_DEPTH, gl_FragCoord.xy*pixel, pixel, 1.);
// #endif
float diffuseAO = min(_mat.ambientOcclusion, ssao);
float specAO = specularAO(NoV, _mat.roughness, diffuseAO);

// Global Ilumination ( mage Based Lighting )
// ------------------------
float3 E = envBRDFApprox(specularColor, NoV, _mat.roughness);
float3 E = envBRDFApprox(specularColor, M);

// 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
// // This is a bit of a hack to pop the metalics
// float specIntensity = (2.0 * M.metallic) *
// saturate(-1.1 + NoV + M.metallic) * // Fresnel
// (M.metallic + (.95 - M.roughness) * 2.0); // make smaller highlights brighter

float diffAO = min(M.ambientOcclusion, ssao);
float specAO = specularAO(M, diffAO);

float3 Fr = float3(0.0, 0.0, 0.0);
Fr = tonemap( envMap(R, _mat.roughness, _mat.metallic) ) * E * specIntensity;
Fr += tonemap( fresnelReflection(R, f0, NoV) ) * _mat.metallic * (1.0-_mat.roughness) * 0.2;
Fr = envMap(M) * E;
#if !defined(PLATFORM_RPI)
Fr += fresnelReflection(M);
#endif
Fr *= specAO;

float3 Fd = float3(0.0, 0.0, 0.0);
Fd = diffuseColor;
float3 Fd = diffuseColor;
#if defined(SCENE_SH_ARRAY)
Fd *= tonemap( sphericalHarmonics(N) );
Fd *= tonemap( sphericalHarmonics(M.normal) );
#endif
Fd *= diffuseAO;
Fd *= diffAO;
Fd *= (1.0 - E);

float3 Fc = fresnel(f0, clearCoatNoV) * _mat.clearCoat;
float3 Fc = fresnel(f0, clearCoatNoV) * M.clearCoat;
float3 attenuation = 1.0 - Fc;
Fd *= attenuation;
Fr *= attenuation;

// float3 clearCoatLobe = isEvaluateSpecularIBL(p, clearCoatNormal, V, clearCoatNoV);
float3 clearCoatR = reflection(V, clearCoatNormal, _mat.clearCoatRoughness);
float3 clearCoatE = envBRDFApprox(f0, clearCoatNoV, _mat.clearCoatRoughness);
float3 clearCoatR = reflection(M.V, clearCoatNormal, M.clearCoatRoughness);
float3 clearCoatE = envBRDFApprox(f0, clearCoatNoV, M.clearCoatRoughness);
float3 clearCoatLobe = float3(0.0, 0.0, 0.0);
clearCoatLobe += tonemap( envMap(clearCoatR, _mat.clearCoatRoughness, 1.0) ) * clearCoatE;
clearCoatLobe += tonemap( fresnelReflection(clearCoatR, f0, clearCoatNoV) ) * (1.0-_mat.clearCoatRoughness);
Fr += clearCoatLobe * (specAO * _mat.clearCoat);
clearCoatLobe += envMap(clearCoatR, M.clearCoatRoughness, 1.0) * clearCoatE * 3.;
clearCoatLobe += tonemap(fresnelReflection(clearCoatR, f0, clearCoatNoV)) * (1.0 - M.clearCoatRoughness) * 0.2;
Fr += clearCoatLobe * (specAO * M.clearCoat);

float4 color = float4(0.0, 0.0, 0.0, 1.0);
color.rgb += Fd * IBL_LUMINANCE; // Diffuse
color.rgb += Fr * IBL_LUMINANCE; // Specular
float4 color = float4(0.0, 0.0, 0.0, 1.0);
color.rgb += Fd * IBL_LUMINANCE; // Diffuse
color.rgb += Fr * IBL_LUMINANCE; // Specular

// LOCAL ILUMINATION
// ------------------------
float3 lightDiffuse = float3(0.0, 0.0, 0.0);
float3 lightSpecular = float3(0.0, 0.0, 0.0);

// TODO:
// - Add support for multiple lights
//
{
#if defined(LIGHT_DIRECTION)
float f0 = max(_mat.f0.r, max(_mat.f0.g, _mat.f0.b));
lightDirectional(diffuseColor, specularColor, N, V, NoV, _mat.roughness, f0, _mat.shadow, lightDiffuse, lightSpecular);
LightDirectional L = LightDirectionalNew();
#elif defined(LIGHT_POSITION)
float f0 = max(_mat.f0.r, max(_mat.f0.g, _mat.f0.b));
lightPoint(diffuseColor, specularColor, N, V, NoV, _mat.roughness , f0, _mat.shadow, lightDiffuse, lightSpecular);
LightPoint L = LightPointNew();
#endif
}

color.rgb += lightDiffuse; // Diffuse
color.rgb += lightSpecular; // Specular

// Clear Coat
#if defined(LIGHT_DIRECTION) || defined(LIGHT_POSITION)
#if defined(LIGHT_DIRECTION)
float3 L = normalize(LIGHT_DIRECTION);
#elif defined(LIGHT_POSITION)
float3 L = normalize(LIGHT_POSITION - _mat.position);
#endif

float3 H = normalize(V + L);
float NoL = saturate(dot(N, L));
float LoH = saturate(dot(L, H));
#if defined(LIGHT_DIRECTION) || defined(LIGHT_POSITION)
lightResolve(diffuseColor, specularColor, M, L, lightDiffuse, lightSpecular);

#if defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// If the material has a normal map, we want to use the geometric normal
// instead to avoid applying the normal map details to the clear coat layer
N = clearCoatNormal;
float clearCoatNoH = saturate(dot(clearCoatNormal, H));
#else
float clearCoatNoH = saturate(dot(N, V));
#endif
color.rgb += lightDiffuse; // Diffuse
color.rgb += lightSpecular; // Specular

// clear coat specular lobe
float D = GGX(N, H, clearCoatNoH, _mat.clearCoatRoughness);
float3 F = fresnel(f0, LoH) * _mat.clearCoat;
float3 Fcc = F;
float3 clearCoat = D *
kelemen(LoH) *
F;
float3 atten = (1.0 - Fcc);

#if defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// If the material has a normal map, we want to use the geometric normal
// instead to avoid applying the normal map details to the clear coat layer
float clearCoatNoL = saturate(dot(clearCoatNormal, L));
color.rgb = color.rgb * atten * NoL + (clearCoat * clearCoatNoL * LIGHT_COLOR) * (LIGHT_INTENSITY * _mat.shadow);
#else
// color.rgb = color.rgb * atten + (clearCoat * LIGHT_COLOR) * (LIGHT_INTENSITY * NoL * _mat.shadow);
color.rgb = color.rgb + (clearCoat * LIGHT_COLOR) * (LIGHT_INTENSITY * NoL * _mat.shadow);
#endif
float3 h = normalize(M.V + L.direction);
float NoH = saturate(dot(M.normal, h));
float NoL = saturate(dot(M.normal, L.direction));
float LoH = saturate(dot(L.direction, h));

#endif
#if defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// If the material has a normal map, we want to use the geometric normal
// instead to avoid applying the normal map details to the clear coat layer
N = clearCoatNormal;
float clearCoatNoH = saturate(dot(clearCoatNormal, h));
#else
float clearCoatNoH = saturate(dot(M.normal, M.V));
#endif

// clear coat specular lobe
float D = GGX(M.normal, h, clearCoatNoH, M.clearCoatRoughness);
float3 F = fresnel(f0, LoH) * M.clearCoat;

float3 Fcc = F;
float3 clearCoat = float3(D, D, D) * kelemen(LoH); // * F;
float3 atten = (1.0 - Fcc);

#if defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// If the material has a normal map, we want to use the geometric normal
// instead to avoid applying the normal map details to the clear coat layer
float clearCoatNoL = saturate(dot(clearCoatNormal, L.direction));
color.rgb = color.rgb * atten * NoL + (clearCoat * clearCoatNoL * L.color) * L.intensity;// * L.shadow;
#else
color.rgb = color.rgb * atten + (clearCoat * L.color) * (L.intensity * NoL); //(L.intensity * L.shadow * NoL);
#endif

#endif
}

// Final
color.rgb *= _mat.ambientOcclusion;
color.rgb += _mat.emissive;
color.a = _mat.albedo.a;
color.rgb *= M.ambientOcclusion;
color.rgb += M.emissive;
color.a = M.albedo.a;

return color;
}
Expand Down

0 comments on commit 0168bbb

Please sign in to comment.