(轉)溶解shader


游戲中物體腐化消失,燃燒消失時,會有從局部慢慢消失的效果,然后配合一些粒子特效,就能達到非常好的美術效果。
類似效果如下:


注:
_DissColor為溶解主色,_AddColor為疊加色,按照溶解的移動方向來看開始色為DissColor+AddColor
上圖中DissColor為紅色,AddColor為綠色
所以燃燒時
開始色為DissColor + AddColor = 黃色
默認色為DissColor 紅色
然后配上火的粒子特效,這樣就能模擬比較真實的燃燒效果。
我們也可以設置其他的顏色,比如被各種魔法,化學物品擊中.....算了,不敢想象了,好殘忍

代碼和原理如下:
表面着色器:

Shader "Dissolve/Dissolve_TexturCoords" {  
    Properties {  
        _Color ("主顏色", Color) = (1,1,1,1)                       // 主色  
_MainTex ("模型貼圖", 2D) = "white" {}                      // 主材質  
_DissolveText ("溶解貼圖", 2D) = "white" {}                 // 溶解貼圖  
_Tile("溶解貼圖的平鋪大小", Range (0, 1)) = 1                // 平鋪值,設置溶解貼圖大小  

_Amount ("溶解值", Range (0, 1)) = 0.5                     // 溶解度  
_DissSize("溶解大小", Range (0, 1)) = 0.1                   // 溶解范圍大小  

_DissColor ("溶解主色", Color) = (1,1,1,1)                  // 溶解顏色  
_AddColor ("疊加色,與主色疊加為開始色[R|G|B>0表示啟用]", Color) = (1,1,1,1) // 改色與溶解色融合形成開始色  
}  
SubShader {   
        Tags { "RenderType"="Opaque" }  
        LOD 200  
        Cull off  

        CGPROGRAM  
        #pragma target 3.0  
        #pragma surface surf BlinnPhong  

        sampler2D _MainTex;  
        sampler2D _DissolveText;  
        fixed4 _Color;          // 主色  
half _Tile;             // 平鋪值  
half _Amount;           // 溶解度  
half _DissSize;         // 溶解范圍  
half4 _DissColor;       // 溶解顏色  
half4 _AddColor;        // 疊加色  
// 最終色  
static half3 finalColor = float3(1,1,1);  

        struct Input {  
            float2 uv_MainTex;  // 只需要主材質的UV信息  
};  

void surf (Input IN, inout SurfaceOutput o) {  
            // 對主材質進行采樣  
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);  
            // 設置主材質和顏色  
o.Albedo = tex.rgb * _Color.rgb;  
            // 對裁剪材質進行采樣,取R色值  
float ClipTex = tex2D (_DissolveText, IN.uv_MainTex/_Tile).r;  

            // 裁剪量 = 裁剪材質R - 外部設置量  
float ClipAmount = ClipTex - _Amount;  
            if(_Amount > 0)  
            {  
                // 如果裁剪材質的R色值 < 設置的裁剪值  那么此點將被裁剪  
if(ClipAmount < 0)  
                {  
                    clip(-0.1);  
                }  
                // 然后處理沒有被裁剪的值  
else  
                {  
                    // 針對沒有被裁剪的點,【裁剪量】小於【裁剪大小】的做處理  
// 如果設置了疊加色,那么該色為ClipAmount/_DissSize(這樣會形成漸變效果)  
if(ClipAmount < _DissSize)  
                    {  
                        if(_AddColor.x == 0)  
                            finalColor.x = _DissColor.x;  
                        else  
                            finalColor.x = ClipAmount/_DissSize;  

                        if (_AddColor.y == 0)  
                            finalColor.y = _DissColor.y;  
                        else  
                            finalColor.y = ClipAmount/_DissSize;  

                        if (_AddColor.z == 0)  
                            finalColor.z = _DissColor.z;  
                        else  
                            finalColor.z = ClipAmount/_DissSize;  
                        // 融合  
o.Albedo  = o.Albedo * finalColor * 2;  
                    }  
                }  
            }  
            o.Alpha = tex.a * _Color.a;  
        }  
        ENDCG  
    }//endsubshader  
}


CG:

//溶解
Shader "Dissolve" {
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _DissolorTex ("DissolorTex (RGB)", 2D) = "white" {}
        _RAmount ("RAmount", Range (0, 1)) = 0.5
        
        _DissolorWith("DissolorWith", float) = 0.1//溶解過度寬度
        _DissColor ("DissColor", Color) = (1,1,1,1)//溶解顏色
        _Illuminate ("Illuminate", Range (0, 4)) = 1
    }
    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Pass 
        {
        CGPROGRAM
        #include "UnityCG.cginc"
    
            struct appdata 
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float2 texcoord1 : TEXCOORD1;
            };
            struct v2f 
            {
                float4 pos : POSITION;
                half2 texcoord : TEXCOORD0;
                half2 texcoord1 : TEXCOORD1;
            };
            
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _DissolorTex;
            float4 _DissolorTex_ST;
            half _RAmount;
            
            half _DissolorWith;
            half4 _DissColor;
            half _Illuminate;
            
            v2f vert(appdata v) 
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.texcoord1 = TRANSFORM_TEX(v.texcoord1, _DissolorTex);
                return o;
            }

            
            half4 frag(v2f i) :COLOR 
            {
                half4 mainCol = tex2D(_MainTex,i.texcoord);
                half4 DissolorTexCol = tex2D(_DissolorTex,i.texcoord1);
                half clipVauleR = DissolorTexCol.r - _RAmount;
                if(clipVauleR <= 0)
                {
                    if(clipVauleR > -_DissolorWith)
                    {
                        if(_RAmount != 1)
                        {
                            //插值顏色過度
                            float t = clipVauleR / -_DissolorWith;
                            mainCol = lerp(mainCol, _DissColor, t);
                        }
                        else
                        {
                            discard;
                        }
                    }
                    else
                    {
                        discard;
                    }
                    
                }
                
                return mainCol * _Illuminate;
            }
        #pragma vertex vert
        #pragma fragment frag
        
        ENDCG
        }
        
    } 
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM