Shader Graph簡介
? 使用著色器(shader)和材質(zhì)(material),我們能夠創(chuàng)造出非常多有趣的效果。除了Unity自帶的shader外,還可以自己編寫shader或使用其他人所編寫的shader。編寫shader通常需要我們了解shader編程語言的語法和相關(guān)特性,總體來說入門難度相對較高,Shader Graph這個工具能夠讓編寫shader的過程更加容易。
? ? ? ? Shader Graph可以讓我們不用寫代碼就創(chuàng)建一些專用的shader。比如你能夠組合不同的紋理,讓它們在片元著色器中移動位置,或者在頂點(diǎn)著色器中改變頂點(diǎn)的位置。在專業(yè)的技術(shù)美術(shù)(technical artist)的手中,shader能夠創(chuàng)造出千變?nèi)f化的視覺效果。
打開已有的Shader Graph
? ? ? ? Shader Graph從名字來看,就是想讓我們用畫圖表的方式來創(chuàng)建shader。我們先來看看Shader Graph打開后的樣子。在下面例子中,有一個Example_Shimmer的shader,它是通過Shader Graph創(chuàng)建的。在工程中直接雙擊這個文件即可打開它。

? ? ? ? ?第一次看到這個界面,腦子會比較糊,沒關(guān)系,我們接下來創(chuàng)建空的Shader Graph窗口來看。
Shader Graph窗口
? ? ? ? 首先,我們在項目窗口中,右鍵新建一個Shader Graph,名字為Shimmer_ShaderGraph,創(chuàng)建好后雙擊打開(我的工程目錄中創(chuàng)建Shader Graph的位置是Assets > CreativeCore_Shaders > ShaderGraphs,渲染管線是URP,因此右鍵選擇Create > Shader? > Universal Render Pipeline > Lit Shader Graph(Unity版本2020.3.43f1c1)):

? ? ? ? 1:Shader Graph工具欄,這里可以保存shader
? ? ? ? 2:Blackboard,黑板,包含了所創(chuàng)建的shader可供外部所使用的屬性。在這里我們可以定義屬性的類型,名字,默認(rèn)值等
? ? ? ? 3:Workspace,工作空間,用于創(chuàng)建shader的node graph的地方
? ? ? ? 4:Main Preview window,主預(yù)覽窗口,可以實(shí)時預(yù)覽當(dāng)前的shader效果
? ? ? ? 5: Graph Inspector window,類似于Unity Editor的Inspector面板,顯示當(dāng)前設(shè)置、屬性和所選擇的node的相關(guān)信息
? ? ? ? 6: Master Stack,主堆棧,定義著色器最終表面外觀的著色器圖的終點(diǎn),一個 Shader 中有且只有一個。它列出了頂點(diǎn)著色器和片段(片元)著色器的主要著色器屬性,并提供插入必要值的終端節(jié)點(diǎn)
? ? ? ? 在Shader Graph窗口中:
? ? ? ? 平移:鼠標(biāo)中間按住后拖動可以實(shí)現(xiàn)平移(或者按住Alt(windows)或Option(Mac))
? ? ? ? 縮放:滾動鼠標(biāo)滾輪
? ? ? ? 聚焦和放大元素:選中元素后按F,按A恢復(fù)
? ? ? ? 了解了基本的Shader Graph窗口后,我們以一個案例來練習(xí)一下。這個練習(xí)目標(biāo)是創(chuàng)建一個自定義的shader,帶有發(fā)光(glowing)、透明(transparent)和微光(shimmer)的效果。
添加程序化貼圖(Procedural map)
? ? ? ? 對于微光(shimmer)的效果,我們使用程序化噪聲貼圖(procedural noise map)來實(shí)現(xiàn)。程序化(Procedural)的意思是紋理是通過方程或算法來創(chuàng)建的,而不是從圖片創(chuàng)建而來。Shader Graph提供了少量可選的程序化噪聲貼圖,每種貼圖會產(chǎn)生像云朵流動效果的貼圖。
? ? ? ? 下面我們來在Shader Graph中添加第一個節(jié)點(diǎn)(node):
? ? ? ? 1. 在Shader Graph的工作空間中按空格鍵打開Create Node菜單(也可以用右鍵選擇Create Node)
? ? ? ? 2. 在搜索框中輸入noise,然后選擇Gradient Noise

? ? ? ? 3. 在工作空間中選擇新建的Gradient Noise,查看結(jié)果
? ? ? ?

