URP多Pass解决方案

允许自定义效果的最多三个Pass(除去投射阴影、写入深度贴图这些)以及他们的顺序
在这里插入图片描述
对于的源码:2021.3.7版本
使用这种描边的前提

Shader "Render Style/Wild Fighting/Character"
{
    Properties
    {
        [Header(Color)]
        _MainTex("Base Map", 2D) = "white"{}
        _Alpha ("Alpha", Range(0, 1)) = 1
        
        [Header(Outline)]
        [IntRange] _Flag ("Flag", Range(0, 255)) = 1
        _OutlineWidth ("Outline Width", float) = 0.5
        _OutlineColor ("Outline Color", color) = (0,0,0,1)

        [Header(Light)]
        _Addtive ("Addtive", Range(0, 1)) = 0.5
        _SpecularPower ("Specular Power", float) = 5
        _SpecularStrength ("Specular Strength", float) = 0.5
        _RimColor ("Rim Color", color) = (1,1,1,1)
        _RimPower ("Rim Power", float) = 5
        _RimStrength ("Rim Strength", float) = 0.5
    }

    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" "RenderPipeline" = "UniversalPipeline" }

        Pass // Write Z
        {
            Name "PreZ"
            Tags { "LightMode"="SRPDefaultUnlit" }

            Stencil
            {
                Ref [_Flag]
                Comp Always
                Pass Replace
            }

            ZWrite On
            ColorMask 0
        }

        Pass // Outline
        {
            Name "Outline"
            Tags { "LightMode"="UniversalForwardOnly" }

            Stencil
            {
                Ref [_Flag]
                Comp NotEqual
                Pass Replace
            }

            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

	        HLSLPROGRAM
	        #pragma vertex vert	
            #pragma fragment frag

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

	        struct appdata
	        {
		        float4 vertex : POSITION;
                float3 tangent : TANGENT;
	        };

	        struct v2f
	        {
		        float4 vertex : SV_POSITION;
	        };

	        half4 _OutlineColor;
	        half _OutlineWidth;
            half _Alpha;

	        v2f vert(appdata v)
	        {
		        v2f o;

                o.vertex = TransformObjectToHClip(v.vertex);

				float3 vnormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.tangent);
				float2 offset = mul((float2x2)UNITY_MATRIX_P, vnormal.xy);
				o.vertex.xy += offset * _OutlineWidth * 0.01;

		        return o;
	        }

	        half4 frag(v2f i) : SV_Target
	        {
		        return half4(_OutlineColor.rgb, _Alpha);
	        }
            ENDHLSL
        }

        Pass // 基础光照
        {
            Name "Light"
            Tags { "LightMode"="UniversalForward" }

            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

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

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
                float3 normalOS : NORMAL;
            };

            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
                float3 normalWS : TEXCOORD2;
            };

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);
            float4 _MainTex_ST;

            half _Alpha;
            float _Addtive;
            float _SpecularPower;
            float _SpecularStrength;
            half4 _RimColor;
            float _RimPower;
            float _RimStrength;

            half4 LightFunc(float3 worldPos, float3 worldNormal, out half4 rimColor)
            {
                Light light = GetMainLight();

                half3 lightDir = normalize(light.direction);
                half3 normalDir = normalize(worldNormal);
                half3 viewDir = normalize(_WorldSpaceCameraPos.xyz - worldPos);
                half3 reflectDir = reflect(-lightDir, normalDir);

                float NdotL = saturate(dot(normalDir, lightDir));
                float NdotR = saturate(dot(normalDir, reflectDir));
                float NdotV = saturate(dot(normalDir, viewDir));

                half4 lightColor = half4(light.color, 1);
                half4 ambient = UNITY_LIGHTMODEL_AMBIENT;
                float AddtiveNdotL = NdotL * (1 - _Addtive) + _Addtive;
                half4 diffuse = AddtiveNdotL * lightColor;
                half4 specular = pow(NdotR, _SpecularPower) * lightColor * _SpecularStrength;
                float rim = pow(1 - NdotV, _RimPower) * _RimStrength * NdotL;
                rimColor = _RimColor * rim;

                return ambient + max(diffuse, specular);
            }

            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
                OUT.positionWS = TransformObjectToWorld(IN.positionOS).xyz;
                OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS);
  
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
                half3 col = tex.rgb;
                half alpha = tex.a * _Alpha;

                half4 rimColor;
                half4 lightColor = LightFunc(IN.positionWS, IN.normalWS, rimColor);
                col *= lightColor;
                col += rimColor;

                return half4(col, alpha);
            }
            ENDHLSL
        }

        UsePass "Universal Render Pipeline/Lit/ShadowCaster"
    }
}


版权声明:本文为derbi123123原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。