前言
最近在學(xué)習(xí)shader Graph相關(guān)內(nèi)容,其實(shí)關(guān)于實(shí)現(xiàn)2d圖片描邊效果,網(wǎng)上可以看到很多教程,但是我發(fā)現(xiàn)大多數(shù)都是基于比較老舊的2018unity版本,可是我們實(shí)際開發(fā)使用可能是比較新的2021及以上版本,差別還是有的,實(shí)際在升級(jí)或者使用過程中,會(huì)遇到諸多問題,而且也很少有人會(huì)分享shader Graph的連線圖源碼
沒有的話我就想著把我的學(xué)習(xí)筆記和源碼整理分享出來吧,于是就有了這篇文章
Shader
1. 內(nèi)描邊
思路:在片元著色器中,判斷當(dāng)前片元的上下左右像素(使用數(shù)值width來確定上下左右“多遠(yuǎn)”,從而得到描邊的寬度),上下左右四個(gè)像素的 alpha 分量相乘越接近0,則該像素顏色越接近描邊顏色。大致可以理解為如果某像素p的上下左右其中某個(gè)像素為透明像素,則p處于邊緣,將p像素繪制為描邊顏色。
代碼如下:
Shader "Custom_Shader/ImageInnerOutline"
{
Properties
{
_MainTex ("Sprite Texture", 2D) = "white" {}
_OutlineWidth ("Outline Width", float) = 1
_OutlineColor ("Outline Color", Color) = (1,1,1,1)
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _MainTex_TexelSize;
float _OutlineWidth;
float4 _OutlineColor;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
half2 left : TEXCOORD1;
half2 right : TEXCOORD2;
half2 up : TEXCOORD3;
half2 down : TEXCOORD5;
};
v2f vert(appdata i)
{
v2f o;
o.vertex = UnityObjectToClipPos(i.vertex);
o.uv = TRANSFORM_TEX(i.uv, _MainTex);
o.left = o.uv + half2(-1, 0) * _MainTex_TexelSize.xy * _OutlineWidth;
o.right = o.uv + half2(1, 0) * _MainTex_TexelSize.xy * _OutlineWidth;
o.up = o.uv + half2(0, 1) * _MainTex_TexelSize.xy * _OutlineWidth;
o.down = o.uv + half2(0, -1) * _MainTex_TexelSize.xy * _OutlineWidth;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 c = tex2D(_MainTex, i.uv);
float transparent = tex2D(_MainTex, i.left).a * tex2D(_MainTex, i.right).a * tex2D(_MainTex, i.up).a * tex2D(_MainTex, i.down).a;
c.rgb = lerp(_OutlineColor.rgb, c.rgb, transparent);
return c;
}
ENDCG
}
}
}
描邊效果:
內(nèi)描邊會(huì)占用圖片本身邊緣的非透明像素,當(dāng)描邊寬度增大時(shí)當(dāng)效果為
2. 外描邊
思路:在片元著色器中,處理像素p,針對(duì)p的上下左右四個(gè)像素采樣(使用一個(gè)變量width來控制描邊寬度,也就是處理上下左右多遠(yuǎn)的像素),若p本身是透明像素,則
若上下左右存在非透明像素,則當(dāng)前像素p返回描邊顏色
若上下左右都是透明像素,則返回透明即可
若 p 本身非透明像素,則返回本身顏色即可
代碼如下:
Shader "Custom_Shader/ImageOuterOutline"
{
Properties
{
_MainTex ("Sprite Texture", 2D) = "white" {}
_OutlineWidth ("Outline Width", float) = 1
_OutlineColor ("Outline Color", Color) = (1.0, 1.0, 1.0, 1.0)
_AlphaValue ("Alpha Value", Range(0, 1)) = 0.1
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _MainTex_TexelSize;
float _OutlineWidth;
float4 _OutlineColor;
float _AlphaValue;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
half2 left : TEXCOORD1;
half2 right : TEXCOORD2;
half2 up : TEXCOORD3;
half2 down : TEXCOORD5;
};
v2f vert(appdata i)
{
v2f o;
o.vertex = o.vertex + i.normal * _OutlineWidth;
o.vertex = UnityObjectToClipPos(i.vertex);
o.uv = TRANSFORM_TEX(i.uv, _MainTex);
o.left = o.uv + half2(-1, 0) * _MainTex_TexelSize.xy * _OutlineWidth;
o.right = o.uv + half2(1, 0) * _MainTex_TexelSize.xy * _OutlineWidth;
o.up = o.uv + half2(0, 1) * _MainTex_TexelSize.xy * _OutlineWidth;
o.down = o.uv + half2(0, -1) * _MainTex_TexelSize.xy * _OutlineWidth;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float transparent = tex2D(_MainTex, i.left).a + tex2D(_MainTex, i.right).a + tex2D(_MainTex, i.up).a + tex2D(_MainTex, i.down).a;
fixed4 col = tex2D(_MainTex, i.uv);
if (col.a < 0.1) {
return step(_AlphaValue, transparent) * _OutlineColor;
} else {
return col;
}
}
ENDCG
}
}
}
外描邊效果:
外描邊不會(huì)占用圖片非透明像素,但要求圖片外圍要有足夠但透明像素,當(dāng)調(diào)整外描邊寬度時(shí),效果:
描邊寬度較大時(shí),Image 圖片頂部和左邊有平滑的切割是圖片本身的范圍
Shader Graph
1. 2d圖片描邊
(ps:圖片看不清也沒關(guān)系,文件末尾我會(huì)放手demo源碼
,不清楚的可以直接查看源碼進(jìn)行學(xué)習(xí))
不同圖片上的效果
2. 帶炫光的2d圖片描邊
不同圖片上的效果
最終演示效果
源碼
https://gitcode.net/unity1/unity2d-shader-picturestroke
參考
- 【視頻】https://www.youtube.com/watch?v=Eyx3EfqqfMw&list=PLzDRvYVwl53tqzN5R-j33Sd7kf_f6b6z4
- 【文章】https://www.jianshu.com/p/c68a730e9a8b
完結(jié)
如果你發(fā)現(xiàn)了文章中存在錯(cuò)誤或者有更好的解決方法,也歡迎評(píng)論私信告訴我哦
好了,我是向宇,https://xiangyu.blog.csdn.net/文章來源:http://www.zghlxwxcb.cn/news/detail-811236.html
一位在小公司默默奮斗的開發(fā)者,出于興趣愛好,于是最近才開始自習(xí)unity。如果你有任何問題,歡迎你來評(píng)論私信告訴我, 雖然有些問題我可能也不一定會(huì),但是我會(huì)查閱各方資料,爭取給出最好的建議,希望可以幫助更多想學(xué)編程的人,共勉~文章來源地址http://www.zghlxwxcb.cn/news/detail-811236.html
到了這里,關(guān)于【實(shí)現(xiàn)100個(gè)unity特效之2】使用shader和shader Graph實(shí)現(xiàn)2d圖片描邊效果(附源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!