讓程序化貼圖動起來
? ? ? ? 回憶一下之前講過的紋理的Offset屬性,它可以改變物體表面從紋理的哪個位置開始映射。前面一小節(jié)生成的貼圖是一個隨機(jī)的噪聲圖,我們可以讓Offset值不停地變化來讓這個圖動起來。
? ? ? ? 正如Tiling和Offset在URP/Lit Shader中是一起出現(xiàn)的一樣,Tiling和Offset在Shader Graph中也是綁定到一個節(jié)點(diǎn)中的。
? ? ? ? 1. 在工作空間中,按空格鍵或右鍵,在彈出的窗口中創(chuàng)建一個Tiling and Offset節(jié)點(diǎn)。這個節(jié)點(diǎn)可以用來調(diào)整noise map的縮放參數(shù)和起始位置
? ? ? ? 2. 拖動Tiling and Offset節(jié)點(diǎn)的output到Gradient Noise Node的input。完成連接后,在Tiling and Offset里的值就會影響到Gradient Noise
? ? ? ? 3. 改變Tiling and Offset節(jié)點(diǎn)上的Offset值,看看實(shí)際的效果。

? ? ? ? ?4. 創(chuàng)建一個Time節(jié)點(diǎn),這個節(jié)點(diǎn)可以讓我們隨著時間變化改變一個值
? ? ? ? 5. 由于我們想要Offset隨著時間變化,因此我們將Time節(jié)點(diǎn)的output和Tiling and Offset節(jié)點(diǎn)的input連接起來,連接后,我們就可以看到noise紋理動起來了

? ? ? ? 注意到Time節(jié)點(diǎn)有幾種選擇,對于Sine/Cosine Time,其效果就是一個來回往復(fù)的效果,正如正弦、余弦函數(shù)是周期函數(shù)的性質(zhì)一樣
? ? ? ? ?6. 最后,我們將Gradient Noise節(jié)點(diǎn)的output連接到Master Stack的Base Color,這樣就能看到這個材質(zhì)所呈現(xiàn)的效果了

? ? ? ? 注意:記得經(jīng)常使用Shader Graph窗口的左上角的 Save Asset保存你的成果?。?!
?添加材質(zhì)的可輸入屬性
? ? ? ? 對于使用你所創(chuàng)建的材質(zhì)的藝術(shù)家或你自己而言,如果我們能夠提供外部可調(diào)的參數(shù)來控制材質(zhì)的效果,比如本例子中,shimmer效果的移動速度,那么這個材質(zhì)會變得更加實(shí)用。要實(shí)現(xiàn)這個功能,我們可以使用input node來設(shè)置材質(zhì)屬性,允許使用者修改最終效果。
? ? ? ? Input node在Blackboard中創(chuàng)建,黑板的標(biāo)題和shader的名字是一樣的。
? ? ? ? 1. 在Blackboard上點(diǎn)擊“+”,選擇Float,創(chuàng)建一個浮點(diǎn)值input node。將其命名為“ScrollSpeed”。使用這個input node,使用者就可以通過輸入一個浮點(diǎn)數(shù)來調(diào)整滾動速度了

? ? ? ? ?2. 拖動剛剛在Blackboard中創(chuàng)建的input node到工作空間中

? ? ? ? ?3. 由于Time節(jié)點(diǎn)并沒有input節(jié)點(diǎn),我們無法直接將ScrollSpeed的輸出和Time節(jié)點(diǎn)輸入連接起來。這里我們用另一種方式來實(shí)現(xiàn)這兩者的結(jié)合,創(chuàng)建一個Multiply節(jié)點(diǎn),它可以用來將兩個值組合到一起,組合的方式是相乘并輸出結(jié)果。

? ? ? ? ? ? ? 提示:還有一種讓Create Node菜單出現(xiàn)的方法,就是拖動ScrollSpeed的output節(jié)點(diǎn)到工作空間的空白處,然后松開鼠標(biāo)左鍵,這時就會出現(xiàn)Create Node菜單。
? ? ? ? 4. 我們將原來Time節(jié)點(diǎn)的output和Tiling And Offset之間的連接,改到ScrollSpeed連接的Multiply節(jié)點(diǎn)上的B輸入上(要刪除原來的連線,可以選擇原來的連線,然后按delete),接下來將Multiply節(jié)點(diǎn)的output和Tiling and Offset的input連接起來。

