目录
原理
实现
效果
最近项目美术需要使用一个带边缘效果的溶解,就顺便记录分享一下。
美术的需求是,在溶解的基础上,可以有一个边缘,边缘可以调节颜色。
因为是手游项目所以没有考虑使用bloom的后处理去柔和边缘。
1.溶解:
使用一张溶解纹理,并在shader中设置一个阈值。
shader中读取该纹理的alpha值(或者其他任何颜色通道的值也可以),当alpha值大于阈值的时候就在fragment shader中剔除该像素。
最终美术通过修改阈值将看到原来的图片随着溶解纹理逐渐的消失或者出现。
2.边缘:
在溶解的基础上增加一个宽度值。
最终在fragment shader中剔除的像素为溶解纹理中alpha值大于(阈值+宽度)的像素。而阈值到宽度之间的那些像素使用新的颜色(即边缘颜色)来替代,小于阈值的那些像素使用主纹理自身的颜色。
Shader "Custom/Disolve"
{
Properties
{
_MainTex ("主纹理", 2D) = "white" {}
_DisolveTex ("溶解纹理", 2D) = "white" {}
_Degree ("溶解程度", Range(0,1.01)) = 0.5
_Width ("光圈宽度", Range(0,1)) = 0.2
_OutCol ("光圈颜色", Color) = (1,1,1,1)
}
SubShader
{
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _DisolveTex;
float _Degree;
float _Width;
fixed4 _OutCol;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed4 disCol = tex2D(_DisolveTex, i.uv);
// 溶解纹理透明度小于阈值取主纹理颜色否则取边缘颜色
col.rgb = lerp(col.rgb, _OutCol.rgb, step(disCol.a, _Degree));
// 剔除大于(阈值+宽度的像素)
clip(disCol.a - _Degree + _Width);
return col;
}
ENDCG
}
}
}
这个代码实现没啥好说的,主要是加注释的两行分别实现了溶解和边缘。。。
这里没有好的素材就随便弄了一个。。。
这个带边缘的溶解效果肯定是不如加了bloom处理的泛光边缘溶解,但是性能开销的话也会小很多,毕竟没有做后处理,也没有搞模糊运算。
最终要出的效果好还是主要依赖于美术溶解纹理的制作。