内置渲染管线
// 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" } }