? ? ? ? ?注意此時,noise貼圖停止運(yùn)動了。這是因?yàn)镾crollSpeed的默認(rèn)值是0,因此Multiply所返回的結(jié)果是0,因此Tiling And Offset節(jié)點(diǎn)中Offset的值固定為0,所以就沒有動的效果了。
? ? ? ? 7. 要修改ScrollSpeed的默認(rèn)值,選中ScrollSpeed,在Graph Inspector中,輸入一個默認(rèn)值。

?貼圖組合
? ? ? ? 前面的幾個小節(jié)中,我們已經(jīng)實(shí)現(xiàn)了一個能夠移動的噪聲貼圖,我們還可以再增加一個造成貼圖,讓這個貼圖移動速度不同,然后疊加組合這兩幅噪聲貼圖的效果來實(shí)現(xiàn)更有趣的效果。
? ? ? ? 首先我們先復(fù)制一份原來的Gradient Noise,Multiply,Tiling And Offset節(jié)點(diǎn)(不用選擇Time或ScrollSpeed)。
? ? ? ? 1. 在工作空間中,拖出一個方框,框住這些節(jié)點(diǎn)(或者通過按住Ctrl后點(diǎn)擊這些節(jié)點(diǎn))
? ? ? ? 2. 選中所有要復(fù)制的節(jié)點(diǎn)后,點(diǎn)擊右鍵,選擇Duplicate,然后復(fù)制這些節(jié)點(diǎn)(也可以用Ctrl+D)

? ? ? ? ?3. 接下來,我們調(diào)節(jié)一下復(fù)制出的噪聲貼圖的移動速度,這里我們要將移動速度變慢。因此我們增加一個Divide節(jié)點(diǎn),用來做除法,將Time的Cosine Time的output連接到Divide節(jié)點(diǎn)的A輸入,然后設(shè)置B輸入為2,表示Time輸出的值除以2.
? ? ? ? ? ? 4. 將Divide節(jié)點(diǎn)的output和Multiply的B節(jié)點(diǎn)連接起來

? ? ? ? 5. 現(xiàn)在我們得到了兩張不同移動速度和方向的噪聲貼圖,為了將它們的效果融合到一起。我們再新建一個Multiply節(jié)點(diǎn),然后將兩個Gradient Noise Map的output連接到Multiply的A,B輸入,然后將Multiply的output連接到Master Stack的Base Color上

使用節(jié)點(diǎn)分組功能
? ? ? ? 當(dāng)Shader Graph中節(jié)點(diǎn)數(shù)量變得龐大時,我們有必要對完成特定功能的節(jié)點(diǎn)進(jìn)行分組管理,以便讓圖看起來更加簡潔。下面我們將所有用來生成Offset值的節(jié)點(diǎn)(不包括Gradient Noise節(jié)點(diǎn))放大一個Group中來維護(hù)。
? ? ? ? 1. 首先選中所有的節(jié)點(diǎn),如下圖

? ? ? ? ?2. 在任意一個選中的節(jié)點(diǎn)上點(diǎn)擊右鍵(注意不是工作空間空白處),點(diǎn)擊Group Selection(或者按Ctrl + G(MAC上按CMD+G) ),然后將Group的名字改為“Changing Offset over Time”

? ? ? ? ?當(dāng)這些節(jié)點(diǎn)被劃分為一個group后,我們可以對它們做整體移動管理,并且從邏輯上看這些節(jié)點(diǎn)的功能一目了然
調(diào)節(jié)紋理的縮放
? ? ? ? 在實(shí)際使用中,我們要讓shader盡可能的有更多的靈活性。當(dāng)前的shader的紋理看起來有些密集,我們可以添加一個input節(jié)點(diǎn)來調(diào)節(jié)紋理的縮放效果。
? ? ? ? 本例子中,我們會增加一個叫GradientScale的浮點(diǎn)類型輸入節(jié)點(diǎn),然后實(shí)現(xiàn)兩個Noise Map有不同縮放比例的效果。具體的過程不再詳細(xì)描述,使用之前的知識已經(jīng)完全足夠了,下面的示例圖是一個參考,大家練習(xí)的時候可以自由發(fā)揮,創(chuàng)造出不同的效果。

