3.頂點外擴方法實現的描邊shader
阿新 • • 發佈:2019-01-22
描邊shader的實現有很多種,頂點外擴是其中之一。頂點外擴的原理是用2個Pass 渲染物體2次
(1)效果最好。
(2)適用範圍廣。
缺點:
(1)對效率有一定影響。因為有2個Pass,所以DrawCall為正常的2倍
附上工程連線:http://download.csdn.net/detail/yinfourever/9565336
第一遍:描邊,頂點沿法線方向外拓後用黑色渲染。外擴這一步的實現是在投影空間,也就是2D的,根絕法線的x和y值進行外擴,因為是沿著法線方向外擴,所以法線越和攝像機方向相同,也就是越接近面向攝像機的頂點,頂點的位置變化的越小,當法線和攝像機方向相同時,不會有任何變化。
第一遍渲染後,實際的影象如下:
第二遍:正常渲染物體,與第一遍渲染的混合在一起
(1)效果最好。
(2)適用範圍廣。
缺點:
(1)對效率有一定影響。因為有2個Pass,所以DrawCall為正常的2倍
(2)對於法線過度不均勻的模型,比如立方體,輪廓會有縫隙。
上邊的立方體例子我是特意把描邊的外擴值調到很大,便於理解。由第一遍渲染後的圖和第二遍渲染後的圖的對比,很容易理解這個方法的原理。其實就是通過法線來把邊緣進行位移,如果不是邊緣,則不位移,比如立方體的正面。在第二次渲染後,會覆蓋同位置的畫素,因為邊緣已經外擴,畫素的位置已經不是原來的位置,因此不會被覆蓋,而像位於立方體正面的畫素,則會被第二次渲染時覆蓋,最後就混合成了帶黑邊的效果圖。
Shader "Study/3_OutLine" { Properties { _MainTex("Texture", 2D) = "white"{} _LineSize("OutlineSize", range(0, 0.1)) = 0.02 _LineColor("LineColor", Color) = (0,0,0,1) } SubShader { Pass { Tags{ "LightMode" = "Always" } // 先繪製這個純色的頂點,然後在下一個pass繪製物件 //這裡不存在前後面,關閉裁剪前後面,也不需要深度快取 Cull Off // 關閉剔除,模型前後都會顯示 ZWrite Off // 系統預設是開的,要關閉。關閉深度快取,後渲染的物體會根據ZTest的結果將自己渲染輸出寫入 ZTest Always // 深度測試[一直顯示],被其他物體擋住後,此pass繪製的顏色會顯示出來 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float _LineSize; float4 _LineColor; struct v2f { float4 pos:SV_POSITION; float4 color : COLOR; }; v2f vert(appdata_full v) { v2f o; // 獲取模型的最終的投影座標 o.pos = mul(UNITY_MATRIX_MVP, v.vertex); // UNITY_MATRIX_IT_MV為【模型座標-世界座標-攝像機座標】【專門針對法線的變換】 // 法線乘以MV,將模型空間 轉換 檢視空間 float3 norm = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal); // 轉換 檢視空間 到 投影空間 【3D轉2D】 float2 offset = TransformViewToProjection(norm.xy); // 得到的offset,模型被擠的非常大,然後乘以倍率 o.pos.xy += offset * _LineSize; o.color = _LineColor; return o; } float4 frag(v2f i) : COLOR { return i.color; } ENDCG } Pass { // 直接使用頂點和片段shader顯示物體 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; struct v2f { float4 pos:SV_POSITION; float2 uv : TEXCOORD0;// 紋理,相對自身的座標軸,float2是一個平面 }; v2f vert(appdata_full v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } float4 frag(v2f i) : COLOR { float4 texCol = tex2D(_MainTex, i.uv); return texCol; } ENDCG } } }
附上工程連線:http://download.csdn.net/detail/yinfourever/9565336