76 lines
3.1 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
#pragma once
#if NiloToonIsAnyFurPass && _NILOTOON_FUR
float ComputeNiloToonFurNoise(float2 uv)
{
float2 furUV = uv * _NiloFurNoiseTiling.xy + _NiloFurNoiseTiling.zw;
return SAMPLE_TEXTURE2D(_NiloFurNoiseTex, sampler_linear_repeat, furUV).r;
}
float ComputeNiloToonFurAlphaAndClip(float2 uv, float furLayer, float furNoise)
{
float furMask = SAMPLE_TEXTURE2D(_NiloFurMask, sampler_linear_repeat, uv).r;
#if NiloToonFurDepthPrepassPass || NiloToonFurPrepassBufferDepthPass
float furAlpha = NiloFurAlphaCutout(furLayer, _NiloFurRootOffset, furNoise, furMask);
if (furAlpha == 0) discard;
#else
float furAlpha = NiloFurAlpha(furLayer, _NiloFurRootOffset, furNoise, furMask);
clip(furAlpha - 0.001);
#endif
return furAlpha;
}
void ApplyNiloToonFurOcclusionShadowAO(inout ToonSurfaceData surfaceData, Varyings input, float furNoise)
{
float furLengthScaled = _NiloFurLength * _NiloFurStrength;
float furAOLengthScale = saturate(furLengthScaled / 0.015);
float furOcclusion = lerp(1.0, input.furLayer, _NiloFurOcclusionShadowAO * furAOLengthScale);
surfaceData.occlusion *= furOcclusion;
}
void ApplyNiloToonFurColorDarkenAO(inout half3 color, Varyings input, float furNoise)
{
UNITY_BRANCH
if (_NiloFurColorDarkenAO <= 0)
return;
#if NiloToonFurDepthPrepassPass
// Cutout color+depth prepass: match lilToon's FUR_PRE root darkening without sampling noise again.
float scaledColorAO = _NiloFurColorDarkenAO * saturate(1.0 - fwidth(input.furLayer));
color *= input.furLayer * scaledColorAO * 2.0 + 1.0 - scaledColorAO;
#else
// Transparent color pass: reuse the fur noise already sampled for alpha.
float colorAOMask = saturate(1.0 - furNoise + furNoise * input.furLayer);
color *= colorAOMask * _NiloFurColorDarkenAO * 1.25 + 1.0 - _NiloFurColorDarkenAO;
#endif
}
void ApplyNiloToonFurAlphaMaskAndRim(
inout half3 color,
inout ToonSurfaceData surfaceData,
Varyings input,
ToonLightingData lightingData,
float furNoise)
{
if (_NiloFurShowOnSkinFace < 0.5)
{
half skinFaceArea = max(lightingData.isFaceArea, lightingData.isSkinArea);
clip(0.5 - skinFaceArea);
}
surfaceData.alpha = ComputeNiloToonFurAlphaAndClip(input.uv01.xy, input.furLayer, furNoise);
float3 furNormalWS = normalize(input.normalWS_averageShadowAttenuation.xyz);
float3 furViewDirWS = lightingData.viewDirectionWS;
half3 furLightColor = min(lightingData.mainLight.color, 1.0);
half3 furInvLighting = saturate((1.0 - furLightColor) * sqrt(furLightColor));
half furInvLightingGray = dot(furInvLighting, 1.0 / 3.0);
color += NiloFurRim(input.furLayer, furNormalWS, furViewDirWS,
_NiloFurRimColor, _NiloFurRimFresnelPower, _NiloFurRimAntiLight, furInvLightingGray) * furLightColor;
}
#endif