Unity Shader實(shí)現(xiàn)新手引導(dǎo)遮罩鏤空效果
這兩天實(shí)現(xiàn)了下新手引導(dǎo)需要的遮罩鏤空shader效果,記錄一下。
1、圓形鏤空shader代碼:
//計(jì)算片元世界坐標(biāo)和目標(biāo)中心位置的距離 float dis = distance(IN.worldPosition.xy, _Center.xy); //過(guò)濾掉距離小于(半徑-過(guò)渡范圍)的片元 clip(dis - (_Radius - _TransitionRange)); //優(yōu)化if條件判斷,如果距離小于半徑則執(zhí)行下一步,等于if(dis < _Radius) fixed tmp = step(dis, _Radius); //計(jì)算過(guò)渡范圍內(nèi)的alpha值 color.a *= (1 - tmp) + tmp * (dis - (_Radius - _TransitionRange)) / _TransitionRange;
效果:忽略漸變的蒙版,隨便找的圖片

2、橢圓鏤空shader代碼:
//計(jì)算X軸方向距離 float disX = distance(IN.worldPosition.x, _Center.x); //計(jì)算Y軸方向距離 float disY = distance(IN.worldPosition.y, _Center.y); //運(yùn)用橢圓方程計(jì)算片元的alpha值,_Ellipse為橢圓系數(shù) fixed factor = clamp(pow(abs(disX / _Width), _Ellipse) + pow(abs(disY / _Height), _Ellipse), 0.0, 1.0); //優(yōu)化if條件判斷 fixed tmp = step(factor, 1.0f); //賦值橢圓外或橢圓內(nèi)的alpha值 color.a *= (1 - tmp) + tmp * factor;
效果:

3、圓形目標(biāo)位置聚合動(dòng)畫(huà)shader代碼:
//_StartTime為效果開(kāi)始時(shí)間點(diǎn),Unity中對(duì)應(yīng)賦值material.SetFloat("_StartTime", Time.timeSinceLevelLoad);
fixed processTime = _Time.y - _StartTime;
//判斷shader執(zhí)行時(shí)長(zhǎng)是否超過(guò)_TotalTime
clip(_TotalTime - processTime);
//優(yōu)化if條件判斷
fixed tmp = step(processTime, _ReduceTime);
//計(jì)算當(dāng)前時(shí)間點(diǎn)的圓形鏤空半徑
float curRadius = (1 - tmp) * _Radius + tmp * (_MaxRadius - (_MaxRadius - _Radius) * processTime / _ReduceTime);
float dis = distance(IN.worldPosition.xy, _Center.xy);
//拋棄距離小于當(dāng)前圓形鏤空半徑的片元
clip(dis - curRadius);
效果:不知道為啥上傳上來(lái)就有問(wèn)題了,正常是沒(méi)問(wèn)題的

