简介
游戏中经常会看到特效给人眼前一亮的感觉,例如当怪物死亡时逐渐消逝的效果、人物由隐形状态逐渐显形的效果。本篇文章将从Shader的角度去思考如何通过代码去实现这些效果。
原理
- 噪声图:利用噪声图的特性可以产生从随机点开始扩散的消融效果
- 片元裁剪:利用Clip函数裁剪消融片元
基本流程:定义一个阈值(DissolveThreshold)范围在[0,1],对噪声图进行纹理采样,将采样结果与阈值进行比较,如果大于阈值则正常显示,如果小于阈值则裁剪当前片元。当阈值从0递增到1时,消融范围逐步扩大实现逐渐消逝效果。当阈值从1递减到0时,消融范围逐步减少实现逐渐显形效果。
普通消融效果
Shader"MyShader/NormalDissolve"
{
Properties
{
_Diffuse("Diffuse Color",Color) = (1,1,1,1) //主颜色
_MainTex("Main Tex",2D) = "white"{
} //主纹理
_DissolveMap("Dissolve Map",2D) = "white"{
} //消融噪声
_DissolveThreshold("Dissolve Threshold",Range(0.0,1.0)) = 0.0 //阈值
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"Queue" = "Geometry"
}
//主Pass负责消融效果
Pass
{
Tags{
"LightMode"="ForwardBase"}
//关闭背面剔除同时渲染模型正面与背面(避免消融裸露模型内部)
Cull Off
CGPROGRAM
#include"Lighting.cginc"
#include"AutoLight.cginc"
#pragma multi_compile_fwdbase
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _DissolveMap;
float4 _DissolveMap_ST;
float _DissolveThreshold;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uvMainTex : TEXCOORD0;
float2 uvMapTex : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uvMainTex = TRANSFOR