// 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