这篇文章主要为大家详细介绍了Unity Shader实现新手引导遮罩镂空效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这两天实现了下新手引导需要的遮罩镂空shader效果,记录一下。
1、圆形镂空shader代码:
//计算片元世界坐标和目标中心位置的距离
float dis = distance(IN.worldPosition.xy, _Center.xy);
//过滤掉距离小于(半径-过渡范围)的片元
clip(dis - (_Radius - _TransitionRange));
//优化if条件判断,如果距离小于半径则执行下一步,等于if(dis < _Radius)
fixed tmp = step(dis, _Radius);
//计算过渡范围内的alpha值
color.a *= (1 - tmp) + tmp * (dis - (_Radius - _TransitionRange)) / _TransitionRange;
效果:忽略渐变的蒙版,随便找的图片
2、椭圆镂空shader代码:
//计算X轴方向距离
float disX = distance(IN.worldPosition.x, _Center.x);
//计算Y轴方向距离
float disY = distance(IN.worldPosition.y, _Center.y);
//运用椭圆方程计算片元的alpha值,_Ellipse为椭圆系数
fixed factor = clamp(pow(abs(disX / _Width), _Ellipse) + pow(abs(disY / _Height), _Ellipse), 0.0, 1.0);
//优化if条件判断
fixed tmp = step(factor, 1.0f);
//赋值椭圆外或椭圆内的alpha值
color.a *= (1 - tmp) + tmp * factor;
效果:
3、圆形目标位置聚合动画shader代码:
//_StartTime为效果开始时间点,Unity中对应赋值material.SetFloat("_StartTime", Time.timeSinceLevelLoad);
fixed processTime = _Time.y - _StartTime;
//判断shader执行时长是否超过_TotalTime
clip(_TotalTime - processTime);
//优化if条件判断
fixed tmp = step(processTime, _ReduceTime);
//计算当前时间点的圆形镂空半径
float curRadius = (1 - tmp) * _Radius + tmp * (_MaxRadius - (_MaxRadius - _Radius) * processTime / _ReduceTime);
float dis = distance(IN.worldPosition.xy, _Center.xy);
//抛弃距离小于当前圆形镂空半径的片元
clip(dis - curRadius);
效果:不知道为啥上传上来就有问题了,正常是没问题的
整个shader源码,在Unity UGUI 自带Default shader基础上添加:
// 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
//计算片元世界坐标和目标中心位置的距离
float dis = distance(IN.worldPosition.xy, _Center.xy);
//过滤掉距离小于(半径-过渡范围)的片元
clip(dis - (_Radius - _TransitionRange));
//优化if条件判断,如果距离小于半径则执行下一步,等于if(dis < _Radius)
fixed tmp = step(dis, _Radius);
//计算过渡范围内的alpha值
color.a *= (1 - tmp) + tmp * (dis - (_Radius - _TransitionRange)) / _TransitionRange;
#elif _ROUNDMODE_ELLIPSE
//计算X轴方向距离
float disX = distance(IN.worldPosition.x, _Center.x);
//计算Y轴方向距离
float disY = distance(IN.worldPosition.y, _Center.y);
//运用椭圆方程计算片元的alpha值,_Ellipse为椭圆系数
fixed factor = clamp(pow(abs(disX / _Width), _Ellipse) + pow(abs(disY / _Height), _Ellipse), 0.0, 1.0);
//优化if条件判断
fixed tmp = step(factor, 1.0f);
//赋值椭圆外或椭圆内的alpha值
color.a *= (1 - tmp) + tmp * factor;
#else
//_StartTime为效果开始时间点,Unity中对应赋值material.SetFloat("_StartTime", Time.timeSinceLevelLoad);
fixed processTime = _Time.y - _StartTime;
//判断shader执行时长是否超过_TotalTime
clip(_TotalTime - processTime);
//优化if条件判断
fixed tmp = step(processTime, _ReduceTime);
//计算当前时间点的圆形镂空半径
float curRadius = (1 - tmp) * _Radius + tmp * (_MaxRadius - (_MaxRadius - _Radius) * processTime / _ReduceTime);
float dis = distance(IN.worldPosition.xy, _Center.xy);
//抛弃距离小于当前圆形镂空半径的片元
clip(dis - curRadius);
#endif
//-------------------add----------------------
return color;
}
ENDCG
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持得得之家。
沃梦达教程
本文标题为:Unity Shader实现新手引导遮罩镂空效果
基础教程推荐
猜你喜欢
- C#控制台实现飞行棋小游戏 2023-04-22
- ZooKeeper的安装及部署教程 2023-01-22
- 一个读写csv文件的C#类 2022-11-06
- C#类和结构详解 2023-05-30
- unity实现动态排行榜 2023-04-27
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C# windows语音识别与朗读实例 2023-04-27
- winform把Office转成PDF文件 2023-06-14
- C# List实现行转列的通用方案 2022-11-02
- C# 调用WebService的方法 2023-03-09