107 lines
3.9 KiB
HLSL
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;
|
|
}
|