Unity 使用Shader Graph實現物體溶解效果


前言

啊咧咧,從大學畢業開始,有一段時間沒有更新過博客了,很懷念當初邊學習邊寫博客的時光。今天打開博客網站看着各位大神通過文字來分享自己的技術心得,也手癢了,決定也來一篇!

說完上面的話,感覺自己像是大佬一樣。嘿嘿,然而本篇文章還是一個小白文,就是Shader Graph的入門知識,一個簡單的物體溶解效果,意在幫助新手了解Shader Graph這個工具。效果如下圖,如果你感興趣,可以看看后面的實現方式,然后來試試吧!
在這里插入圖片描述

注:本項目Unity版本為2021.1.12f1c1

一,配置環境

為了使用Shader Graph這個工具,我們首先需要配置一下開發環境,由於目前的Shader Graph一般應用在UrpHdrp的可編程渲染管線模板下,所以我們要在項目中使用Urp或者Hdrp插件,具體的配置方法有下面兩種

第一種:
在我們創建項目時,通過Unity Hub直接創建一個由Unity官方提供的Urp或者Hdrp的模板。

創建方式為打開Unity Hub,然后點擊創建,選擇Urp模板創建即可:
在這里插入圖片描述

第二種:

點擊Unity編輯器導航欄的Window菜單,並在其中找到Package Manager點擊,即可打開資源包管理器面板,我們可以在這里面管理項目中的插件,或者安裝一些Unity官方提供給我們的插件。

在本案例中,我們需要安裝一個名為Universal RP的插件

在這里插入圖片描述
如圖所示,通過搜索Universal RP,可以找到Urp的插件,通過左下角的安裝按鈕可以將其導入到項目中,然后需要對項目的渲染管線進行一系列的配置,具體的配置可以查看之前的文章:

文章鏈接:

二,創建一個Shader Graph文件

完成上面的環境配置后,就可以在project面板右鍵選擇創建,然后選擇Shader,並在其中找到Blank Shader Graph(注意,我使用的是2021.1.12f1c1版本的Unity,更早版本可能沒有這個選項,可以選擇PBR Shader)並點擊創建一個Shader Graph
在這里插入圖片描述
命名為Dissolve,創建完成后,我們可以在編輯器中找到一個與剛剛創建的Shader Graph命名相同的窗口,接下來就可以在這里面實現一些連連看的操作了。

三,通過Shader Graph編寫一個Shader ,實現物體溶解效果

在創建完之后,可以在窗口中看到下面圖片中的一些內容,大概可以分為四個內容區域,我自己也對其進行了一些命名方便大家理解:

在這里插入圖片描述
四個具體區域:

  • 變量添加區域:這個區域就是為我們添加一些輸入變量,就像C#變量的public int i一樣創建一個變量i,然后就可以在Inspecter面板對該變量進行調整
  • 屬性調整區域:這個區域有點類似於Inspecter面板,可以對變量添加區域的一些變量進行數量或者進行調整
  • 節點編輯區:是我們的主要的工作區域,通過創建與連接一個個節點來實現最終的效果
  • 預覽區域:可以實時的看到我們的材質顯示的效果

了解完整個Shader Graph面板的基本結構,就可以開始通過該功能來實現一些效果了,終於來到了正題。

添加ActiveTargets