?調(diào)整對比度
? ? ? ? 目前為止,我們的shader已經(jīng)越來越有微光的效果了,但效果本身只有黑白兩種對比強(qiáng)烈的顏色,并且也無法修改顏色。
? ? ? ? 要調(diào)整對比度,我們需要使用Remap節(jié)點(diǎn),它可以將0-1范圍的值縮到更窄的范圍內(nèi)。
? ? ? ? 1. 首先在Blackboard中增加一個Vector2 input節(jié)點(diǎn),它只有兩個值。我們?nèi)∶麨镽emapValues,將它拖到工作空間中,并設(shè)置Y為1
? ? ? ? 2. 增加一個Remap節(jié)點(diǎn)到工作空間
? ? ? ? 3. 連接之前作為Base Map input節(jié)點(diǎn)的Multiply節(jié)點(diǎn)的output,到Remap的的In節(jié)點(diǎn)
? ? ? ? 4. 連接RemapValues節(jié)點(diǎn)到Reamp節(jié)點(diǎn)的Out Min Max,這個值指定了Remap節(jié)點(diǎn)所能輸出的值的最小值和最大值,可供外部進(jìn)行調(diào)節(jié)
? ? ? ? 5. 確保Remap節(jié)點(diǎn)的In Min Max的值設(shè)置為了0和1,這個值是用來匹配輸入值In的實(shí)際范圍的。
? ? ? ? 6. 在Graph Inspector中,調(diào)節(jié)一下RemapValues的默認(rèn)值
? ? ? ? 7. 將Remap節(jié)點(diǎn)的output和Master Stack的Base Color進(jìn)行連接,看看實(shí)際效果

?調(diào)整顏色和透明度
? ? ? ? 為了能夠調(diào)整顏色,我們再添加一個Multiply節(jié)點(diǎn),讓當(dāng)前Remap輸出的顏色和一個TintColor的input節(jié)點(diǎn)進(jìn)行疊加,有了之前的基礎(chǔ),這里應(yīng)該很容易能夠完成。

? ? ? ? ?如果要讓顏色看起來更加突出,這里TintColor的Mode可以選擇HDR。

? ? ? ? ?顏色看起來似乎還是不夠突出?我們還可以將Multiply節(jié)點(diǎn)的output連接到Master Stack的Emission節(jié)點(diǎn)上,看看效果

? ? ? ? ?接下來我們來實(shí)現(xiàn)透明效果,在Graph Inspector中,在Graph Settings標(biāo)簽頁上,將Surface改為Transparent,然后將Remap節(jié)點(diǎn)的output和MasterStack的Alpha連接起來

?最后的練習(xí)
? ? ? ? 觀察目前為止我們所創(chuàng)建的Shader的Master Stack,里面還有Metallic和Smoothness這兩個值我們沒有動過,我們可以嘗試添加Input節(jié)點(diǎn)來讓使用者能夠調(diào)節(jié)這兩個值,這個練習(xí)留給大家自己實(shí)現(xiàn)。
? ? ? ? 重要提示:記得點(diǎn)擊Save Asset及時保存你的進(jìn)展
創(chuàng)建一個測試材質(zhì)
? ? ? ? 到這里我們已經(jīng)創(chuàng)建出了一個shader了,要使用這個shader,我們創(chuàng)建一個新的材質(zhì),取名為MyShimmerMaterial,然后將這個材質(zhì)的Shader選擇為我們用Shader Graph創(chuàng)建的shader

? ? ? ? ?我們將其應(yīng)用到場景中的某個模型上,看看實(shí)際效果

?Shader Graph更多的探索
? ? ? ? 上面的練習(xí)我們創(chuàng)建了一個簡單的shader并且應(yīng)用到了材質(zhì)上。Shader Graph還有許多東西值得探索,在具體使用過程中,我們可能會想要了解某一個節(jié)點(diǎn)的詳細(xì)幫助信息。我們可以在Shader Graph中選擇一個節(jié)點(diǎn),右鍵點(diǎn)擊后,選擇Open Documentation選項,Unity會幫助我們打開這個節(jié)點(diǎn)相關(guān)的文檔。
? ? ? ? Unity官方關(guān)于Shader Graph的手冊地址:????? https://docs.unity3d.com/Packages/com.unity.shadergraph@10.7/manual/index.html
? ? ? ? Unity官方的一個制作飄揚(yáng)的旗幟的案例:
https://learn.unity.com/project/make-a-flag-move-with-shadergraph
? ? ? ? Unity資源商店中其他創(chuàng)作者的案例:
????https://assetstore.unity.com/?free=true&q=shader%20graph