diff --git a/Assets/External/AmplifyShaderEditor/Plugins/EditorResources/Templates/URP/NiloToonEnvironment.shader b/Assets/External/AmplifyShaderEditor/Plugins/EditorResources/Templates/URP/NiloToonEnvironment.shader index 7974312f1..f3245569e 100644 --- a/Assets/External/AmplifyShaderEditor/Plugins/EditorResources/Templates/URP/NiloToonEnvironment.shader +++ b/Assets/External/AmplifyShaderEditor/Plugins/EditorResources/Templates/URP/NiloToonEnvironment.shader @@ -22,6 +22,10 @@ Shader /*ase_name*/ "Hidden/Universal/NiloToonEnvironment" /*end*/ _ScreenSpaceOutlineIntensity("Screen Space Outline Intensity", Range(0,1)) = 1 [HDR]_ScreenSpaceOutlineColor("Screen Space Outline Color", Color) = (1,1,1,1) _ScreenSpaceOutlineWidth("Screen Space Outline Width", Float) = 1 + + // NiloToon Character Self Shadow Receiver (off by default to keep parity with original ASE template) + [Toggle(_RECEIVE_NILOTOON_CHAR_SHADOW)] _ReceiveNiloToonCharShadow("Receive NiloToon Char Shadow", Float) = 0 + _NiloToonCharShadowStrength(" Shadow Strength", Range(0, 1)) = 1.0 } SubShader @@ -198,6 +202,10 @@ Shader /*ase_name*/ "Hidden/Universal/NiloToonEnvironment" /*end*/ #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF #pragma shader_feature_local_fragment _SPECULAR_SETUP + // NiloToon Character Self Shadow keywords + #pragma shader_feature_local_fragment _RECEIVE_NILOTOON_CHAR_SHADOW + #pragma multi_compile_fragment _ _NILOTOON_RECEIVE_SELF_SHADOW + // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN @@ -307,6 +315,8 @@ Shader /*ase_name*/ "Hidden/Universal/NiloToonEnvironment" /*end*/ half3 _ScreenSpaceOutlineColor; float _ScreenSpaceOutlineWidth; float _Surface; + // NiloToon Character Self Shadow per-material strength + float _NiloToonCharShadowStrength; /*ase_srp_batcher*/ CBUFFER_END @@ -326,6 +336,56 @@ Shader /*ase_name*/ "Hidden/Universal/NiloToonEnvironment" /*end*/ half3 _GlobalScreenSpaceOutlineTintColorForEnvi; float _CurrentCameraFOV; + // NiloToon Character Self Shadow uniforms + sampling function + // (mirrors NiloToonEnvironment_LitForwardPass.hlsl. Both keywords required: + // _RECEIVE_NILOTOON_CHAR_SHADOW = per-material toggle, _NILOTOON_RECEIVE_SELF_SHADOW = global runtime keyword set by C# pass.) + #if defined(_RECEIVE_NILOTOON_CHAR_SHADOW) && defined(_NILOTOON_RECEIVE_SELF_SHADOW) + TEXTURE2D(_NiloToonCharSelfShadowMapRT); + SAMPLER_CMP(sampler_NiloToonCharSelfShadowMapRT_LinearClampCompare); + SAMPLER(sampler_NiloToonCharSelfShadowMapRT_Linear_Clamp); + float4x4 _NiloToonSelfShadowWorldToClip; + float4 _NiloToonSelfShadowParam; + float3 _NiloToonSelfShadowLightDirection; + float _GlobalReceiveNiloToonSelfShadowMap; + float _NiloToonSelfShadowRange; + float _NiloToonSelfShadowUseNdotLFix; + + half SampleNiloToonCharSelfShadow(float3 positionWS, float3 normalWS, float linearEyeDepth) + { + float4 positionSelfShadowCS = mul(_NiloToonSelfShadowWorldToClip, float4(positionWS, 1)); + float3 positionSelfShadowNDC = positionSelfShadowCS.xyz; + + float2 shadowMapUV = positionSelfShadowNDC.xy * 0.5 + 0.5; + float ndcZCompareValue = positionSelfShadowNDC.z; + ndcZCompareValue = UNITY_NEAR_CLIP_VALUE < 0 ? ndcZCompareValue * 0.5 + 0.5 : ndcZCompareValue; + + #if UNITY_UV_STARTS_AT_TOP + shadowMapUV.y = 1 - shadowMapUV.y; + #endif + + if(shadowMapUV.x < 0 || shadowMapUV.x > 1 || shadowMapUV.y < 0 || shadowMapUV.y > 1) + return 1; + + float shadowMapRawDepth = SAMPLE_TEXTURE2D_LOD(_NiloToonCharSelfShadowMapRT, + sampler_NiloToonCharSelfShadowMapRT_Linear_Clamp, + shadowMapUV, 0).r; + if(shadowMapRawDepth < 0.0001) + return 1; + + half shadow = SAMPLE_TEXTURE2D_SHADOW(_NiloToonCharSelfShadowMapRT, + sampler_NiloToonCharSelfShadowMapRT_LinearClampCompare, + float3(shadowMapUV, ndcZCompareValue)); + + float fadeTotalDistance = 1.0; + shadow = lerp(shadow, 1, saturate((1.0 / fadeTotalDistance) * (linearEyeDepth - (_NiloToonSelfShadowRange - fadeTotalDistance)))); + + if(_NiloToonSelfShadowUseNdotLFix > 0.5) + shadow *= smoothstep(0.1, 0.2, saturate(dot(normalWS, _NiloToonSelfShadowLightDirection))); + + return shadow; + } + #endif + #ifdef SCENEPICKINGPASS float4 _SelectionID; #endif @@ -531,6 +591,17 @@ Shader /*ase_name*/ "Hidden/Universal/NiloToonEnvironment" /*end*/ #endif Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, nilotoonShadowMask); + + // NiloToon Character Self Shadow (matches order in NiloToonEnvironment_LitForwardPass.hlsl: applied before shadow border tint) + #if defined(_RECEIVE_NILOTOON_CHAR_SHADOW) && defined(_NILOTOON_RECEIVE_SELF_SHADOW) + { + float linearEyeDepth = abs(mul(UNITY_MATRIX_V, float4(input.positionWS, 1)).z); + half charSelfShadow = SampleNiloToonCharSelfShadow(input.positionWS, inputData.normalWS, linearEyeDepth); + charSelfShadow = lerp(1, charSelfShadow, _NiloToonCharShadowStrength * _GlobalReceiveNiloToonSelfShadowMap); + color.rgb *= charSelfShadow; + } + #endif + float isShadowEdge = 1-abs(mainLight.shadowAttenuation-0.5)*2; color.rgb = lerp(color.rgb, color.rgb * _NiloToonGlobalEnviShadowBorderTintColor.rgb, isShadowEdge * _NiloToonGlobalEnviShadowBorderTintColor.a);