Shader "Custom/Shader" { Properties { _Color("Main Tint", Color) = (1,1,1,1) _MainTex ("Texture", 2D) = "white" {} _OutlineWidth("OutlineWidth",Range(0,1)) = 0.1 _OutlineColor("OutlineColor", Color) = (1, 1, 1, 1) _AlphaBlend ("AlphaBlend",Range(0,1)) = 0.8 // 用於在透明紋理的基礎上控制整體的透明度 _AlphaTest ("AlphaTest",Range(0,1)) = 0.5 } SubShader { // RenderType標簽可以讓Unity把這個Shader歸入到提前定義的組(Transparent)用於指明該Shader是一個使用了透明度混合的Shader // IgnoreProjector=True這意味着該Shader不會受到投影器(Projectors)的影響 // 為了使用透明度混合的Shader一般都應該在SubShader中設置這三個標簽 Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } //第一個Pass,開啟深度寫入,不輸出顏色,處理AlphaTest部分 Pass{ // 僅僅是把模型的深度信息寫入深度緩沖中從而剔除模型中被自身遮擋的片元 ZWrite On // 用於設置顏色通道的寫掩碼(Wirte Mask)ColorMask RGB|A|0|(R/G/B/A組合) // 當為0時意味着該Pass不寫入任何顏色通道,也就不會輸出任何顏色 //也可以不用,這樣就能刻意控制AlphaTest導致的發絲邊緣的顏色 ColorMask 0 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; fixed _AlphaTest; struct a2v { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target{ fixed4 texColor = tex2D(_MainTex, i.uv); clip(texColor.a - _AlphaTest); //進行AlphaTest //clip函數,但參數為負數則舍棄該片元輸出 return fixed4(0,0,0,1); } ENDCG } //第二個Pass,關閉深度寫入,處理AlphaBlend半透明,處理光照等部分 Pass{ // 向前渲染路徑的方式 Tags{ "LightMode" = "ForwardBase" } Cull Off //關閉剔除,讓頭發雙面顯示 ZWrite Off //關閉深度寫入 //透明度混合需要關閉深度寫入 //Orgb = SrcAlpha * Srgb + OneMinusSrcAlpha * Drgb //Oa = SrcAlpha * Sa + OneMinusSrcAlpha * Da //將本Shader計算出的顏色值(源顏色值) * 源Alpha值 + 目標顏色值(可以理解為背景色) * (1-源Alpha值),從而讓源物體展示出了(1-alpha)的透明度。 Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed _AlphaBlend; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float3 worldNormal : TEXCOORD0; float3 worldPos : TEXCOORD1; float2 uv : TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target{ fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed4 texColor = tex2D(_MainTex, i.uv); fixed3 albedo = texColor.rgb * _Color; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir)); // 設置透明度通道的值 return fixed4(ambient + diffuse, texColor.a * _AlphaBlend); } ENDCG } //第三個Pass,處理描邊 Pass{ Cull Front //剔除正面 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; fixed _AlphaTest; float _OutlineWidth; float4 _OutlineColor; struct a2v { float4 vertex : POSITION; float4 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD2; }; v2f vert(a2v v) { v2f o; //o.pos = mul(UNITY_MATRIX_MVP, v.vertex); //float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal); //float2 offset = TransformViewToProjection(normal.xy); //o.pos.xy += offset *o.pos.z * _OutlineWidth; //方法二: //o.pos = UnityObjectToClipPos(v.vertex); //float3 normal = UnityObjectToWorldNormal(v.normal); //normal = mul(UNITY_MATRIX_VP, normal); //o.pos.xyz += normal * _Outline; float4 pos = mul(UNITY_MATRIX_MV, v.vertex); // viewPos,頂點變換到視角空間 float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal); // viewNormal,UNITY_MATRIX_IT_MV這個針對方向向量,法線變換 normal.z = -0.5; // viewNormal 對頂點法線的z分量進行處理,使他們等於一個定值 float4 newNoraml = float4(normalize(normal), 0); //歸一化后的noraml pos = pos + newNoraml * _OutlineWidth; // viewPos 沿法線方向對頂點進行擴大 o.pos = mul(UNITY_MATRIX_P, pos); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 texColor = tex2D(_MainTex, i.uv); //AlphaTest為了讓描邊也能根據透貼部分來勾邊,也可以不加 clip(texColor.a - _AlphaTest); return _OutlineColor; } ENDCG } } FallBack "Diffuse" }
轉載至:https://blog.csdn.net/zolin7/article/details/79647120