内置渲染管线

 

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "SunY/C14-Hatching"
{
    Properties
    {
        _Color("Color Tint", Color) = (1, 1, 1, 1)
        _TileFactor("Tile Factor", float) = 1
        _Outline("Outline", Range(0, 1)) = 0.1
        _Hatch0("Hatch 0", 2D) = "white"{}
        _Hatch1("Hatch 1", 2D) = "white"{}
        _Hatch2("Hatch 2", 2D) = "white"{}
        _Hatch3("Hatch 3", 2D) = "white"{}
        _Hatch4("Hatch 4", 2D) = "white"{}
        _Hatch5("Hatch 5", 2D) = "white"{}
    }

    SubShader
    {
        Tags { "RenderType" = "Opaque" "Queue" = "Geometry" }

        UsePass "SunY/C14-ToonShading/OUTLINE"

        Pass
        {
            Tags { "LightMode" = "ForwardBase" }

            Cull Back

            CGPROGRAM

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            #pragma vertex vert
            #pragma fragment frag

            #pragma multi_compile_fwdbase

            fixed4 _Color;
            float _TileFactor;
            sampler2D _Hatch0;
            sampler2D _Hatch1;
            sampler2D _Hatch2;
            sampler2D _Hatch3;
            sampler2D _Hatch4;
            sampler2D _Hatch5;

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                fixed3 hatchWeights0 : TEXCOORD1;
                fixed3 hatchWeights1 : TEXCOORD2;
                float3 worldPos : TEXCOORD3;
                SHADOW_COORDS(4)
            };

            v2f vert(a2v v)
            {
                v2f o;

                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord.xy * _TileFactor;

                fixed3 worldLightDir = normalize(WorldSpaceLightDir(v.vertex));
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);

                fixed diff = saturate(dot(worldLightDir, worldNormal));

                o.hatchWeights0 = fixed3(0, 0, 0);
                o.hatchWeights1 = fixed3(0, 0, 0);

                float hatchFactor = diff * 7;

                if(hatchFactor > 6.0)
                {

                }
                else if(hatchFactor > 5.0)
                {
                    o.hatchWeights0.x = hatchFactor - 5;
                }
                else if(hatchFactor > 4.0)
                {
                    o.hatchWeights0.x = hatchFactor - 4;
                    o.hatchWeights0.y = 1 - o.hatchWeights0.x;
                }
                else if(hatchFactor > 3.0)
                {
                    o.hatchWeights0.y = hatchFactor - 3;
                    o.hatchWeights0.z = 1 - o.hatchWeights0.y;
                }
                else if(hatchFactor > 2.0)
                {
                    o.hatchWeights0.z = hatchFactor - 2;
                    o.hatchWeights1.x = 1 - o.hatchWeights0.z;
                }
                else if(hatchFactor > 1.0)
                {
                    o.hatchWeights1.x = hatchFactor - 1;
                    o.hatchWeights1.y = 1 - o.hatchWeights1.x;
                }
                else
                {
                    o.hatchWeights1.y = hatchFactor;
                    o.hatchWeights1.z = 1 - o.hatchWeights1.y;
                }

                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                TRANSFER_SHADOW(o);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeights0.x;
                fixed4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeights0.y;
                fixed4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeights0.z;
                fixed4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeights1.x;
                fixed4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeights1.y;
                fixed4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeights1.z;

                fixed4 whiteColor = fixed4(1, 1, 1, 1) * (1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z);
                fixed4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor;

                UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);

                return fixed4(hatchColor.rgb * _Color.rgb * atten, 1);
            }

            ENDCG
        }
    }

    FallBack "Diffuse"
}

URP渲染管线

