基本思路:Shader用两个Pass,一个渲染描边部分,一个渲染物体部分。
Pass1:剔除正面,渲染背面,把顶点延法线方向外围扩展一定宽度,用来表现描边的粗细,这部分用自己设定的颜色。
Pass2:剔除背面,渲染正面,正常渲染所看到的物体模型。
1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'mul(UNITY_MATRIX_MVP,*)' 2 3 Shader "xj/ModelEffect/Outline" { 4 Properties { 5 _Color ("模型颜色", Color) = (1,1,1,1) 6 _OutlineColor ("描边颜色", Color) = (1,0,0,1) 7 _Outline ("描边宽度", float) = 0.03 8 _MainTex ("模型贴图", 2D) = "white" {} 9 _AlphaTex ("Alpha (A)", 2D) = "white" {} 10 _intensity ("强度", float ) = 1.0 11 } 12 13 CGINCLUDE 14 #include "UnityCG.cginc" 15 16 struct appdata { 17 float4 vertex : POSITION; 18 float3 normal : NORMAL; 19 half2 texcoord : TEXCOORD0; 20 }; 21 22 struct v2f { 23 float4 pos : SV_POSITION; 24 fixed4 color : COLOR; 25 half2 texcoord : TEXCOORD0; 26 }; 27 28 struct basevt { 29 float4 pos : SV_POSITION; 30 half2 texcoord : TEXCOORD0; 31 }; 32 33 sampler2D _MainTex; 34 sampler2D _AlphaTex; 35 uniform fixed _Outline; 36 uniform fixed4 _OutlineColor; 37 uniform fixed4 _Color; 38 fixed _intensity; 39 40 v2f outline_vert(appdata v) 41 { 42 //在vertex阶段,每个顶点按照法线的方向偏移一部分,不过这种会造成近大远小的透视问题 43 //正确的做法是转换到投影空间下做偏移 44 //v.vertex.xyz += v.normal * _Outline; 45 46 v2f o; 47 o.pos = mul(UNITY_MATRIX_MVP,v.vertex); 48 float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal); 49 float2 offset = TransformViewToProjection(norm.xy); 50 o.pos.xy += offset * _Outline; 51 o.color = _OutlineColor; 52 o.texcoord = v.texcoord; 53 return o; 54 } 55 56 fixed4 outline_frag(v2f i): SV_Target 57 { 58 fixed4 color = i.color; 59 color.a = tex2D(_AlphaTex, i.texcoord).a; 60 return color; 61 } 62 63 basevt base_vert(appdata v) 64 { 65 basevt o; 66 o.pos = mul(UNITY_MATRIX_MVP,v.vertex); 67 o.texcoord = v.texcoord; 68 return o; 69 } 70 71 fixed4 base_frag(basevt i): SV_Target 72 { 73 fixed4 col = tex2D(_MainTex, i.texcoord) * _Color * _intensity; 74 col.a = tex2D(_AlphaTex, i.texcoord).a * _Color.a; 75 return col; 76 } 77 ENDCG 78 79 SubShader { 80 Tags { "Queue" = "Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} 81 Fog {Mode Off} 82 83 Pass 84 { 85 Name "OUTLINE" 86 Cull Front //剔除正面 87 CGPROGRAM 88 89 #pragma vertex outline_vert 90 #pragma fragment outline_frag 91 #pragma fragmentoption ARB_precision_hint_fastest 92 93 ENDCG 94 } 95 96 Pass 97 { 98 Name "BASE" 99 Cull Back //剔除背面 100 CGPROGRAM 101 102 #pragma vertex base_vert 103 #pragma fragment base_frag 104 #pragma fragmentoption ARB_precision_hint_fastest 105 106 ENDCG 107 } 108 } 109 FallBack "xj/Default" 110 }