Files
YachtDice/Assets/Plugins/AllIn13DShader/Shaders/ShaderLibrary/AllIn13DShaderLight.hlsl
T
2026-02-23 22:01:07 +07:00

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