Shader "SunY/C14-U-Hatching"
{
    Properties
    {
        _Color("Color Tint", Color) = (1, 1, 1, 1)
        _TileFactor("Tile Factor", float) = 1
        _Outline("Outline", Range(0, 1)) = 0.1
        _Hatch0("Hatch 0", 2D) = "white"{}
        _Hatch1("Hatch 1", 2D) = "white"{}
        _Hatch2("Hatch 2", 2D) = "white"{}
        _Hatch3("Hatch 3", 2D) = "white"{}
        _Hatch4("Hatch 4", 2D) = "white"{}
        _Hatch5("Hatch 5", 2D) = "white"{}
    }

    SubShader
    {
        Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            Tags { "LightMode" = "UniversalForward" }

            Cull Back

            HLSLPROGRAM

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

            #pragma vertex vert
            #pragma fragment frag

            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE

            half4 _Color;
            float _TileFactor;

            TEXTURE2D(_Hatch0);
            SAMPLER(sampler_Hatch0);
            TEXTURE2D(_Hatch1);
            SAMPLER(sampler_Hatch1);
            TEXTURE2D(_Hatch2);
            SAMPLER(sampler_Hatch2);
            TEXTURE2D(_Hatch3);
            SAMPLER(sampler_Hatch3);
            TEXTURE2D(_Hatch4);
            SAMPLER(sampler_Hatch4);
            TEXTURE2D(_Hatch5);
            SAMPLER(sampler_Hatch5);

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                half3 hatchWeights0 : TEXCOORD1;
                half3 hatchWeights1 : TEXCOORD2;
                float3 worldPos : TEXCOORD3;
            };

            v2f vert(a2v v)
            {
                v2f o;

                o.pos = TransformObjectToHClip(v.vertex);
                o.uv = v.texcoord.xy * _TileFactor;

                Light light = GetMainLight();

                half3 worldLightDir = normalize(light.direction);
                half3 worldNormal = normalize(TransformObjectToWorldDir(v.normal));

                half diff = saturate(dot(worldLightDir, worldNormal));

                float hatchFactor = diff * 7;

                o.hatchWeights0 = half3(0, 0, 0);
                o.hatchWeights1 = half3(0, 0, 0);

                if(hatchFactor > 6.0)
                {

                }
                else if(hatchFactor > 5.0)
                {
                    o.hatchWeights0.x = hatchFactor - 5;
                }
                else if(hatchFactor > 4.0)
                {
                    o.hatchWeights0.x = hatchFactor - 4;
                    o.hatchWeights0.y = 1 - o.hatchWeights0.x;
                }
                else if(hatchFactor > 3.0)
                {
                    o.hatchWeights0.y = hatchFactor - 3;
                    o.hatchWeights0.z = 1 - o.hatchWeights0.y;
                }
                else if(hatchFactor > 2.0)
                {
                    o.hatchWeights0.z = hatchFactor - 2;
                    o.hatchWeights1.x = 1 - o.hatchWeights0.z;
                }
                else if(hatchFactor > 1.0)
                {
                    o.hatchWeights1.x = hatchFactor - 1;
                    o.hatchWeights1.y = 1 - o.hatchWeights1.x;
                }
                else
                {
                    o.hatchWeights1.y = hatchFactor;
                    o.hatchWeights1.z = 1 - o.hatchWeights1.y;
                }

                o.worldPos = TransformObjectToWorld(v.vertex).xyz;

                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                half4 hatchTex0 = SAMPLE_TEXTURE2D(_Hatch0, sampler_Hatch0, i.uv) * i.hatchWeights0.x;
                half4 hatchTex1 = SAMPLE_TEXTURE2D(_Hatch1, sampler_Hatch1, i.uv) * i.hatchWeights0.y;
                half4 hatchTex2 = SAMPLE_TEXTURE2D(_Hatch2, sampler_Hatch2, i.uv) * i.hatchWeights0.z;
                half4 hatchTex3 = SAMPLE_TEXTURE2D(_Hatch3, sampler_Hatch3, i.uv) * i.hatchWeights1.x;
                half4 hatchTex4 = SAMPLE_TEXTURE2D(_Hatch4, sampler_Hatch4, i.uv) * i.hatchWeights1.y;
                half4 hatchTex5 = SAMPLE_TEXTURE2D(_Hatch5, sampler_Hatch5, i.uv) * i.hatchWeights1.z;

                half4 whiteColor = half4(1, 1, 1, 1) * (1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z);
                half4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor;

                float4 SHADOW_COORDS = TransformWorldToShadowCoord(i.worldPos);
                Light light = GetMainLight(SHADOW_COORDS);

                return half4(hatchColor.rgb * _Color.rgb * light.shadowAttenuation, 1);
            }

            ENDHLSL
        }

        UsePass "SunY/C14-U-ToonShading/OUTLINE"
    }
}