1.溶解原理
    image.png
    Ramp渐变贴图一张用来实现溶解的基础
    2.smoothstep(限制在0-1区间内)
    image.png
    3.saturate (归一化)
    image.png

    4.实际实现思路过程
    image.png
    4.1-首先先写出溶解边缘效果的渐变贴图,完成他的纹理采样三步骤:定义-声明-采样

    1. _RampTex("渐变效果(RGB)",2D) = "White" {}
    2. sampler2D _RampTex;
    3. fixed4 RampTex = tex2D(_RampTex,i.uv);

    下面是片断着色器代码

    1. fixed4 frag(v2f i):SV_TARGET
    2. {
    3. fixed4 c;
    4. fixed4 tex = tex2D(_Tex,i.uv.xy);
    5. c = tex;
    6. c += _Color;
    7. fixed4 dissolveUV = tex2D(_Dissolve,i.uv.zw);
    8. clip(dissolveUV-_Clip);
    9. fixed4 RampTex = tex2D(_RampTex,i.uv);
    10. c += RampTex;
    11. return c;
    12. }

    image.png
    这样渐变贴图就叠加到了颜色贴图当中

    4.2-在片断着色器中,把RampTex数据中的i.uv替换为dissolveTex的UV数据信息

    1. fixed4 frag(v2f i):SV_TARGET
    2. {
    3. fixed4 c;
    4. fixed4 tex = tex2D(_Tex,i.uv.xy);
    5. c = tex;
    6. c += _Color;
    7. fixed4 dissolveUV = tex2D(_Dissolve,i.uv.zw);
    8. clip(dissolveUV-_Clip);
    9. fixed4 RampTex = tex2D(_RampTex,dissolveUV);
    10. c += RampTex;
    11. return c;
    12. }

    image.pngimage.pngimage.png
    image.png
    也就是说,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区间
    image.png
    那么如果我们把滑块_Clip的值替换为min最小值,那么RampTex得到的UV数据信息就是在_Clip与1之间,clip值越大,所有小于clip值得UV数据会被强制归于Clip的值.
    image.pngimage.pngimage.pngimage.pngimage.png
    clip=0 clip=0.3 clip=0.5 clip=0.6 clip=1
    如果我们不容易理解,可以先把clip那行注释掉,先不让他消失,来看颜色的变化,理解以后再加上clip的裁剪消失的效果,就会出现上图的效果了。
    image.pngimage.pngimage.pngimage.pngimage.png
    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内,最终看到的就是一个(_Clipimage.png效果实现!

    5.代码优化
    因为smoothstep的计算量比较大所以我们可以找到一种新的优化方案:
    image.png
    我们在UnityCG.cginc 中找到他的计算方法,并进行图像化

    image.png
    image.png

    那结果很明显,我们只需要不带平滑的计算就可以实现我们的效果了,只需要选取计算saturate的部分即可。

    1. fixed dissolveValue = saturate((dissolveUV-_Clip)/(_Clip+0.1-_Clip));
    2. fixed4 RampTex = tex2D(_RampTex,dissolveValue);

    image.png要注意这个方法函数的计算过程都是一维向量,数据类型为fixed
    然后下面这张贴图我们在计算和采样时发现,他的V坐标颜色数值都是一样,所以在声明时不需要采用2D贴图 用1D足矣,并不会影响计算过程和最终效果
    image.png
    因此修改代码如下

    1. sampler _RampTex;
    2. fixed4 rampTex = tex1D(_RampTex,dissolveValue);

    6.整体代码展示

    1. Shader "WSP/FrameWork7"
    2. {
    3. Properties
    4. {
    5. [Header(Base Color)]
    6. [Space(10)]
    7. _Color("Color",Color) = (0,0,0,0)
    8. _Tex("MainTex",2D) = "White" {}
    9. [Space(15)]
    10. [Header(Dissolve)]
    11. [Space(10)]
    12. _Dissolve("DissolveTex",2D) = "White" {}
    13. [NoScaleOffset]_RampTex("Ramp(RGB)",2D) = "White" {}
    14. _Clip("Clip",Range(0,1)) = 0
    15. }
    16. SubShader
    17. {
    18. pass
    19. {
    20. CGPROGRAM
    21. #pragma vertex vert
    22. #pragma fragment frag
    23. #include "UnityCG.cginc"
    24. sampler2D _Tex;
    25. fixed4 _Color;
    26. sampler2D _Dissolve;float4 _Dissolve_ST;
    27. fixed _Clip;
    28. sampler _RampTex;
    29. struct appdata
    30. {
    31. float4 vertex :POSITION;
    32. float4 uv :TEXCOORD;
    33. };
    34. struct v2f
    35. {
    36. float4 pos :POSITION;
    37. float4 uv :TEXCOORD;
    38. };
    39. v2f vert(appdata v)
    40. {
    41. v2f o;
    42. o.pos = UnityObjectToClipPos(v.vertex);
    43. o.uv.xy = v.uv.xy;
    44. //o.uv.zw = v.uv *_Dissolve_ST.xy+_Dissolve_ST.zw;
    45. o.uv.zw = TRANSFORM_TEX(v.uv,_Dissolve);
    46. return o;
    47. }
    48. fixed4 frag(v2f i):SV_TARGET
    49. {
    50. fixed4 c;
    51. fixed4 tex = tex2D(_Tex,i.uv.xy);
    52. c = tex;
    53. c += _Color;
    54. fixed4 dissolveUV = tex2D(_Dissolve,i.uv.zw);
    55. clip(dissolveUV-_Clip);
    56. fixed dissolveValue = saturate((dissolveUV-_Clip)/(_Clip+0.1-_Clip));
    57. fixed4 rampTex = tex1D(_RampTex,dissolveValue);
    58. c += rampTex;
    59. return c;
    60. }
    61. ENDCG
    62. }
    63. }
    64. }