玩神界原罪2,感觉人物被建筑遮挡时,建筑的“溶解”效果很有意思,想实现一下。然后发现连溶解都没实现过,emmmmm。。。。先来把溶解实现了~
原理就是根据一张噪声图的值是否大于某个阈值,来判断是否丢弃像素值。然后阈值从0到1就可以让物体从有到无了。然后加了一条溶解的过渡带,为了显得不那么突兀。
改变阈值从0到1再从1到0,效果如下:
![]()
代码如下:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/Dissolve" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_DissolveTex("DissolveMap", 2D) = "white"{}//噪声图
_DissolveThreshold("DissolveThreshold", Range(0,1)) = 0
_EdgeWidth("EdgeWidth",Range(0,1))=0.01 //过渡边界的宽度
_EdgeColor("EdgeColor",Color)=(1,0,0,1) //过渡边界的颜色
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler _DissolveTex;
float _DissolveThreshold;
float _EdgeWidth;
float4 _EdgeColor;
struct v2f{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
};
v2f vert(appdata_full i){
v2f o;
o.pos=UnityObjectToClipPos(i.vertex);
o.uv=TRANSFORM_TEX(i.texcoord,_MainTex);
return o;
}
float4 frag(v2f i): SV_Target{
float4 dValue=tex2D(_DissolveTex,i.uv);
float4 outColor=tex2D(_MainTex, i.uv);
if(dValue.r<_DissolveThreshold){//小于阈值的丢弃
discard;
}
float delta=dValue.r-_DissolveThreshold;
float temp=sign( _EdgeWidth-delta);//负数的话表示是超过边界宽度的,正数表示是小于宽度的,sign取符号。
float4 endColor=lerp(outColor,_EdgeColor,saturate(temp));//saturate一下,那么超过宽度的都显示正常的颜色,小于宽度的都显示边界颜色。
return endColor;
}
ENDCG
}
}
FallBack "Diffuse"
}