1.溶解原理
Ramp渐变贴图一张用来实现溶解的基础
2.smoothstep(限制在0-1区间内)
3.saturate (归一化)
4.实际实现思路过程
4.1-首先先写出溶解边缘效果的渐变贴图,完成他的纹理采样三步骤:定义-声明-采样
_RampTex("渐变效果(RGB)",2D) = "White" {}sampler2D _RampTex;fixed4 RampTex = tex2D(_RampTex,i.uv);
下面是片断着色器代码
fixed4 frag(v2f i):SV_TARGET{fixed4 c;fixed4 tex = tex2D(_Tex,i.uv.xy);c = tex;c += _Color;fixed4 dissolveUV = tex2D(_Dissolve,i.uv.zw);clip(dissolveUV-_Clip);fixed4 RampTex = tex2D(_RampTex,i.uv);c += RampTex;return c;}

这样渐变贴图就叠加到了颜色贴图当中
4.2-在片断着色器中,把RampTex数据中的i.uv替换为dissolveTex的UV数据信息
fixed4 frag(v2f i):SV_TARGET{fixed4 c;fixed4 tex = tex2D(_Tex,i.uv.xy);c = tex;c += _Color;fixed4 dissolveUV = tex2D(_Dissolve,i.uv.zw);clip(dissolveUV-_Clip);fixed4 RampTex = tex2D(_RampTex,dissolveUV);c += RampTex;return c;}



也就是说,RampTex纹理贴图中每一个像素点的UV数据等于dissolveTex中的每一个UV数据信息
(进一步解释一下:我们知道0为黑色,1为白色。那就是说颜色越黑的溶解遮罩贴图数值越小,越偏向与渐变贴图中亮的地方,越白的溶解这招数值越大,越偏向与渐变贴图中暗的地方)
4.3-使用smoothstep语法把数据限制在0-1区间,方便与clip进行计算和判断,从而实现边缘溶解的裁剪效果
fixed4 RampTex = tex2D(_RampTex,smoothstep(0,1,dissolveUV));
假设最小值为0最大值为1,x为溶解遮罩的uv数据,那我们最终得到的RampTex的片断数据会跟之前一样,效果也是一样的因为UV数据被强制限制在0-1区间
那么如果我们把滑块_Clip的值替换为min最小值,那么RampTex得到的UV数据信息就是在_Clip与1之间,clip值越大,所有小于clip值得UV数据会被强制归于Clip的值.




clip=0 clip=0.3 clip=0.5 clip=0.6 clip=1
如果我们不容易理解,可以先把clip那行注释掉,先不让他消失,来看颜色的变化,理解以后再加上clip的裁剪消失的效果,就会出现上图的效果了。




clip=0 clip=0.3 clip=0.5 clip=0.6 clip=1
例如当clip为0.5时,所有小于0.5的UV数据信息都会等于0.5,也就是消失的那部分。因为低于0.5的偏黑颜色都被限制在0.5或以上了,所以可以看到整体颜色画面会向着全白数值1接近的趋势。
4.4-最后由于我们最小值限制以后最大值并没有赋予一个动态的值,它默认是1所有颜色都不会被约束,所以要对RampTex的最大值进行约束。
fixed4 RampTex = tex2D(_RampTex,smoothstep(_Clip,_Clip+0.1,dissolveUV));
所有大于_Clip+0.1的值都会被限制在_Clip+0.1内,最终看到的就是一个(_Clip
效果实现!
5.代码优化
因为smoothstep的计算量比较大所以我们可以找到一种新的优化方案:
我们在UnityCG.cginc 中找到他的计算方法,并进行图像化


那结果很明显,我们只需要不带平滑的计算就可以实现我们的效果了,只需要选取计算saturate的部分即可。
fixed dissolveValue = saturate((dissolveUV-_Clip)/(_Clip+0.1-_Clip));fixed4 RampTex = tex2D(_RampTex,dissolveValue);
要注意这个方法函数的计算过程都是一维向量,数据类型为fixed
然后下面这张贴图我们在计算和采样时发现,他的V坐标颜色数值都是一样,所以在声明时不需要采用2D贴图 用1D足矣,并不会影响计算过程和最终效果
因此修改代码如下
sampler _RampTex;fixed4 rampTex = tex1D(_RampTex,dissolveValue);
6.整体代码展示
Shader "WSP/FrameWork7"{Properties{[Header(Base Color)][Space(10)]_Color("Color",Color) = (0,0,0,0)_Tex("MainTex",2D) = "White" {}[Space(15)][Header(Dissolve)][Space(10)]_Dissolve("DissolveTex",2D) = "White" {}[NoScaleOffset]_RampTex("Ramp(RGB)",2D) = "White" {}_Clip("Clip",Range(0,1)) = 0}SubShader{pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _Tex;fixed4 _Color;sampler2D _Dissolve;float4 _Dissolve_ST;fixed _Clip;sampler _RampTex;struct appdata{float4 vertex :POSITION;float4 uv :TEXCOORD;};struct v2f{float4 pos :POSITION;float4 uv :TEXCOORD;};v2f vert(appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv.xy = v.uv.xy;//o.uv.zw = v.uv *_Dissolve_ST.xy+_Dissolve_ST.zw;o.uv.zw = TRANSFORM_TEX(v.uv,_Dissolve);return o;}fixed4 frag(v2f i):SV_TARGET{fixed4 c;fixed4 tex = tex2D(_Tex,i.uv.xy);c = tex;c += _Color;fixed4 dissolveUV = tex2D(_Dissolve,i.uv.zw);clip(dissolveUV-_Clip);fixed dissolveValue = saturate((dissolveUV-_Clip)/(_Clip+0.1-_Clip));fixed4 rampTex = tex1D(_RampTex,dissolveValue);c += rampTex;return c;}ENDCG}}}
