Shader燃烧溶解效果(二)

前面的一篇介绍了最基础的溶解效果
本篇会在第一篇的基础上优化:
(1)添加溶解方向
(2)溶解边缘颜色过度效果
(3)可在此下效果中调试理解_Spread 的作用

在这里插入图片描述

采样Ramp渐变图: Wrap Mode设置为 : Clamp
在这里插入图片描述

代码如下:

Shader "Unlit/Dissolve_Easy_Double"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _Gradient("Gradient",2D) = "white" {
    
    }
        _ChangeAmount("ChangeAmount",Range(0,1)) = 1
        _EdgeColor("EdgeColor已经被弃用,改为从 Ramp图中采样颜色",color) = (0,1,0,1)
        _EdgeWidth("EdgeWidth",Range(0,2)) = 0.2
        _EdgeColorIntensity("EdgeColorIntensity",Range(0,2)) = 1        
        _Spread("Spread溶解边缘的扩散值",Range(0,1)) = 0.3
        
        _Noise("Noise Tex",2D) = "white"{
    
    }
        
        _Ramp("Ramp Tex",2D) = "white"{
    
    }
    }
    SubShader
    {
    
    
        Tags {
    
     "Queue"="AlphaTest" "RenderType"="Opaque" }
        LOD 100

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };
            float _ChangeAmount;
            sampler2D _MainTex,_Gradient;
            float4 _MainTex_ST,_Gradient_ST;

            float4 _EdgeColor;
            float _EdgeWidth,_EdgeColorIntensity;
            float _Spread;
            
            sampler2D _Noise;
            sampler2D _Ramp;

            // 重映射函数
            float remap(float x,float oldmin,float oldMax,float newMin,float newMax)
            {
    
    
                return (x - oldmin)/(oldMax - oldmin) * (newMax-newMin) + newMin;   
            }          


            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv1 = TRANSFORM_TEX(v.uv, _Gradient);
                return o;
            }

            // 思路并不复杂,重要的是思路!!!!!
            //  step,  lerp, smoothStep 组合  0,1 相乘,  然后裁剪屏蔽 只留下白色1,黑色0
            // 这样就能够在特定的位置产生相应的效果
            fixed4 frag (v2f i) : SV_Target
            {
    
    
                fixed4 col = tex2D(_MainTex, i.uv);              
                fixed gradient = tex2D(_Gradient,i.uv1).r;
                float remapData =  remap(_ChangeAmount,0,1.0,-_Spread,1.0);   
                gradient = gradient - remapData;
                //return fixed4((gradient).xxx,1);
                gradient/= _Spread;
                
                //方向控制
                float noise = tex2D(_Noise,i.uv).r;
                // 乘以2 - noise  是为了确保   当 溶解未开始的情况下 保证未溶解   
                gradient = gradient* 2 - noise;      
                      
                      
                      
                      
                        
                
                float dis = saturate(1 - distance(0.5,gradient) / _EdgeWidth);
                
                //  渐变色-----------
                float2 rampUV = float2(1 - dis,0.5 );
                float4 edgeCol = tex2D(_Ramp,rampUV);              
                
                //----------------  
                //return fixed4((dis).xxx,1);                              
                float alpha =  step(0.5,gradient);
                col.a = alpha * col.a;     
                clip( col.a - 0.5);                                
                fixed4 edgeColor = edgeCol * _EdgeColorIntensity;
                col = lerp(col,edgeColor,dis);             
                return col;
            }
            ENDCG
        }
    }
}

(2)球形溶解:

在这里插入图片描述
使用的都是前面讲到过的知识,这里直接上代码
这里说明一下 /1.8 是为了将模型的高度 映射到 (0,1)的范围内,所以 不同的模型需要除以不同的参数变为1.

Shader "Unlit/Dissolve_Easy_Sphere_code"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _ChangeAmount("ChangeAmount",Range(0,1)) = 1
        _EdgeColor("EdgeColor已经被弃用,改为从 Ramp图中采样颜色",color) = (0,1,0,1)
        _EdgeWidth("EdgeWidth",Range(0,2)) = 0.2
        _EdgeColorIntensity("EdgeColorIntensity",Range(0,2)) = 1        
        _Spread("Spread溶解边缘的扩散值",Range(0,1)) = 0.3
        
        _Noise("Noise Tex",2D) = "white"{
    
    }
        
        _Ramp("Ramp Tex",2D) = "white"{
    
    }
        _Softness("Softness",Range(0,0.5)) = 0.3
    }
    SubShader
    {
    
    
        Tags {
    
     "Queue"="Transparent" "RenderType"="Transparent" }
        LOD 100

        Pass
        {
    
    
            cull off
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD2;
            };
            float _ChangeAmount;
            sampler2D _MainTex;
            float4 _MainTex_ST;

            float4 _EdgeColor;
            float _EdgeWidth,_EdgeColorIntensity;
            float _Spread,_Softness;
            
            sampler2D _Noise;
            sampler2D _Ramp;

            // 重映射函数
            float remap(float x,float oldmin,float oldMax,float newMin,float newMax)
            {
    
    
                return (x - oldmin)/(oldMax - oldmin) * (newMax-newMin) + newMin;   
            }          


            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
    
    
                float3 rootPos = mul(unity_ObjectToWorld,float4(-0.5,-0.5,-0.5,1));
                //float3 rootPos = mul(unity_ObjectToWorld,float4(0,0,0,1));
                // 球形溶解
                float gradient = distance(i.worldPos,rootPos) / 1.8;
                // 垂直方向溶解
                //float gradient = i.worldPos.y - rootPos.y;                         
                fixed4 col = tex2D(_MainTex, i.uv);              
                float remapData =  remap(_ChangeAmount,0,1.0,-_Spread,1.0);   
                gradient = gradient - remapData;
                gradient/= _Spread;
                
                //方向控制
                float noise = tex2D(_Noise,i.uv).r;
                // 乘以2 - noise  是为了确保   当 溶解未开始的情况下 保证未溶解   
                gradient = gradient* 2 - noise;                                          
                float dis = saturate(1 - distance(_Softness,gradient) / _EdgeWidth);
                
                //  渐变色-----------
                float2 rampUV = float2(1 - dis,0.5 );
                float4 edgeCol = tex2D(_Ramp,rampUV);              
               
               
               
                float alpha =  smoothstep(_Softness,0.5,gradient);       
                fixed4 edgeColor = edgeCol * _EdgeColorIntensity;
                float3 emission = lerp(col,edgeColor,dis).rgb;
                col.a = alpha * col.a;
                return float4(emission,col.a);
            }
            ENDCG
        }
    }
}

猜你喜欢

转载自blog.csdn.net/js0907/article/details/117197420