Shader实例:溶解效果(Dissolve)

效果:

图左:一道金光闪过,瞬间灰飞烟灭
图右:燃烧效果,先过渡到黄色,然后渐渐过渡到黑色,最后消失殆尽。

这是游戏中常见的效果,各位可以想想自己玩过的游戏。
手头正在玩的,梦三国手游,死亡的时候就是溶解消失。

代码有注释:

Shader "Custom/Dissolve"
 {
    Properties 
    {
        _MainTex("main tex",2D) = ""{}
        _DissolveTex("dissolve tex",2D) = ""{}//溶解纹理,根据这张图的R值(也可以是其它通道的值)来做溶解判断,简单的说就是利用这张图的特征来作为溶解的样式
        _DissolveColor("dissolve color",Color) = (0,0,0,1)//溶解颜色
        _EdgeColor("edge color",Color) = (0,0,0,1)//边缘颜色
        _DissolveSpeed("dissolve speed",Range(0,5)) = 2//溶解速度
        _DissolveFactor1("dissolve factor1",range(0,1)) = 0.7//溶解因子1,大于这个因子就向溶解色过渡
        _DissolveFactor2("dissolve factor2",range(0,1)) = 0.9//溶解因子2,大于这个因子就向边缘色过渡
    }
 
    SubShader 
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
 
            struct appdata_custom
            {
                float4 vertex:POSITION;
                float4 texcoord:TEXCOORD0;
            };
 
            struct v2f
            {
                float4 pos:POSITION;
                float2 uv:TEXCOORD0;
            };
 
            sampler2D _MainTex;
            float4 _MainTex_ST;
 
            sampler2D _DissolveTex;
            float4 _DissolveColor;
            float4 _EdgeColor;
            float _DissolveSpeed;
            float _DissolveFactor1;
            float _DissolveFactor2;
 
            v2f vert(appdata_custom v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                return o;
            }
 
            half4 frag(v2f IN):COLOR
            {
                half4 c = tex2D(_MainTex,IN.uv);
                float dissolve_c_r = tex2D(_DissolveTex,IN.uv).r;
                float factor = saturate(_Time.y*_DissolveSpeed/5);
                if(factor>dissolve_c_r)
                {
                    discard;
                    //clip(-1.0);
                }
 
                float rate = factor / dissolve_c_r;
                if(rate > _DissolveFactor1)
                {
                    //向溶解色过渡
                    c.rgb = lerp(c.rgb,_DissolveColor.rgb,rate);
 
                    if(rate>_DissolveFactor2)
                    {
                        //向边缘色过渡
                        c.rgb = lerp(c.rgb, _EdgeColor.rgb,rate);
                    }
                }
                return c;
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}

clip:如果输入向量中的任何元素小于0,则丢弃当前像素。
discard:丢弃当前像素,功能同clip
lerp:线性插值,eg:lerp(a,b,f),a*(1-f)+b*f,随着f增大,a会越来越趋向于b

CG函数,无需记忆,待用到之时再去查阅即可。

posted @ 2016-05-13 16:08  Joe师傅  阅读(5053)  评论(0编辑  收藏  举报