废话不多说进入正题.
下面这张动图是基于硬边做的溶解
下面这张动图是基于软边做的溶解
两者区别是溶解边缘有无过渡
然后再上代码
Shader "Custom/Disslove"
{
Properties
{
_MainTex("MainTex", 2D) = "white" {}
_NoiseTex("NoiseTex", 2D) = "white" {}
_EdgeWidth("EdgeWidth", Range( 0 , 1)) = 0
_Dissolve("Dissolve", Range( 0.0001 , 1)) = 0.1643941
}
SubShader {
Tags {
"IgnoreProjector"="True"
"Queue"="Transparent"
"RenderType"="Transparent"
}
Pass {
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 2.0
uniform sampler2D _NoiseTex;
uniform float _Dissolve;
uniform float _EdgeWidth;
uniform sampler2D _MainTex;
struct VertexInput {
float4 vertex : POSITION;
float2 uv0 : TEXCOORD0;
float4 uv1 : TEXCOORD1;
float4 uv2 : TEXCOORD2;
float4 vertexColor : COLOR;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0;
float4 uv1 : TEXCOORD1;
float4 uv2 : TEXCOORD2;
float4 vertexColor : COLOR;
};
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.uv0 = v.uv0;
o.uv1 = v.uv1;
o.uv2 = v.uv2;
o.vertexColor = v.vertexColor;
o.pos = UnityObjectToClipPos( v.vertex );
return o;
}
float4 frag(VertexOutput i) : COLOR {
float4 noiseTex = tex2D( _NoiseTex, i.uv0 );
float4 mainTex = tex2D( _MainTex, i.uv0 );
float radio = saturate((noiseTex.r - _Dissolve)/(_EdgeWidth*_Dissolve));
return fixed4(mainTex.rgb,radio*mainTex.a);
}
ENDCG
}
}
}
千万要记住噪声图要有过渡色, 如果没有过渡色也没办法做出来软边效果.
要点讲解此行技术关键
float radio = saturate((noiseTex.r - _Dissolve)/(_EdgeWidth*_Dissolve));
noiseTex.r就是扫描的当前某个像素点 _Dissolve是溶解度 _EdgeWidth是描边宽度 (默认r,g,b通道值相等)
当前像素值(noiseTex.r)-溶解度(_Dissolve)=可视像素溶解差值
可视像素溶解差值 / _EdgeWidth(描边宽度)=跟描边宽度有关的色差值 溶解是先从接近于0的黑色开始 所以可视像素溶解差值 / _EdgeWidth(描边宽度)得出来效果也是由远及近对应的效果也是从浅到深
乘以_Dissolve是为了防止_EdgeWidth调的很大但是_Dissolve为0时候就开始溶解