[Add] All in one shader
This commit is contained in:
@@ -0,0 +1,347 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user