《Shader 入門精要》之消融效果

其實這個也是 《Shader 入門精要里面的》,我單獨把里面的消融部分提出來再看,其實思路就比較簡單了。
先提取噪聲圖的紅色通道和我們設定的控制參數(shù)相減,然后 clip,就可以實現(xiàn)下面的效果了。

消融1
Shader "ZhangQr/Dissolve"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _BurnTex("Burn Texture",2D) = "white" {}
        _BurnLevel("Burn Level", Range(0,1)) = 1
        _Length("Length",Range(0,1)) = 0
        _BurnColor1("BurnColor1",Color) = (1,1,1)
        _BurnColor2("BurnColor2",Color) = (1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Cull Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog

            #include "UnityCG.cginc"


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

            struct v2f
            {
                float2 uv : TEXCOORD0; // xy 存儲主紋理,zw 存儲燃燒貼圖紋理
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BurnTex;
            float _BurnLevel;
            float _Length;
            fixed3 _BurnColor1;
            fixed3 _BurnColor2;

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

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 burn = tex2D(_BurnTex,i.uv.xy);
                clip(burn.r - _BurnLevel); // 被 clip 之后,留下的都是大于 0 的值,并且離消融中心越近的值越小,_Length 就是比較的這個
                fixed4 col = tex2D(_MainTex, i.uv);[圖片上傳失敗...(image-d7fada-1608271082911)]

                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

剩下來的 burn.r - _BurnLevel 其實是一個 [0-1] 的值了,并且離燃燒邊緣越近,值就越小,那我們可以通過這個值來混合邊緣和主帖圖。

消融2
Shader "ZhangQr/Dissolve"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _BurnTex("Burn Texture",2D) = "white" {}
        _BurnLevel("Burn Level", Range(0,1)) = 1
        _Length("Length",Range(0,1)) = 0
        _BurnColor1("BurnColor1",Color) = (1,1,1)
        _BurnColor2("BurnColor2",Color) = (1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Cull Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog

            #include "UnityCG.cginc"


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

            struct v2f
            {
                float4 uv : TEXCOORD0; // xy 存儲主紋理,zw 存儲燃燒貼圖紋理
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BurnTex;
            float4 _BurnTex_ST;
            float _BurnLevel;
            float _Length;
            fixed3 _BurnColor1;
            fixed3 _BurnColor2;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv.zw = TRANSFORM_TEX(v.uv, _BurnTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 burn = tex2D(_BurnTex,i.uv.zw);
                clip(burn.r - _BurnLevel); // 被 clip 之后,留下的都是大于 0 的值,并且離消融中心越近的值越小,_Length 就是比較的這個
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                fixed3 gradient = smoothstep(0,_Length,burn.r - _BurnLevel);
                fixed3 finalColor = lerp(_BurnColor1,col,gradient);
                UNITY_APPLY_FOG(i.fogCoord, col);
                return fixed4(finalColor,1);
            }
            ENDCG
        }
    }
}

如果上面就是想要的效果,那么就可以結束了,下面使用 pow 來讓燒焦的效果更真實。

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 burn = tex2D(_BurnTex,i.uv.zw);
                clip(burn.r - _BurnLevel); // 被 clip 之后,留下的都是大于 0 的值,并且離消融中心越近的值越小,_Length 就是比較的這個
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                fixed3 gradient = smoothstep(0,_Length,burn.r - _BurnLevel);
                fixed3 finalColor = lerp(_BurnColor1,_BurnColor2,gradient);
                finalColor = pow(finalColor,5); // 讓燒焦的效果更真實
                UNITY_APPLY_FOG(i.fogCoord, col);
                return fixed4(finalColor,1);
            }
加了 pow

沒加 pow

現(xiàn)在是兩種燒焦的顏色,下面要在燒焦邊緣以外的地方讓物體原本的顏色顯現(xiàn)出來??梢岳斫鉃橐还彩欠譃槿龑?,最里面那層是燒焦顏色1,接著是燒焦的顏色2,最外面是物體原本的顏色。_Length 是用來控制最里面那一層和中間那層的分界線,那需要再加一個 _Length2 來區(qū)分中間那一層和最外面那一層。

燒焦

可以看到最里面是黃色,然后是紅黑的,最后是木紋的顏色。代碼如下:

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 burn = tex2D(_BurnTex,i.uv.zw);
                clip(burn.r - _BurnLevel); // 被 clip 之后,留下的都是大于 0 的值,并且離消融中心越近的值越小,_Length 就是比較的這個
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                fixed3 gradient = smoothstep(0,_Length,burn.r - _BurnLevel);
                fixed3 burnColor = lerp(_BurnColor1,_BurnColor2,gradient);
                burnColor = pow(burnColor,5);
                //fixed3 gradient2 = _BurnLevel == 0 ? 1 : smoothstep(0,_Length2,burn.r - _BurnLevel); // 在 _BurnLevel == 0  的時候會有一點中間的顏色
               fixed3 gradient2 = step(0.0001,_BurnLevel) * (1-smoothstep(0,_Length2,burn.r - _BurnLevel)); // 在 _BurnLevel == 0  的時候會有一點中間的顏色
                burnColor = lerp(col,burnColor,gradient2);
                UNITY_APPLY_FOG(i.fogCoord, col);
                return fixed4(burnColor,1);
            }

如果上面不對 _BurnLevel 單獨判 0 的話,會出現(xiàn)下面這種情況:


_BurnLevel = 0
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容