Unity Shader Graph – Distance Dissolve Target

前言

先前我們有做過Dissolve的練習,但是沒有利用語法控制Dissolve的效果只能夠利用動畫的指示做比較單調的融解,這次的練習利用Shader graph以及C#語法的配合,可以利用物件控制溶解的效果以及位置、高度甚至依照材質變化,這種方式不僅僅只是用到遊戲上面做出酷炫的效果,更可以在未來展場或是其他應用上做些改變讓場景更加有趣。

點我下載 Shader Grpah

  1. 一開始的時候當然就是先建立Shader graph了,因為這次會用到AlphaClipThreshold通道,所以我們選擇PBR Shader,這個Shader graph 也是可以在HDRP環境下運作所以可以安心服用,我們可以先給他一個Color屬性當作Albedo顏色代表,而這邊也可以依照之後的材質去做更改。

2. 因為Dissolve已經有做過了,所以一定不陌生Simple Noise Node是最容易上手的溶解形狀,一樣因為我們希望可以控制Scale 所以建立一個Vector1屬性來控制。

接著將noise串到Add的A通道,B通道則是要接受Distance的資訊。

3. Distance mask的部分主要是我們要做溶解的效果Node群組,首先最重要的Position node先建立,接著連接到Distance A通道,因為到時候我們要可以控制Distance的 X、Y 、 Z資訊,所以建立一個Vector 3 屬性並命名為Position以便日後控制,接著就將Distance Node的輸出串到Divide Node做劃分,這邊我們溪Distance的屬性是可以控制的,所以給他一個Vector1 屬性當作Distance控制用,接著串接到Clmap的in 通道並將out通道串到one minus Node的 in ,最後我們將整個 Distance mask的資訊與剛剛的Dissolve mask 的Add 做串連,這樣就完成了第一部分的溶解效果。

4. 在來就是我們溶解的時候有Border邊邊的光暈現象,所以來製作Emission Border的Node吧。首先我們先建立一個Clamp 接收 Dissolve mask 的Add 資訊,接著輸出到Remap Node。

這邊因為Remap的主要功能是要改變Border溶解邊邊光暈的size,所以我們先建立一個Vector 1屬性當作控制 Border Size的Node,但是因為Remap的 out Min Max是 Vector 2 的輸入源,所以我們這邊在新增一個Vector 2 Node 當作媒介,將剛剛建立好的Vector1 串到Vector 2 並將Vector 2 的 Y值設定為1 ,這樣串起來就可以正常調整了。

Remap Node處理好以後在串到一個Clamp 的 in 輸入源,接著將此Clamp Node Multiply起,這邊我們希望可以調整Emission 的顏色,因為 Emission 是要發光的,所以記得建立Color屬性的時候要設定為HDR,設定好以後拉進去Multiply 並餵給Emission。

串接好以後Save asset ,我們回到scene看一下, 值接調整Distance的數值就可以很直覺的看到溶解的效果,但是這跟我們之前做的 Dissolve shader grpah 並無兩樣,所以讓我們用C# 語法做點魔術吧。

5. 首先在Scrip 資料點選右鍵建立一個新的C#語法檔案,這邊可以命名為DistanceDissolveTarget.cs

接著我們在public class DistanceDissolveTarget : MonoBehaviour下寫入語法

public Transform m_objectToTrack = null;

private Material m_materialRef = null;
private Renderer m_renderer = null;


public Renderer Renderer
{
    get
    {
        if (m_renderer == null)
            m_renderer = this.GetComponent<Renderer>();

        return m_renderer;
    }
}

public Material MaterialRef
{
    get
    {

        if(m_materialRef == null)
            m_materialRef = Renderer.material;

        return m_materialRef;
    }
}


private void Awake ()
{
    m_renderer = this.GetComponent<Renderer>();
    m_materialRef = m_renderer.material;

}

private void Update()
{
    if(m_objectToTrack != null)
        {
        Debug.Log(m_objectToTrack.position);
        MaterialRef.SetVector("_Position", m_objectToTrack.position);
    }
}

private void OnDestroy()
{
    m_renderer = null;
    if (m_materialRef != null)
        Destroy(m_materialRef);

    m_materialRef = null;

}

6. 語法儲存好以後我們在已經有上了Dissolve材質的模型上面加上剛剛寫好的語法。

語法加好以後你的Unity可能會報錯,主要是因為他不知道他要Track的物件是哪個。

這邊我隨便建立了一個cube當作Track Object ,並讓語法知道我要Object to track的是此物件(直接將scene裡面的物件拉進去就好了)

這時候有趣的事情發生了,我們將剛剛Track用的物件靠近接收語法的物體看看,就會發現Distance的效果出來了。

首先我先用Distance 設定為1 , 可以看到兩個物件要靠得很近才會出現溶解的效果。

接著我將Distance 改為2 可以看到兩個物件沒有很靠近就出現了溶解效果,而且溶解的幅度很大。

小記

利用語法以及一些Node的串接可以讓 Dissolve 產生千變萬化的效果,當然這次的練習只是簡單的測試效果,如果有其他的想法或是創意的話光是這樣的效果就可以做出非常多有趣的案例了。

參考資料: https://www.youtube.com/watch?v=suXg_5K5BLQ&list=PLX3w–II9wfWba0Ctn3NqI-guyKExbPpR

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *