518 lines
16 KiB
HLSL
518 lines
16 KiB
HLSL
#ifndef ALLIN13DSHADER_BRDF
|
|
#define ALLIN13DSHADER_BRDF
|
|
|
|
/************/
|
|
#define MEDIUMP_FLT_MAX 65504.0
|
|
#define saturateMediump(x) min(x, MEDIUMP_FLT_MAX)
|
|
#define MIN_ROUGHNESS 0.01
|
|
|
|
struct BDRFPerLightData
|
|
{
|
|
float3 H;
|
|
float3 L;
|
|
|
|
float3 lightColor;
|
|
float distanceAttenuation;
|
|
float3 shadowColor;
|
|
float3 correctedLightColor;
|
|
|
|
float rawNdotL;
|
|
float correctedRawNdotL;
|
|
float NdotL;
|
|
float TdotL;
|
|
float BdotL;
|
|
|
|
float NdotH;
|
|
float TdotH;
|
|
float BdotH;
|
|
|
|
float VdotH;
|
|
float LdotH;
|
|
float LdotH_2;
|
|
|
|
float LdotV;
|
|
|
|
float3 F;
|
|
float3 kS;
|
|
float3 kD;
|
|
};
|
|
|
|
struct BDRFCommonData
|
|
{
|
|
float3 N;
|
|
float3 T;
|
|
float3 B;
|
|
float3 V;
|
|
|
|
float NdotV;
|
|
float TdotV;
|
|
float BdotV;
|
|
|
|
float metallic;
|
|
float smoothness;
|
|
float roughness;
|
|
float roughness_2;
|
|
float cubeLod;
|
|
|
|
float3 F0;
|
|
|
|
float2 mainUV;
|
|
|
|
float3 positionWS;
|
|
float2 normalizedScreenSpaceUV;
|
|
};
|
|
|
|
float D_GGX_Anisotropic(float NoH, const float3 h,
|
|
const float3 t, const float3 b, float at, float ab) {
|
|
|
|
//TODO: Pass TdotH and BdotH through parameters
|
|
float ToH = dot(t, h);
|
|
float BoH = dot(b, h);
|
|
float a2 = at * ab;
|
|
float3 v = float3(ab * ToH, at * BoH, a2 * NoH);
|
|
float v2 = dot(v, v);
|
|
float w2 = a2 / v2;
|
|
return a2 * w2 * w2 * (1.0 / ALLIN13DSHADER_PI);
|
|
}
|
|
|
|
float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float ToV, float BoV,
|
|
float ToL, float BoL, float NoV, float NoL) {
|
|
float lambdaV = NoL * length(float3(at * ToV, ab * BoV, NoV));
|
|
float lambdaL = NoV * length(float3(at * ToL, ab * BoL, NoL));
|
|
float v = 0.5 / (lambdaV + lambdaL);
|
|
return saturateMediump(v);
|
|
}
|
|
/************/
|
|
|
|
float DistributionGGX(float a, float NdotH)
|
|
{
|
|
float a2 = max(a*a, MIN_ROUGHNESS * MIN_ROUGHNESS);
|
|
float NdotH2 = NdotH*NdotH;
|
|
|
|
float num = a2;
|
|
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
|
denom = ALLIN13DSHADER_PI * denom * denom;
|
|
|
|
return num / denom;
|
|
}
|
|
|
|
float GeometrySchlickGGX(float NdotV, float roughness)
|
|
{
|
|
float r = (roughness + 1.0);
|
|
float k = (r*r) / 8.0;
|
|
|
|
float num = NdotV;
|
|
float denom = NdotV * (1.0 - k) + k;
|
|
|
|
return num / denom;
|
|
}
|
|
|
|
float GeometrySmith(float NdotV, float NdotL, float roughness)
|
|
{
|
|
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
|
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
|
|
|
return ggx1 * ggx2;
|
|
}
|
|
|
|
float3 fresnelSchlick(float3 F0, float VdotH)
|
|
{
|
|
float OneMinusVdotH = 1 - VdotH;
|
|
float OneMinusVdotH_5 = OneMinusVdotH * OneMinusVdotH * OneMinusVdotH * OneMinusVdotH * OneMinusVdotH;
|
|
return F0 + (1.0 - F0) * OneMinusVdotH_5;
|
|
}
|
|
|
|
float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
|
|
{
|
|
float oneMinusRoughness = 1.0 - roughness;
|
|
float oneMinusCosTheta = 1.0 - cosTheta;
|
|
|
|
return F0 + (max(oneMinusRoughness, F0) - F0) * pow(clamp(oneMinusCosTheta, 0.0, 1.0), 5.0);
|
|
}
|
|
|
|
inline float3 FresnelLerp (float3 F0, float3 F90, float cosA)
|
|
{
|
|
float t = Pow_5 (1 - cosA); // ala Schlick interpoliation
|
|
return lerp (F0, F90, t);
|
|
}
|
|
|
|
//Cook Torrance
|
|
float3 SpecularTerm(float a, float roughness, float3 F, float NdotH, float NdotV, float NdotL, float VdotH)
|
|
{
|
|
float D = DistributionGGX(a, NdotH);
|
|
float G = GeometrySmith(NdotV, NdotL, roughness);
|
|
float3 numerator = 4.0 * D * G * F;
|
|
|
|
float denominator = 4 * NdotV * NdotL;
|
|
denominator = max(denominator, 0.0001);
|
|
|
|
float3 res = numerator / denominator;
|
|
return res;
|
|
}
|
|
|
|
|
|
float3 SpecularAnisoTerm(
|
|
float at, float ab,
|
|
float3 F,
|
|
float NdotH, float NdotV, float NdotL,
|
|
float TdotV, float BdotV,
|
|
float TdotL, float BdotL,
|
|
float TdotH, float BdotH,
|
|
float3 H, float3 T, float3 B)
|
|
{
|
|
float D = D_GGX_Anisotropic(NdotH, H, T, B, at, ab);
|
|
float V = V_SmithGGXCorrelated_Anisotropic(
|
|
at, ab,
|
|
TdotV, BdotV,
|
|
TdotL, BdotL,
|
|
NdotV, NdotL);
|
|
|
|
float3 res = D * V * F;
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 SpecularIBL(float3 positionWS, float2 normalizedScreenSpaceUV, float3 normalWS, float3 viewDirWS, float cubeLod)
|
|
{
|
|
float3 res = 0;
|
|
|
|
#ifdef REFLECTIONS_ON
|
|
res = GetSkyColor(positionWS, normalizedScreenSpaceUV, normalWS, viewDirWS, cubeLod);
|
|
#endif
|
|
return res;
|
|
}
|
|
|
|
float3 DiffuseTerm(float LdotH, float LdotV, float NdotL, float roughness, float3 colorDiffuse)
|
|
{
|
|
float LdotH_2 = LdotH * LdotH;
|
|
|
|
float f0 = 1.0;
|
|
float f90 = 0.5 + 2*(roughness * LdotH_2);
|
|
|
|
float3 fDiffuse = lerp(f0, f90, NdotL) * lerp(f0, f90, LdotV);
|
|
|
|
float3 res = (colorDiffuse / ALLIN13DSHADER_PI) * fDiffuse;
|
|
return res;
|
|
}
|
|
|
|
float3 DiffuseTerm02(float NdotV, float NdotL, float LdotH, float perceptualRoughness, float3 albedo)
|
|
{
|
|
float fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
|
|
// Two schlick fresnel term
|
|
float lightScatter = (1 + (fd90 - 1) * Pow_5(1 - NdotL));
|
|
float viewScatter = (1 + (fd90 - 1) * Pow_5(1 - NdotV));
|
|
|
|
float3 res = (albedo /*/ ALLIN13DSHADER_PI*/) * lightScatter * viewScatter;
|
|
return res;
|
|
}
|
|
|
|
float3 IndirectLighting(float3 albedo, float3 specularColor, EffectsData effectsData, BDRFCommonData commonData, AllIn1GI gi)
|
|
{
|
|
float3 N = commonData.N;
|
|
float3 V = commonData.V;
|
|
|
|
//float3 ambientColor = GetAmbientColor(effectsData);
|
|
float3 diffuse = gi.diffuse * albedo;
|
|
|
|
float3 F = fresnelSchlickRoughness(commonData.NdotV, commonData.F0, commonData.roughness);
|
|
float3 kS = F;
|
|
float3 specular = 0;
|
|
#ifdef REFLECTIONS_ON
|
|
float3 specularIBL = SpecularIBL(commonData.positionWS, commonData.normalizedScreenSpaceUV, N, V, commonData.cubeLod);
|
|
|
|
//float reflectionLuminance = GetLuminance(float4(specularIBL, 1.0));
|
|
//specularIBL = lerp(diffuse, specularIBL, smoothstep(0.0, 0.1, reflectionLuminance * (1 - commonData.roughness)));
|
|
|
|
//TODO: Intermediate _Metallic values looks weird
|
|
float F_factor = 1 - commonData.metallic;
|
|
specular = specularIBL * lerp(1.0, F, F_factor);
|
|
#else
|
|
specular = lerp(diffuse * 0.25, diffuse, (1 - commonData.roughness));
|
|
#endif
|
|
|
|
float3 kD = 1.0 - kS;
|
|
kD *= 1.0 - commonData.metallic;
|
|
|
|
float3 indirectDiffuse = kD * diffuse;
|
|
|
|
//TODO: Some problems with specularColor
|
|
float3 indirectSpecular = specular * specularColor;
|
|
|
|
|
|
float3 res = indirectDiffuse + indirectSpecular;
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
float3 DirectDiffuse_PBR(float3 albedo, BDRFCommonData commonData, BDRFPerLightData perLightData, AllIn1LightData lightData)
|
|
{
|
|
float3 diffuseTerm = DiffuseTerm02(commonData.NdotV, perLightData.NdotL, perLightData.LdotH, commonData.roughness, albedo);
|
|
|
|
float correctedNdotL = saturate(perLightData.correctedRawNdotL);
|
|
float3 directDiffuse = 0;
|
|
#if defined(_LIGHTMODEL_CLASSIC)
|
|
directDiffuse = diffuseTerm * perLightData.kD * perLightData.correctedLightColor * correctedNdotL;
|
|
#elif defined(_LIGHTMODEL_HALFLAMBERT)
|
|
float NdotL = saturate(perLightData.correctedRawNdotL);
|
|
float halfLambertTerm = (NdotL * ACCESS_PROP_FLOAT(_HalfLambertWrap)) + (1 - ACCESS_PROP_FLOAT(_HalfLambertWrap));
|
|
float halfLambertTerm_2 = halfLambertTerm * halfLambertTerm;
|
|
directDiffuse = diffuseTerm * halfLambertTerm_2 * perLightData.correctedLightColor;
|
|
#elif defined(_LIGHTMODEL_FAKEGI)
|
|
float fakeGI = (correctedNdotL * ACCESS_PROP_FLOAT(_HardnessFakeGI)) + 1.0 - ACCESS_PROP_FLOAT(_HardnessFakeGI);
|
|
directDiffuse = diffuseTerm * fakeGI * perLightData.correctedLightColor;
|
|
#elif defined(_LIGHTMODEL_TOON)
|
|
directDiffuse = diffuseTerm * perLightData.kD * perLightData.correctedLightColor * correctedNdotL;
|
|
float toonFactor = smoothstep(ACCESS_PROP_FLOAT(_ToonCutoff), ACCESS_PROP_FLOAT(_ToonCutoff) + ACCESS_PROP_FLOAT(_ToonSmoothness), correctedNdotL);
|
|
directDiffuse *= toonFactor;
|
|
#elif defined(_LIGHTMODEL_TOONRAMP)
|
|
float3 rampLight = SAMPLE_TEX2D_LOD(_ToonRamp, float4((perLightData.correctedRawNdotL * 0.5) + 0.5, 0, 0, 0)).rgb;
|
|
directDiffuse = diffuseTerm * perLightData.kD * perLightData.correctedLightColor * rampLight;
|
|
//float diffuseTermLuminance = GetLuminance(directDiffuse);
|
|
//directDiffuse = SAMPLE_TEX2D(_ToonRamp, float2(diffuseTermLuminance, diffuseTermLuminance)).rgb;
|
|
#endif
|
|
|
|
return directDiffuse;
|
|
}
|
|
|
|
#ifdef SPECULAR_ON
|
|
float3 DirectSpecular_PBR(float3 specularColor, BDRFCommonData commonData, BDRFPerLightData perLightData, AllIn1LightData lightData, float4 specularMap)
|
|
{
|
|
float3 specularTerm = 0;
|
|
|
|
//float4 specularMap = SAMPLE_TEX2D(_SpecularMap, commonData.mainUV);
|
|
|
|
#if defined(_SPECULARMODEL_CLASSIC)
|
|
specularTerm = SpecularTerm(commonData.roughness_2, commonData.roughness, perLightData.F, perLightData.NdotH, commonData.NdotV, perLightData.NdotL, perLightData.VdotH);
|
|
#elif defined(_SPECULARMODEL_TOON)
|
|
specularTerm = SpecularTerm(commonData.roughness_2, commonData.roughness, perLightData.F, perLightData.NdotH, commonData.NdotV, perLightData.NdotL, perLightData.VdotH);
|
|
specularTerm = smoothstep(ACCESS_PROP_FLOAT(_SpecularToonCutoff), ACCESS_PROP_FLOAT(_SpecularToonCutoff) + ACCESS_PROP_FLOAT(_SpecularToonSmoothness), specularTerm);
|
|
#elif defined(_SPECULARMODEL_ANISOTROPIC) || defined(_SPECULARMODEL_ANISOTROPICTOON)
|
|
//https://google.github.io/filament/Filament.html?utm_source=chatgpt.com#materialsystem/anisotropicmodel
|
|
float aniso = ACCESS_PROP_FLOAT(_Anisotropy);
|
|
float at = max((1 - ACCESS_PROP_FLOAT(_AnisoShininess)) * (1.0 + aniso), 0.001);
|
|
float ab = max((1 - ACCESS_PROP_FLOAT(_AnisoShininess)) * (1.0 - aniso), 0.001);
|
|
|
|
specularTerm = SpecularAnisoTerm(at, ab, perLightData.F,
|
|
perLightData.NdotH, commonData.NdotV, perLightData.NdotL,
|
|
commonData.TdotV, commonData.BdotV, perLightData.TdotL,
|
|
perLightData.BdotL, perLightData.TdotH, perLightData.BdotH,
|
|
perLightData.H, commonData.T, commonData.B);
|
|
specularTerm = saturate(specularTerm);
|
|
|
|
#if defined(_SPECULARMODEL_ANISOTROPICTOON)
|
|
float specularSmoothness = max(ACCESS_PROP_FLOAT(_SpecularToonSmoothness), 0.001);
|
|
specularTerm = smoothstep(ACCESS_PROP_FLOAT(_SpecularToonCutoff), ACCESS_PROP_FLOAT(_SpecularToonCutoff) + specularSmoothness, specularTerm);
|
|
#endif
|
|
#endif
|
|
|
|
specularTerm *= specularMap.r;
|
|
|
|
float3 directSpecular = specularTerm * specularColor * ACCESS_PROP_FLOAT(_SpecularAtten) * perLightData.correctedLightColor * perLightData.NdotL;
|
|
return directSpecular;
|
|
}
|
|
#endif
|
|
|
|
float3 DirectLighting_PBR(float3 albedo, BDRFCommonData commonData, BDRFPerLightData perLightData, AllIn1LightData lightData, float4 specularMap)
|
|
{
|
|
float3 diffuseTerm = DirectDiffuse_PBR(albedo, commonData, perLightData, lightData);
|
|
|
|
float3 specularColor = lerp(1.0, albedo, commonData.metallic);
|
|
|
|
float3 specularTerm = 0;
|
|
#ifdef SPECULAR_ON
|
|
specularTerm = DirectSpecular_PBR(specularColor, commonData, perLightData, lightData, specularMap);
|
|
#endif
|
|
|
|
float3 directLight = diffuseTerm + specularTerm;
|
|
return directLight;
|
|
}
|
|
|
|
BDRFCommonData CreateCommonBDRFData(float3 albedo, EffectsData effectsData)
|
|
{
|
|
BDRFCommonData res;
|
|
|
|
res.N = effectsData.normalWS;
|
|
res.T = effectsData.tangentWS;
|
|
res.B = effectsData.bitangentWS;
|
|
res.V = normalize(_WorldSpaceCameraPos.xyz - effectsData.vertexWS);
|
|
|
|
res.metallic = effectsData.metallic;
|
|
float smoothness = effectsData.smoothness;
|
|
#ifdef _METALLIC_MAP_ON
|
|
float4 metallicMapColor = SAMPLE_TEX2D(_MetallicMap, effectsData.mainUV);
|
|
|
|
float metallicMapValue = metallicMapColor.r;
|
|
res.metallic *= metallicMapValue;
|
|
res.metallic = saturate(res.metallic);
|
|
|
|
float glossMapValue = metallicMapColor.a;
|
|
smoothness *= glossMapValue;
|
|
smoothness = saturate(smoothness);
|
|
#endif
|
|
|
|
res.smoothness = lerp(0, 0.95, smoothness);
|
|
|
|
res.roughness = (1 - res.smoothness);
|
|
res.roughness_2 = res.roughness * res.roughness;
|
|
res.cubeLod = res.roughness * 8;
|
|
|
|
res.NdotV = max(dot(res.N, res.V), 0.0);
|
|
res.TdotV = max(dot(res.T, res.V), 0.0);
|
|
res.BdotV = max(dot(res.B, res.V), 0.0);
|
|
|
|
|
|
float3 f0 = 0.04;
|
|
f0 = lerp(f0, albedo, res.metallic);
|
|
|
|
res.F0 = f0;
|
|
|
|
res.mainUV = effectsData.mainUV;
|
|
|
|
res.positionWS = effectsData.vertexWS;
|
|
res.normalizedScreenSpaceUV = effectsData.normalizedScreenSpaceUV;
|
|
|
|
return res;
|
|
}
|
|
|
|
BDRFPerLightData CreatePerLightData(BDRFCommonData commonData, AllIn1LightData lightData, float isAdditionalLight)
|
|
{
|
|
BDRFPerLightData res;
|
|
|
|
float oneMinusMetallic = 1 - commonData.metallic;
|
|
|
|
res.L = lightData.lightDir;
|
|
|
|
res.lightColor = lightData.lightColor.rgb;
|
|
res.distanceAttenuation = lightData.distanceAttenuation;
|
|
res.shadowColor = lightData.shadowColor.rgb;
|
|
res.correctedLightColor = lightData.lightColor.rgb * lightData.distanceAttenuation * lightData.shadowColor.rgb;
|
|
|
|
res.H = normalize(commonData.V + res.L);
|
|
|
|
res.NdotH = max(dot(commonData.N, res.H), 0.0);
|
|
res.rawNdotL = dot(commonData.N, res.L);
|
|
res.correctedRawNdotL = res.rawNdotL;
|
|
#if !defined(FORWARD_ADD_PASS)
|
|
#if defined(_LIGHTMODEL_HALFLAMBERT) || defined(_LIGHTMODEL_FAKEGI) || defined(_LIGHTMODEL_TOONRAMP)
|
|
res.correctedLightColor = isAdditionalLight > 0 ? res.correctedLightColor : res.lightColor;
|
|
res.correctedRawNdotL = isAdditionalLight > 0 ? res.correctedRawNdotL : res.correctedRawNdotL * GetLuminance(lightData.shadowColor.rgb);
|
|
#endif
|
|
#endif
|
|
|
|
res.NdotL = max(res.rawNdotL, 0.0);
|
|
res.TdotL = max(dot(commonData.T, res.L), 0.0);
|
|
res.BdotL = max(dot(commonData.B, res.L), 0.0);
|
|
|
|
res.VdotH = max(dot(commonData.V, res.H), 0.0);
|
|
res.TdotH = max(dot(commonData.T, res.H), 0.0);
|
|
res.BdotH = max(dot(commonData.B, res.H), 0.0);
|
|
|
|
res.LdotV = max(dot(res.L, commonData.V), 0.0);
|
|
res.LdotH = max(dot(res.L, res.H), 0.0);
|
|
|
|
res.LdotH_2 = res.LdotH * res.LdotH;
|
|
|
|
res.F = fresnelSchlick(commonData.F0, res.VdotH);
|
|
res.kS = res.F;
|
|
res.kD = (1.0 - res.kS) * oneMinusMetallic;
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 CalculateLighting_PBR(float3 albedo, float alpha, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
BDRFCommonData commonData = CreateCommonBDRFData(albedo, effectsData);
|
|
|
|
float3 specularColor = lerp(1.0, albedo, commonData.metallic);
|
|
|
|
AllIn1LightData mainLightData = GetMainLightData(effectsData.vertexWS, effectsData, gi);
|
|
|
|
|
|
float3 directLighting = albedo;
|
|
float4 specularMap = float4(1, 1, 1, 1);
|
|
|
|
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
uint meshRenderingLayers = AllIn1GetMeshRenderingLayer();
|
|
directLighting = 0;
|
|
if (IsMatchingLightLayer(mainLightData.layerMask, meshRenderingLayers))
|
|
{
|
|
directLighting = albedo;
|
|
#endif
|
|
BDRFPerLightData perLightData_mainLight = CreatePerLightData(commonData, mainLightData, 0.0);
|
|
|
|
#ifdef SPECULAR_ON
|
|
specularMap = SAMPLE_TEX2D(_SpecularMap, commonData.mainUV);
|
|
#endif
|
|
|
|
directLighting = DirectLighting_PBR(albedo, commonData, perLightData_mainLight, mainLightData, specularMap);
|
|
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
}
|
|
#endif
|
|
|
|
#if defined(ADDITIONAL_LIGHT_LOOP) && !defined(_LIGHTMODEL_FASTLIGHTING)
|
|
// Additional light loop for non-main directional lights. This block is specific to Forward+.
|
|
#if USE_CLUSTER_LIGHT_LOOP
|
|
UNITY_LOOP for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
|
|
{
|
|
AllIn1LightData additionalLightData = GetPointLightData(lightIndex, effectsData.vertexWS, effectsData.normalWS, effectsData, gi);
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
if (IsMatchingLightLayer(additionalLightData.layerMask, meshRenderingLayers))
|
|
{
|
|
#endif
|
|
BDRFPerLightData perLightData_additionalLight = CreatePerLightData(commonData, additionalLightData, 1.0);
|
|
directLighting += DirectLighting_PBR(albedo, commonData, perLightData_additionalLight, additionalLightData, specularMap);
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
uint numAdditionalLights = NUM_ADDITIONAL_LIGHTS;
|
|
LIGHT_LOOP_BEGIN_ALLIN13D(numAdditionalLights, effectsData)
|
|
AllIn1LightData additionalLightData = GetPointLightData(lightIndex, effectsData.vertexWS, effectsData.normalWS, effectsData, gi);
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
|
|
uint meshRenderingLayers = AllIn1GetMeshRenderingLayer();
|
|
if (IsMatchingLightLayer(additionalLightData.layerMask, meshRenderingLayers))
|
|
{
|
|
#endif
|
|
BDRFPerLightData perLightData_additionalLight = CreatePerLightData(commonData, additionalLightData, 1.0);
|
|
directLighting += DirectLighting_PBR(albedo, commonData, perLightData_additionalLight, additionalLightData, specularMap);
|
|
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
}
|
|
#endif
|
|
|
|
LIGHT_LOOP_END_ALLIN13D
|
|
#endif
|
|
|
|
float2 ssaoFactor = GetSSAO(effectsData.normalizedScreenSpaceUV.xy, alpha);
|
|
|
|
float3 res = directLighting * ssaoFactor.x;
|
|
|
|
|
|
|
|
//We add IndirectLighting only once
|
|
#ifndef FORWARD_ADD_PASS
|
|
#if defined(_CUSTOM_SHADOW_COLOR_ON)
|
|
float shadowT = saturate(mainLightData.realtimeShadow + 1.0 - global_shadowColor.a);
|
|
res = lerp(global_shadowColor, res, shadowT);
|
|
#endif
|
|
|
|
float3 ao = 1.0;
|
|
#ifdef _AOMAP_ON
|
|
ao = GetAOMapTerm(effectsData.mainUV);
|
|
#endif
|
|
|
|
float3 indirectLighting = IndirectLighting(albedo, specularColor, effectsData, commonData, gi);
|
|
res += (indirectLighting) * ao * ssaoFactor.y;
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
#endif |