107 lines
3.9 KiB
HLSL

// SPDX-License-Identifier: (Not available for this version, you are only allowed to use this software if you have express permission from the copyright holder and agreed to the latest NiloToonURP EULA)
// Copyright (c) 2021 Kuroneko ShaderLab Limited
// For more information, visit -> https://github.com/ColinLeung-NiloCat/UnityURPToonLitShaderExample
// #pragma once is a safe guard best practice in almost every .hlsl,
// doing this can make sure your .hlsl's user can include this .hlsl anywhere anytime without producing any multi include conflict
#pragma once
half3 BlendNiloGenericRimLight3DColor(half3 dstCol, half3 srcCol, half srcA, uint blendMode)
{
half3 add = dstCol + srcCol;
half3 mul = dstCol * srcCol;
half3 outCol = dstCol;
if (blendMode == 0) outCol = srcCol;
else if (blendMode == 1) outCol = add;
else if (blendMode == 2) outCol = max(add - mul, dstCol);
else if (blendMode == 3) outCol = mul;
return lerp(dstCol, outCol, srcA);
}
half NiloGenericRimLight3DTooningScale(half value, half border, half blur)
{
half borderMin = saturate(border - blur * 0.5);
half borderMax = saturate(border + blur * 0.5);
half denominator = max(0.0001, saturate(borderMax - borderMin + fwidth(value)));
return saturate((value - borderMin) / denominator);
}
float3 GetNiloGenericRimLight3DCameraForwardWS()
{
return normalize(-float3(UNITY_MATRIX_I_V[0][2], UNITY_MATRIX_I_V[1][2], UNITY_MATRIX_I_V[2][2]));
}
half3 ApplyNiloGenericRimLight3D(
half3 dstColor,
half3 albedo,
half facing,
half3 normalWS_NoNormalMap,
half3 normalWS,
half3 viewDirectionWS,
half3 lightDirectionWS,
half3 lightColor,
half finalShadowArea,
half inShadow25PercentMul,
half4 colorTex,
half4 color,
half4 indirColor,
half colorAlpha,
half mainStrength,
half enableLighting,
half shadowMask,
half backfaceMask,
uint blendMode,
half dirStrength,
half dirRange,
half border,
half blur,
half indirRange,
half indirBorder,
half indirBlur,
half normalStrength,
half fresnelPower,
half vrParallaxStrength)
{
half3 rimNormalWS = normalize(lerp(normalWS_NoNormalMap, normalWS, normalStrength));
#if defined(USING_STEREO_MATRICES)
half3 rimViewDirectionWS = normalize(lerp(GetNiloGenericRimLight3DCameraForwardWS(), viewDirectionWS, vrParallaxStrength));
#else
half3 rimViewDirectionWS = normalize(viewDirectionWS);
#endif
half rim = pow(saturate(1.0 - abs(dot(rimNormalWS, rimViewDirectionWS))), fresnelPower);
rim = facing < (backfaceMask - 1.0) ? 0.0 : rim;
half lightNormalRaw = dot(lightDirectionWS, rimNormalWS) * 0.5 + 0.5;
half dirDenominator = max(0.0001, 1.0 + dirRange);
half indirDenominator = max(0.0001, 1.0 + indirRange);
half lightNormalDir = saturate((lightNormalRaw + dirRange) / dirDenominator);
half lightNormalIndir = saturate((1.0 - lightNormalRaw + indirRange) / indirDenominator);
half rimDir = lerp(rim, rim * lightNormalDir, dirStrength);
half rimIndir = rim * lightNormalIndir * dirStrength;
rimDir = NiloGenericRimLight3DTooningScale(rimDir, border, blur);
rimIndir = NiloGenericRimLight3DTooningScale(rimIndir, indirBorder, indirBlur);
half rimShadow = saturate(finalShadowArea * inShadow25PercentMul);
rimDir = lerp(rimDir, rimDir * rimShadow, shadowMask);
rimIndir = lerp(rimIndir, rimIndir * rimShadow, shadowMask);
half4 rimColor = color * colorTex;
half4 rimIndirColor = indirColor * colorTex;
rimColor.a *= colorAlpha;
rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * albedo, mainStrength);
half3 rimLightMul = 1.0 - enableLighting + lightColor * enableLighting;
dstColor = BlendNiloGenericRimLight3DColor(dstColor, rimColor.rgb * rimLightMul, rimDir * rimColor.a, blendMode);
dstColor = BlendNiloGenericRimLight3DColor(dstColor, rimIndirColor.rgb * rimLightMul, rimIndir * rimIndirColor.a, blendMode);
return dstColor;
}