卡渲前向Pss ToonForwardPass

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"



struct Attributes

{

    float4 positionOS   : POSITION;

    float3 normalOS     : NORMAL;

    float4 tangentOS    : TANGENT;

    float4 color        : COLOR;

    float2 uv           : TEXCOORD0;

    float2 backUV       : TEXCOORD1;

};



struct Varyings

{

    float2 uv           : TEXCOORD0;

    float2 backUV       : TEXCOORD1;

    float3 positionWS   : TEXCOORD2;

    half3 tangentWS     : TEXCOORD3;

    half3 bitangentWS   : TEXCOORD4;

    half3 normalWS      : TEXCOORD5;

    float4 positionNDC  : TEXCOORD6;

    half4 color         : COLOR;

    float4 positionCS   : SV_POSITION;

};



half GetShadow(Varyings input, half3 lightDirection, half aoFactor)

{

    half NDotL = dot(input.normalWS, lightDirection);

    half halfLambert = 0.5 * NDotL + 0.5;

    half shadow = saturate(2.0 * halfLambert * aoFactor);

    return lerp(shadow, 1.0, step(0.9, aoFactor));

}



half GetFaceShadow(Varyings input, half3 lightDirection)

{

    half3 F = SafeNormalize(half3(_FaceDirection.x, 0.0, _FaceDirection.z));

    half3 L = SafeNormalize(half3(lightDirection.x, 0.0, lightDirection.z));

    half FDotL = dot(F, L);

    half FCrossL = cross(F, L).y;

    half2 shadowUV = input.uv;

    shadowUV.x = lerp(shadowUV.x, 1.0 - shadowUV.x, step(0.0, FCrossL));

    half faceShadowMap = SAMPLE_TEXTURE2D(_FaceLightMap, sampler_FaceLightMap, shadowUV).r;

    half faceShadow = step(-0.5 * FDotL + 0.5 + _FaceShadowOffset, faceShadowMap);



    half faceMask = SAMPLE_TEXTURE2D(_FaceShadow, sampler_FaceShadow, input.uv).a;

    half maskedFaceShadow = lerp(faceShadow, 1.0, faceMask);



    return maskedFaceShadow;

}



half3 GetShadowColor(half shadow, half material, half day)

{

    int index = 4;

    index = lerp(index, 1, step(0.2, material));

    index = lerp(index, 2, step(0.4, material));

    index = lerp(index, 0, step(0.6, material));

    index = lerp(index, 3, step(0.8, material));



    half rangeMin = 0.5 + _ShadowOffset - _ShadowSmoothness;

    half rangeMax = 0.5 + _ShadowOffset;

    half2 rampUV = half2(smoothstep(rangeMin, rangeMax, shadow), index / 10.0 + 0.5 * day + 0.05);

    half3 shadowRamp = SAMPLE_TEXTURE2D(_ShadowRamp, sampler_ShadowRamp, rampUV);



    half3 shadowColor = shadowRamp * lerp(_ShadowColor, 1.0, smoothstep(0.9, 1.0, rampUV.x));

    shadowColor = lerp(shadowColor, 1.0, step(rangeMax, shadow));



    return shadowColor;

}



half3 GetSpecular(Varyings input, half3 lightDirection, half3 albedo, half3 lightMap)

{

    half3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);

    half3 H = SafeNormalize(lightDirection + V);

    half NDotH = dot(input.normalWS, H);

    half blinnPhong = pow(saturate(NDotH), _SpecularSmoothness);



    half3 normalVS = TransformWorldToViewNormal(input.normalWS, true);

    half2 matcapUV = 0.5 * normalVS.xy + 0.5;

    half3 metalMap = SAMPLE_TEXTURE2D(_MetalMap, sampler_MetalMap, matcapUV);



    half3 nonMetallic = step(1.1, lightMap.b + blinnPhong) * lightMap.r * _NonmetallicIntensity;

    half3 metallic = blinnPhong * lightMap.b * albedo * metalMap * _MetallicIntensity;

    half3 specular = lerp(nonMetallic, metallic, step(0.9, lightMap.r));



    return specular;

}



half GetRim(Varyings input)

{

    half3 normalVS = TransformWorldToViewNormal(input.normalWS, true);

    float2 uv = input.positionNDC.xy / input.positionNDC.w;

    float2 offset = float2(_RimOffset * normalVS.x / _ScreenParams.x, 0.0);



    float depth = LinearEyeDepth(SampleSceneDepth(uv), _ZBufferParams);

    float offsetDepth = LinearEyeDepth(SampleSceneDepth(uv + offset), _ZBufferParams);

    half rim = smoothstep(0.0, _RimThreshold, offsetDepth - depth) * _RimIntensity;



    half3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);

    half NDotV = dot(input.normalWS, V);

    half fresnel = pow(saturate(1.0 - NDotV), 5.0);



    return rim * fresnel;

}



Varyings ForwardPassVertex(Attributes input)

{

    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);

    VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);



    Varyings output = (Varyings)0;

    output.uv = TRANSFORM_TEX(input.uv, _BaseMap);

    output.backUV = TRANSFORM_TEX(input.backUV, _BaseMap);

    output.positionWS = vertexInput.positionWS;

    output.tangentWS = normalInput.tangentWS;

    output.bitangentWS = normalInput.bitangentWS;

    output.normalWS = normalInput.normalWS;

    output.color = input.color;

    output.positionNDC = vertexInput.positionNDC;

    output.positionCS = vertexInput.positionCS;



    output.positionCS.xy += _ScreenOffset.xy * output.positionCS.w;



    return output;

}



half4 ForwardPassFragment(Varyings input, FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC) : SV_TARGET

{

#if _DOUBLE_SIDED

    input.uv = lerp(input.uv, input.backUV, IS_FRONT_VFACE(facing, 0.0, 1.0));

#endif



    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);

    half3 albedo = baseMap.rgb * _BaseColor.rgb;

    half alpha = baseMap.a;



#if _IS_FACE

    albedo = lerp(albedo, _FaceBlushColor.rgb, _FaceBlushStrength * alpha);

#endif



#if _NORMAL_MAP

    half3x3 tangentToWorld = half3x3(input.tangentWS, input.bitangentWS, input.normalWS);

    half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.uv);

    half3 normalTS = UnpackNormal(normalMap);

    half3 normalWS = TransformTangentToWorld(normalTS, tangentToWorld, true);

    input.normalWS = normalWS;

#endif



    Light mainLight = GetMainLight();

    half3 lightDirection = SafeNormalize(mainLight.direction * _LightDirectionMultiplier);



    half4 lightMap = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, input.uv);

    half material = lerp(lightMap.a, _CustomMaterialType, _UseCustomMaterialType);

#if _IS_FACE

        half shadow = GetFaceShadow(input, lightDirection);

#else

        half aoFactor = lightMap.g * input.color.r;

        half shadow = GetShadow(input, lightDirection, aoFactor);

#endif

    half3 shadowColor = GetShadowColor(shadow, material, _IsDay);



    half3 specular = 0.0;

#if _SPECULAR

    specular = GetSpecular(input, lightDirection, albedo, lightMap.rgb);

#endif



    half3 emission = 0.0;

#if _EMISSION

    emission = albedo * _EmissionIntensity * alpha;

#endif



    half3 rim = 0.0;

#if _RIM

    rim = albedo * GetRim(input);

#endif



    half3 finalColor = albedo * shadowColor + specular + rim + emission;

    half finalAlpha = 1.0;



    return half4(finalColor, finalAlpha);

}