zoukankan      html  css  js  c++  java
  • (转)溶解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
            }
            
        } 
        
    }
  • 相关阅读:
    RocketMQ视频
    框架进度
    待做事项
    lombok.Data报错问题
    cannot touch "dev/dir/tomcat/a.txt"
    服务器命令
    小知识汇总----不断更新中...
    消息推送APNS--------借鉴前人经验,自己实践验证
    iOS开发之企业账号最新申请流程
    solr4.3+tomcat入门部署(转自http://qindongliang1922.iteye.com/blog/1893254)
  • 原文地址:https://www.cnblogs.com/wonderKK/p/4418273.html
Copyright © 2011-2022 走看看