生活随笔
收集整理的這篇文章主要介紹了
Unity Shader 实现透明护盾效果
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這是大致的效果圖,圖片壓得有點糊。我參考了本篇博客 Unity shader護盾特效.
這是原博客展示的圖片:
本例采用了特殊的模型與貼圖,原博客里有視頻鏈接的教程,從模型到貼圖。
以下是代碼
Shader
"Summer/Shield"
{Properties
{_MainTex ("Texture", 2D
) = "white" {}_ScanTex ("Scan Texture", 2D
) = "white" {}_Color("Color",Color
)=(0,0,0,1)_ScanColor("Scan Color",Color
)=(0,0,0,1)_RimColor("rim color",Color
) = (1,1,1,1)_RimPower ("rim power",range(1,10)) = 2_FresnelScale("ScanFresnelScale",range(0,1))=0.5_ScanSpeed("ScanSpeed",range(0,2))=0.5_ScanScale("ScanScale",range(0,1))=0.1}SubShader
{Tags
{ "Queue"="Transparent""IgnoreProjector" = "True" "RenderType" = "Transparent" }LOD 100ZWrite OffBlend SrcAlpha OneMinusSrcAlpha
CGINCLUDE#include
"UnityCG.cginc"struct appdata
{float4 vertex
: POSITION;float2 uv
: TEXCOORD0;float2 scanUV
:TEXCOORD1;fixed4 color
:COLOR;float3 normal
:NORMAL;};struct v2f
{float2 uv
: TEXCOORD0;float4 vertex
: SV_POSITION;fixed4 vertColor
:TEXCOORD1;float2 scanUV
:TEXCOORD2;};sampler2D _MainTex
;float4 _MainTex_ST
;fixed4 _Color
;sampler2D _ScanTex
;float4 _ScanTex_ST
;fixed4 _ScanColor
;float _ScanSpeed
;fixed4 _RimColor
;float _RimPower
;fixed _FresnelScale
;fixed _ScanScale
;v2f
vert (appdata v
){v2f o
;o
.vertex
= UnityObjectToClipPos(v
.vertex
);o
.uv
= TRANSFORM_TEX(v
.uv
, _MainTex
);o
.scanUV
=TRANSFORM_TEX(v
.scanUV
,_ScanTex
);float3
V = WorldSpaceViewDir(v
.vertex
);V = mul(unity_WorldToObject
,V);o
.vertColor
=v
.color
;o
.vertColor
.r
= dot(v
.normal
,normalize(V));o
.vertColor
.r
*=sign(o
.vertColor
.r
);return o
;}fixed4
frag (v2f i
) : SV_Target
{fixed4 col
= tex2D(_MainTex
, i
.uv
);i
.scanUV
.y
+=_Time
.y
*_ScanSpeed
;fixed scanF
=tex2D(_ScanTex
,i
.scanUV
).a
;clip(-scanF
);col
=col
*i
.vertColor
.a
*_Color
;fixed fresnel
=_FresnelScale
+(1-_FresnelScale
)*pow((1-i
.vertColor
.r
),_RimPower
);fixed fresnleAlpha
=lerp(0,1,fresnel
);fixed4 backCol
=fixed4(_RimColor
.rgb
,fresnleAlpha
);fixed4 fianlColor
=(col
+backCol
)+_ScanColor
*scanF
;return fianlColor
;}v2f
vert_Convex(appdata v
){v2f o
;o
.vertex
= UnityObjectToClipPos(v
.vertex
);o
.uv
= TRANSFORM_TEX(v
.uv
, _MainTex
);o
.scanUV
=TRANSFORM_TEX(v
.scanUV
,_ScanTex
);float3
V = WorldSpaceViewDir(v
.vertex
);V = mul(unity_WorldToObject
,V);o
.vertColor
=v
.color
;o
.vertColor
.r
= dot(v
.normal
,normalize(V));o
.vertColor
.r
*=sign(o
.vertColor
.r
);float4 pos
=mul(UNITY_MATRIX_MV,v
.vertex
);float3 normal
=mul((float3x3
)UNITY_MATRIX_IT_MV,v
.normal
);normal
.z
-=0.2;pos
+=float4(normalize(normal
),0)*(_ScanScale
);o
.vertex
=mul(UNITY_MATRIX_P,pos
);return o
;}fixed4
frag_Convex (v2f i
) : SV_Target
{fixed4 col
= tex2D(_MainTex
, i
.uv
);i
.scanUV
.y
+=_Time
.y
*_ScanSpeed
;fixed scanF
=tex2D(_ScanTex
,i
.scanUV
).a
;if(scanF
==0){discard
;}col
=col
*i
.vertColor
.a
*_Color
*(1-i
.vertColor
.a
);fixed fresnel
=_FresnelScale
+(1-_FresnelScale
)*pow((1-i
.vertColor
.r
),_RimPower
);fixed fresnleAlpha
=lerp(0,1,fresnel
);fixed4 backCol
=fixed4(_ScanColor
.rgb
,fresnleAlpha
);fixed4 fianlColor
=col
+backCol
+fresnleAlpha
*_ScanColor
;return fianlColor
;}ENDCGPass
{Cull Off
CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fwdbase
ENDCG}Pass
{CGPROGRAM#pragma vertex vert_Convex#pragma fragment frag_Convex#pragma multi_compile_fwdbase
ENDCG}}
}
主要思路是兩個Pass,一個渲染主體,該部分要剔除掉掃描到的部分;第二個Pass渲染掃描部分,即頂點經過偏移(向法線方向突出),該部分剔除未掃描的部分,從而實現一個動態掃描頂點偏移的效果。一開始我想的是一個Pass,在vert里進行掃描圖片(掃描圖片:一張模擬掃描效果的貼圖,類似流光貼圖)的采樣,然后將該頂點偏移,但后來發現tex2D獲取的值不能在vert里使用(我也不知道為什么,一用就報錯),最后只能用這種最簡單的方式。
第一個Pass部分
float3
V = WorldSpaceViewDir(v
.vertex
);V = mul(unity_WorldToObject
,V);o
.vertColor
=v
.color
;o
.vertColor
.r
= dot(v
.normal
,normalize(V));o
.vertColor
.r
*=sign(o
.vertColor
.r
);不用saturate的原因是saturate將小于
0的取為,而我關了剔除,這樣看到背面就是純色而沒有透明效果
i
.scanUV
.y
+=_Time
.y
*_ScanSpeed
;fixed scanF
=tex2D(_ScanTex
,i
.scanUV
).a
;clip(-scanF
);
fixed fresnel
=_FresnelScale
+(1-_FresnelScale
)*pow((1-i
.vertColor
.r
),_RimPower
);fixed fresnleAlpha
=lerp(0,1,fresnel
);fixed4 backCol
=fixed4(_RimColor
.rgb
,fresnleAlpha
);
第二個Pass部分
進行頂點變換,在視角空間下進行沿法線方向的頂點偏移float4 pos
=mul(UNITY_MATRIX_MV,v
.vertex
);float3 normal
=mul((float3x3
)UNITY_MATRIX_IT_MV,v
.normal
);normal
.z
-=0.2;pos
+=float4(normalize(normal
),0)*(_ScanScale
);o
.vertex
=mul(UNITY_MATRIX_P,pos
);
剔除Alpha值為零,即未掃描到的像素i
.scanUV
.y
+=_Time
.y
*_ScanSpeed
;fixed scanF
=tex2D(_ScanTex
,i
.scanUV
).a
;if(scanF
==0){discard
;}
好了,這大概就是全部了,感謝你的閱讀,如有錯誤,歡迎舉正。
總結
以上是生活随笔為你收集整理的Unity Shader 实现透明护盾效果的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。