在屬性調整區域(Graph Inspector)里面選擇Graph Setting中找到Active Empty,初始時我們可以看到上面顯示List is Empty,很明顯,我們需要新建一個,點擊加號添加一個Universal,就可以在下面的內容中調整我們需要的Shader類型屬性:
在這里插入圖片描述
如果你經常為模型調整材質,相信你對這些參數一定不會陌生,如果你不了解也沒有關系,下面列出一些關鍵的參數來幫助你去調整自己的Shader:

  • Material:有四個選項Lit(受光:接受光照影響)、UnLit(不受光照影響,UI元素常常是UnLit)、Sprite litSprite UnLit則多應用於2D場景
  • Workflow:有鏡面(Specular)與金屬度(Metallic
  • SurfaceTransparent(透明)、Opaque(不透明)
  • Alpha Clip:透明通道裁切(小於該值的透明通道歸零)

在創建完Universal后,可以發現在節點編輯區出現了最終的輸出面板

物體溶解效果原理

實現物體的溶解效果,在本項目中是通過修改物體材質的透明度實現的,既物體材質的Alpha通道,但是如何修改才能確保物體准確的溶解呢。

要實現這樣的效果,需要通過一個關鍵的節點來實現該功能:

  • Simple Noise(噪波節點):根據UV生成簡單的噪波,可以利用其隨機的確定物體不同位置的透明度,而且如果仔細觀察噪波圖,會發現透明度高與透明度低的地方是漸變的,而不是截斷的(要理解這一含義,可以從水波的效果來思考,任意相鄰的兩點之間是連續的,而不可能存在橫截面)

為什么噪波的分布是漸變的,可以通過官方文檔看出:

  • 在兩個決定的UV坐標點之間的的噪波強度的計算為插值計算,而不是隨機產生:在這里插入圖片描述

到這里,你可能不太理解,這樣一張噪波圖為什么能做到溶解的效果,如果僅僅通過其來改變物體的透明度,怎么形成變化的溶解呢

其實很簡單,首先我們定義一個從零到一變化的值,然后利用這個值對噪波圖進行處理,高於這個值的區域設置其Alpha為一,而低於這個值的區域則為零,這樣,隨着這個值的不斷增大,直到大於一的時候,物體透明的區域逐漸增大至全部。這一過程就是實現溶解的方式

可以舉這樣的一個例子,白蛇傳中水漫金山,你從一張等高圖中看到的場景是什么樣子的呢,水慢慢的占滿了整個地圖,如何占據的呢,就是根據一條條等高線逐漸的蔓延:
在這里插入圖片描述
類似如圖,噪波圖里面的透明度也會形成一條條這樣的線,在溶解時,透明度小的線先消失,直到最大為1的線消失。

節點介紹

如果你看了上面的介紹,有可能會覺得很麻煩。我要如何修改Alpha呀,這怎么可能去使用一個值來分割出來不同的透明度區域,而且還要歸一或者歸零。

如果你有這些問題哈哈哈,那說明你真的是新手,Shader Graph作為一個專門編輯Shader 的工具,為我們封裝了許多許多的方法來幫助我們開發,在本案例中,會有幾個節點很方便的幫助我們來實現這樣的效果:

  • Time:可以幫助我們生成一個變化的數值
  • Step:本質上是一個bool類型判斷節點,但是返回的是0或1,而且判斷條件也是比較兩個數值的大小
  • Remap:用來重新映射一個區間范圍,比如說將從0到10的數字映射到從0到1
  • add:加法
  • Multiply:乘法

不多廢話了,簡簡單單的一個溶解效果,結果讓我說了這么多廢話

實現

如果你對原理不感興趣,上面全是廢話,下面直接開始效果實現的教程

1,更改Universal選項

前面我們添加了一個Active Targets,但是你會在Fragment(片元着色器)中發現沒有Alpha通道,而我們要對透明通道進行裁切,所以我們需要在Universal中將Alpha Clip中勾選上:在這里插入圖片描述

如上圖,我們在右邊設置完畢后,左邊的Fragment會多出兩個輸入項,一個是Alpha用來控制透明度,而另外一個Alpha Clip Threshold(1)則是我們上文說到的實現截斷功能的輸入。當Alpha小於Alpha Clip Threshold(1)時,則物體會直接透明,若大於該值時,不處理

注意:

  • 如果是不透明物體,不要嘗試將Surface選項更改為Transparent(透明),如果設置為透明,物體會未溶解部分會出現半透明的情況

2,為物體添加材質

首先說明一下如何添加一個輸入:在變量添加區域點擊加號,即可添加一個變量,變量的類型有FloatColorTexture等等

創建一個Texture 輸入變量,拖入到節點編輯區,點擊后可以在屬性調整區添加一張貼圖。並連接一個材質節點Sample Texture 2D節點,連接好后,將該節點的輸出連至Base Color(3),如圖:
在這里插入圖片描述

3,溶解效果的實現

之前說過,溶解效果需要一張噪波圖與一個0到1的變化的數值(通過Time節點的Sine Time產生,同時使用),具體的連線如圖:

在這里插入圖片描述

  • Sine節點本質是一個Sin函數,我們知道sin函數是一個y值為-1到1的一個循環的曲線,x是由UnityTime來決定的,所以會隨着時間變化持續的輸出-1到1在這里插入圖片描述

如果你觀察了預覽區,你就可以發現,預覽小球已經有了溶解的效果,What?這么簡單?僅僅三四個節點,就可以實現一個高級的溶解效果。

這就是Shader Graph的優勢,對於一些比較成熟的效果有着比較高的封裝性,只需要簡單的拖拽就可以完美的實現,但是不夠靈活,對於一些創造性的活動就需要大量的工作

4,為溶解邊緣加高光

完成上一步后,似乎和賣家秀不太一樣呀,好像缺了點什么?

好像是邊緣沒有光呢,沒錯,由於溶解邊緣沒有光,質感下降了許多,通過下面的操作,可以為其添加一些邊緣光:
在這里插入圖片描述
在上面的圖示中,添加了一個Color類型的輸入變量,用來控制邊緣的顏色,而添加的三個節點,在前面有介紹,第一個就是Add按鈕,在溶解的邊緣的透明度的數值加一即為未溶解的邊緣,類似於等高圖,目前溶解到五千米,我加一米,即五千零一米,剛好是溶解的邊緣,接下來通過一個Step節點 判斷需要亮度的范圍(即小於五千零一米的所有區域輸出為1),這樣透明區間到五千零一米之間就會有一圈亮的區域

5,通過腳本調用該效果

實現這樣的溶解效果后,可以作為一個角色死亡時的特效,但是該怎么去實現這楊的功能呢,本案例就提供一個簡單的腳本來應用這樣的效果。

由於角色的死亡是一次事件的觸發,我們使用Sin函數來循環溶解該物體毫無意義,因此我們定義一個float變量輸入作為從顯示到完全溶解的控制變量。
在這里插入圖片描述

通過改變這一變量來控制物體的溶解過程,具體的腳本實現方式為:

	public Material material;
    public void Start()
    {
    	//獲取修改材質溶解度的變量並設置初始值
        id = Shader.PropertyToID("TestNum");
        material.SetFloat(id, 0);        
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(DestroyCube());
        }
    }
    IEnumerator DestroyCube()
    {
        int n = 2000;
        float num = 0;
        Mathf.Sin(Time.time);
        while (n>0)
        {            
            num = Mathf.Lerp(num, 1,0.001f);
            material.SetFloat(id, num);
            n--;
            yield return null;
        }        
    }

編寫上面的腳本,掛載到任一物體上面,並將剛剛創建好的材質拖入即可,這樣就可以實現一個由事件驅動的溶解效果,如圖點擊空格鍵后效果:
在這里插入圖片描述

結束

Shader Graph對於不會編程寫Shader的人很友好,通過簡單的學習就可以實現一些很酷炫的效果,但是相比來說,還是沒有編程實現那樣的靈活。並且效果的性能完全是自己不可控的,取決與Unity官方的性能優化,這樣來講,適配性就低很多。

不過Shaer Graph很明顯的優勢就是可以對於效果原理的理解很形象,能夠更好幫助初級開發者的學習渲染的知識。如果你和我一樣也是一個小白,也嘗試去學習一下吧!


免責聲明!

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



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