347 lines
11 KiB
HLSL
347 lines
11 KiB
HLSL
#ifndef ALLIN13DSHADER_LIGHT_INCLUDED
|
|
#define ALLIN13DSHADER_LIGHT_INCLUDED
|
|
|
|
|
|
#if ALLIN1_USE_FORWARD_PLUS
|
|
#define LIGHT_LOOP_BEGIN_ALLIN13D(lightCount, data) { \
|
|
uint lightIndex; \
|
|
ClusterIterator _urp_internal_clusterIterator = ClusterInit(data.normalizedScreenSpaceUV, data.vertexWS, 0); \
|
|
[loop] while (ClusterNext(_urp_internal_clusterIterator, lightIndex)) { \
|
|
lightIndex += URP_FP_DIRECTIONAL_LIGHTS_COUNT; \
|
|
ALLIN1_FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
|
|
#define LIGHT_LOOP_END_ALLIN13D } }
|
|
#else
|
|
#define LIGHT_LOOP_BEGIN_ALLIN13D(lightCount, data) \
|
|
if(lightCount > 0) { \
|
|
for (uint lightIndex = 0u; lightIndex < lightCount; ++lightIndex) {
|
|
#define LIGHT_LOOP_END_ALLIN13D } }
|
|
#endif
|
|
|
|
float GetMainLightIntensity()
|
|
{
|
|
return length(GetMainLightColorRGB());
|
|
}
|
|
|
|
#if defined(_SHADINGMODEL_PBR) || defined(_SPECULARMODEL_ANISOTROPIC) || defined(_SPECULARMODEL_ANISOTROPICTOON)
|
|
#include "../ShaderLibrary/AllIn13DShader_BRDF.hlsl"
|
|
#endif
|
|
|
|
float3 GetBitangentWS(float4 tangentOS, float3 tangentWS, float3 normalWS)
|
|
{
|
|
float tangentSign = tangentOS.w * unity_WorldTransformParams.w;
|
|
float3 res = cross(normalWS, tangentWS) * tangentSign;
|
|
return res;
|
|
}
|
|
|
|
float3 DiffuseTerm(AllIn1LightData lightData, float3 normal, float isAdditionalLight)
|
|
{
|
|
float rawNdotL = dot(normal, lightData.lightDir);
|
|
float3 lightModel = 0;
|
|
float3 lightColor = lightData.lightColor.rgb * lightData.distanceAttenuation * lightData.shadowColor.rgb;
|
|
|
|
#if !defined(FORWARD_ADD_PASS)
|
|
#if defined(_LIGHTMODEL_HALFLAMBERT) || defined(_LIGHTMODEL_FAKEGI) || defined(_LIGHTMODEL_TOONRAMP)
|
|
lightColor = isAdditionalLight > 0 ? lightColor : lightData.lightColor.rgb;
|
|
rawNdotL = isAdditionalLight > 0 ? rawNdotL : rawNdotL * GetLuminance(lightData.shadowColor.rgb);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(_LIGHTMODEL_CLASSIC)
|
|
float NdotL = saturate(rawNdotL);
|
|
lightModel = NdotL;
|
|
|
|
#elif defined(_LIGHTMODEL_TOON)
|
|
float NdotL = saturate(rawNdotL);
|
|
lightModel = smoothstep(ACCESS_PROP_FLOAT(_ToonCutoff), ACCESS_PROP_FLOAT(_ToonCutoff) + ACCESS_PROP_FLOAT(_ToonSmoothness), NdotL);
|
|
|
|
#elif defined(_LIGHTMODEL_TOONRAMP)
|
|
float NdotL = (rawNdotL * 0.5) + 0.5;
|
|
lightModel = SAMPLE_TEX2D_LOD(_ToonRamp, float4(NdotL, 0, 0, 0)).rgb;
|
|
|
|
#elif defined(_LIGHTMODEL_HALFLAMBERT)
|
|
float NdotL = saturate(rawNdotL);
|
|
float halfLambertTerm = (NdotL * ACCESS_PROP_FLOAT(_HalfLambertWrap)) + (1 - ACCESS_PROP_FLOAT(_HalfLambertWrap));
|
|
lightModel = halfLambertTerm * halfLambertTerm;
|
|
|
|
#elif defined(_LIGHTMODEL_FAKEGI)
|
|
float NdotL = saturate(rawNdotL);
|
|
lightModel = (NdotL * ACCESS_PROP_FLOAT(_HardnessFakeGI)) + 1.0 - ACCESS_PROP_FLOAT(_HardnessFakeGI);
|
|
|
|
#elif defined(_LIGHTMODEL_FASTLIGHTING)
|
|
lightModel = saturate(rawNdotL);
|
|
|
|
#endif
|
|
|
|
float3 res = lightModel * lightColor;
|
|
|
|
return res;
|
|
}
|
|
|
|
#ifdef SPECULAR_ON
|
|
|
|
float3 SpecularTerm(float3 objectColor, AllIn1LightData lightData,
|
|
float3 normalWS, float3 tangentWS, float3 bitangentWS,
|
|
float3 viewDirWS, float glossiness, float2 mainUV, float4 specularTex)
|
|
{
|
|
float3 lightColor = lightData.lightColor.rgb * lightData.distanceAttenuation * lightData.shadowColor.rgb;
|
|
float3 reflectionDir = reflect(-lightData.lightDir, normalWS);
|
|
float rawVdotL = dot(viewDirWS, reflectionDir);
|
|
|
|
float3 specularModel = 0;
|
|
|
|
|
|
#if defined(_SPECULARMODEL_CLASSIC) || defined(_SPECULARMODEL_TOON)
|
|
float3 halfVector = normalize(viewDirWS + lightData.lightDir);
|
|
float NdotH = saturate(dot(normalWS, halfVector));
|
|
float specularIntensity = pow(NdotH, glossiness);
|
|
|
|
#elif defined(_SPECULARMODEL_ANISOTROPIC) || defined(_SPECULARMODEL_ANISOTROPICTOON)
|
|
float3 H = normalize(viewDirWS + lightData.lightDir);
|
|
|
|
float TdotH = saturate(dot(tangentWS, H));
|
|
float BdotH = saturate(dot(bitangentWS, H));
|
|
|
|
float TdotV = saturate(dot(tangentWS, viewDirWS));
|
|
float BdotV = saturate(dot(bitangentWS, viewDirWS));
|
|
|
|
float TdotL = saturate(dot(tangentWS, lightData.lightDir));
|
|
float BdotL = saturate(dot(bitangentWS, lightData.lightDir));
|
|
|
|
float NdotH = saturate(dot(normalWS, H));
|
|
float NdotL = saturate(dot(normalWS, lightData.lightDir));
|
|
float NdotV = saturate(dot(normalWS, viewDirWS));
|
|
|
|
float VdotH = saturate(dot(viewDirWS, H));
|
|
|
|
float anisotropy = ACCESS_PROP_FLOAT(_Anisotropy);
|
|
float anisoShininess = ACCESS_PROP_FLOAT(_AnisoShininess);
|
|
float at = max((1 - anisoShininess) * (1.0 + anisotropy), 0.001);
|
|
float ab = max((1 - anisoShininess) * (1.0 - anisotropy), 0.001);
|
|
|
|
float3 specularIntensity = SpecularAnisoTerm(
|
|
at, ab,
|
|
float3(1.0, 1.0, 1.0),
|
|
NdotH, NdotV, NdotL,
|
|
TdotV, BdotV,
|
|
TdotL, BdotL,
|
|
TdotH, BdotH,
|
|
H, tangentWS.xyz, bitangentWS.xyz) * NdotL;
|
|
|
|
specularIntensity = saturate(specularIntensity);
|
|
#endif
|
|
|
|
#if defined(_SPECULARMODEL_ANISOTROPICTOON) || defined(_SPECULARMODEL_TOON)
|
|
float specularSmoothness = max(ACCESS_PROP_FLOAT(_SpecularToonSmoothness), 0.001);
|
|
specularIntensity = smoothstep(ACCESS_PROP_FLOAT(_SpecularToonCutoff), ACCESS_PROP_FLOAT(_SpecularToonCutoff) + specularSmoothness, specularIntensity);
|
|
#endif
|
|
|
|
specularModel = specularIntensity * lightColor;
|
|
float3 res = specularModel * ACCESS_PROP_FLOAT(_SpecularAtten) * specularTex.r;
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 SpecularTerm_Basic(float3 objectColor, AllIn1LightData lightData,
|
|
float3 normalWS, float3 tangentWS, float3 bitangentWS, float3 viewDirWS, float2 mainUV, float4 specularTex)
|
|
{
|
|
float3 res = SpecularTerm(objectColor, lightData,
|
|
normalWS, tangentWS, bitangentWS,
|
|
viewDirWS, ACCESS_PROP_FLOAT(_Shininess) * ACCESS_PROP_FLOAT(_Shininess), mainUV, specularTex);
|
|
return res;
|
|
}
|
|
|
|
#endif
|
|
|
|
float3 RimTermOperation(float3 normalWS, float3 viewDirWS, float minRim, float maxRim, float rimAttenuation, float3 rimColor)
|
|
{
|
|
float NdotV = saturate(dot(normalWS, viewDirWS));
|
|
float rimIntensity = (1 - NdotV);
|
|
rimIntensity = smoothstep(minRim, maxRim, rimIntensity) * rimAttenuation;
|
|
|
|
float3 res = rimIntensity * rimColor;
|
|
return res;
|
|
}
|
|
|
|
float3 DirectLighting(float3 objectColor, EffectsData effectsData, AllIn1LightData lightData, float4 specularTex, float isAdditionalLight)
|
|
{
|
|
float3 res = 0;
|
|
|
|
float3 diffuseTerm = DiffuseTerm(lightData, effectsData.normalWS, isAdditionalLight) * objectColor;
|
|
|
|
#if defined(_CUSTOM_SHADOW_COLOR_ON) && !defined(FORWARD_ADD_PASS)
|
|
float shadowT = saturate(lightData.realtimeShadow + 1.0 - global_shadowColor.a);
|
|
diffuseTerm = lerp(global_shadowColor, diffuseTerm, shadowT);
|
|
#endif
|
|
|
|
float3 specularTerm = 0;
|
|
#ifdef SPECULAR_ON
|
|
|
|
float NdotL = saturate(dot(effectsData.normalWS, lightData.lightDir));
|
|
|
|
specularTerm = SpecularTerm_Basic(objectColor, lightData,
|
|
effectsData.normalWS, effectsData.tangentWS, effectsData.bitangentWS,
|
|
effectsData.viewDirWS, effectsData.mainUV, specularTex) * NdotL;
|
|
#endif
|
|
|
|
res = diffuseTerm + specularTerm;
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 DirectLighting(float3 objectColor, float2 ssaoFactor, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
AllIn1LightData mainLightData = GetMainLightData(effectsData.vertexWS, effectsData, gi);
|
|
|
|
|
|
float3 res = objectColor;
|
|
float4 specularTex = float4(1, 1, 1, 1);
|
|
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
uint meshRenderingLayers = AllIn1GetMeshRenderingLayer();
|
|
res = 0;
|
|
if (IsMatchingLightLayer(mainLightData.layerMask, meshRenderingLayers))
|
|
{
|
|
res = objectColor;
|
|
#endif
|
|
|
|
#ifdef SPECULAR_ON
|
|
specularTex = SAMPLE_TEX2D(_SpecularMap, effectsData.mainUV);
|
|
#endif
|
|
|
|
res = DirectLighting(objectColor, effectsData, mainLightData, specularTex, 0);
|
|
|
|
#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
|
|
res += DirectLighting(objectColor, effectsData, additionalLightData, specularTex, 1);
|
|
#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
|
|
if (IsMatchingLightLayer(additionalLightData.layerMask, meshRenderingLayers))
|
|
{
|
|
#endif
|
|
res += DirectLighting(objectColor, effectsData, additionalLightData, specularTex, 1);
|
|
#ifdef ALLIN1_USE_LIGHT_LAYERS
|
|
}
|
|
#endif
|
|
|
|
LIGHT_LOOP_END_ALLIN13D
|
|
#endif
|
|
|
|
res *= ssaoFactor.x;
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 IndirectLighting_Basic(float3 objectColor, float2 ssaoFactor, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
//float3 ambientColor = GetAmbientColor(effectsData);
|
|
|
|
float3 ao = 1.0;
|
|
|
|
float3 reflections = 0;
|
|
#ifdef REFLECTIONS_ON
|
|
reflections = GetSkyColor(effectsData.vertexWS, effectsData.normalizedScreenSpaceUV, effectsData.normalWS, effectsData.viewDirWS, 1.0);
|
|
#endif
|
|
|
|
float3 indirectLighting = /*(ambientColor + lightmap)*/gi.diffuse * objectColor;
|
|
indirectLighting += reflections;
|
|
|
|
indirectLighting *= ssaoFactor.y;
|
|
|
|
return indirectLighting;
|
|
}
|
|
|
|
float3 CalculateLighting_Basic(float3 objectColor, float alpha, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
float2 ssaoFactor = GetSSAO(effectsData.normalizedScreenSpaceUV.xy, alpha);
|
|
|
|
float3 directLighting = DirectLighting(objectColor, ssaoFactor, effectsData, gi);
|
|
|
|
|
|
float3 indirectLighting = 0;
|
|
//We add IndirectLighting only once
|
|
#ifndef FORWARD_ADD_PASS
|
|
indirectLighting = IndirectLighting_Basic(objectColor, ssaoFactor, effectsData, gi);
|
|
|
|
#ifdef _AOMAP_ON
|
|
float3 aoMapValue = GetAOMapTerm(effectsData.mainUV);
|
|
indirectLighting *= aoMapValue;
|
|
#endif
|
|
#endif
|
|
|
|
float3 res = directLighting + indirectLighting;
|
|
|
|
return res;
|
|
}
|
|
|
|
#ifdef _SHADINGMODEL_PBR
|
|
float3 CalculateLighting_MetallicWorkflow(
|
|
float3 vertexWS,
|
|
float3 normalWS, float3 tangentWS, float3 bitangentWS,
|
|
float3 objectColor, float alpha,
|
|
float3 shadows, float3 ambientCol, float3 viewDirWS,
|
|
float2 mainUV, FragmentData fragmentData, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
float3 res = CalculateLighting_PBR(objectColor, alpha, effectsData, gi);
|
|
|
|
return res;
|
|
}
|
|
|
|
#endif
|
|
|
|
float3 CalculateLighting(float3 vertexWS,
|
|
float3 normalWS, float3 tangentWS, float3 bitangentWS,
|
|
float3 objectColor, float alpha,
|
|
float shadows, float3 ambientCol, float3 viewDirWS,
|
|
float2 mainUV,
|
|
float3 lightColor, float3 lightDir,
|
|
FragmentData fragmentData, float lightAtten, EffectsData effectsData,
|
|
AllIn1GI gi)
|
|
{
|
|
#ifdef _CUSTOM_SHADOW_COLOR_ON
|
|
float3 shadowColor = lerp(1.0, global_shadowColor, 1 - shadows);
|
|
#else
|
|
float3 shadowColor = shadows;
|
|
#endif
|
|
|
|
float3 res = 0;
|
|
#ifdef _LIGHTMODEL_FASTLIGHTING
|
|
res = CalculateLighting_Basic(objectColor, alpha, effectsData, gi);
|
|
#else
|
|
#ifdef _SHADINGMODEL_PBR
|
|
res = CalculateLighting_MetallicWorkflow(
|
|
vertexWS,
|
|
normalWS, tangentWS, bitangentWS,
|
|
objectColor, alpha,
|
|
shadowColor, ambientCol, viewDirWS,
|
|
mainUV, fragmentData, effectsData, gi);
|
|
#else
|
|
res = CalculateLighting_Basic(objectColor, alpha, effectsData, gi);
|
|
#endif
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
#endif |