整個(gè)shader源碼,在Unity UGUI 自帶Default shader基礎(chǔ)上添加:
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "UI/Default_Mask"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
//-------------------add----------------------
_Center("Center", vector) = (0, 0, 0, 0)
_Radius("Radius", Range(0,1000)) = 1000 // sliders
_TransitionRange("Transition Range", Range(0, 100)) = 10
_Width("Width", Float) = 1
_Height("Height", Float) = 1
_Ellipse("Ellipse", Float) = 4
_ReduceTime("ReduceTime", Float) = 1
_TotalTime("TotalTime", Float) = 1
_StartTime("StartTime", Float) = 0
_MaxRadius("MaxRadius", Float) = 1500
[KeywordEnum(ROUND, ELLIPSE, DYNAMIC_ROUND)] _RoundMode("Mask mode", Float) = 0
//-------------------add----------------------
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#pragma multi_compile _ROUNDMODE_ROUND _ROUNDMODE_ELLIPSE _ROUNDMODE_DYNAMIC_ROUND
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
//-------------------add----------------------
half _Radius;
float2 _Center;
half _TransitionRange;
half _Width;
half _Height;
half _Ellipse;
fixed _ReduceTime;
half _TotalTime;
float _StartTime;
half _MaxRadius;
//-------------------add----------------------
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = v.texcoord;
OUT.color = v.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
//-------------------add----------------------
#ifdef _ROUNDMODE_ROUND
//計(jì)算片元世界坐標(biāo)和目標(biāo)中心位置的距離
float dis = distance(IN.worldPosition.xy, _Center.xy);
//過(guò)濾掉距離小于(半徑-過(guò)渡范圍)的片元
clip(dis - (_Radius - _TransitionRange));
//優(yōu)化if條件判斷,如果距離小于半徑則執(zhí)行下一步,等于if(dis < _Radius)
fixed tmp = step(dis, _Radius);
//計(jì)算過(guò)渡范圍內(nèi)的alpha值
color.a *= (1 - tmp) + tmp * (dis - (_Radius - _TransitionRange)) / _TransitionRange;
#elif _ROUNDMODE_ELLIPSE
//計(jì)算X軸方向距離
float disX = distance(IN.worldPosition.x, _Center.x);
//計(jì)算Y軸方向距離
float disY = distance(IN.worldPosition.y, _Center.y);
//運(yùn)用橢圓方程計(jì)算片元的alpha值,_Ellipse為橢圓系數(shù)
fixed factor = clamp(pow(abs(disX / _Width), _Ellipse) + pow(abs(disY / _Height), _Ellipse), 0.0, 1.0);
//優(yōu)化if條件判斷
fixed tmp = step(factor, 1.0f);
//賦值橢圓外或橢圓內(nèi)的alpha值
color.a *= (1 - tmp) + tmp * factor;
#else
//_StartTime為效果開(kāi)始時(shí)間點(diǎn),Unity中對(duì)應(yīng)賦值material.SetFloat("_StartTime", Time.timeSinceLevelLoad);
fixed processTime = _Time.y - _StartTime;
//判斷shader執(zhí)行時(shí)長(zhǎng)是否超過(guò)_TotalTime
clip(_TotalTime - processTime);
//優(yōu)化if條件判斷
fixed tmp = step(processTime, _ReduceTime);
//計(jì)算當(dāng)前時(shí)間點(diǎn)的圓形鏤空半徑
float curRadius = (1 - tmp) * _Radius + tmp * (_MaxRadius - (_MaxRadius - _Radius) * processTime / _ReduceTime);
float dis = distance(IN.worldPosition.xy, _Center.xy);
//拋棄距離小于當(dāng)前圓形鏤空半徑的片元
clip(dis - curRadius);
#endif
//-------------------add----------------------
return color;
}
ENDCG
}
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Unity shader實(shí)現(xiàn)消融效果
- Unity shader實(shí)現(xiàn)自由放大縮小效果
- Unity Shader實(shí)現(xiàn)序列幀動(dòng)畫(huà)效果
- Unity3D中shader 輪廓描邊效果實(shí)現(xiàn)代碼
- unity shader實(shí)現(xiàn)玻璃折射效果
- Unity Shader實(shí)現(xiàn)玻璃材質(zhì)效果
- Unity Shader實(shí)現(xiàn)描邊OutLine效果
- Unity3D Shader實(shí)現(xiàn)貼圖切換效果
- Unity shader實(shí)現(xiàn)遮罩效果
- 淺談Unity中的Shader
相關(guān)文章
DevExpress SplitContainerControl用法總結(jié)
這篇文章主要介紹了DevExpress SplitContainerControl用法,對(duì)初學(xué)者有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-08-08
C#實(shí)現(xiàn)SSE(Server-Sent Events)服務(wù)端和客戶(hù)端的示例代碼
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)SSE(Server-Sent Events)服務(wù)端和客戶(hù)端的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下2024-03-03
c# 用Dictionary實(shí)現(xiàn)日志數(shù)據(jù)批量插入
這篇文章主要介紹了c# 用Dictionary實(shí)現(xiàn)日志數(shù)據(jù)批量插入的步驟,幫助大家更好的理解和使用c#中的Dictionary類(lèi),感興趣的朋友可以了解下2021-02-02
C#編程自學(xué)之?dāng)?shù)據(jù)類(lèi)型和變量三
C#語(yǔ)言類(lèi)型系統(tǒng)提出的一個(gè)核心概念裝箱(boxing)拆箱(unboxing)。裝箱和取消裝箱的概念是C#的類(lèi)型系統(tǒng)的核心。它在“值類(lèi)型”和“引用類(lèi)型”之間的架起了一座橋梁,使得任何“值類(lèi)型”的值都可以轉(zhuǎn)換為object類(lèi)型的值,反過(guò)來(lái)轉(zhuǎn)換也可以。2015-10-10
C#使用SqlServer作為日志數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
這篇文章主要給大家介紹了關(guān)于C#使用SqlServer作為日志數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

