對(duì)于3D游戲來(lái)說(shuō),有很多絢麗的效果,都是靠shader(著色器)來(lái)實(shí)現(xiàn)的。不過(guò)很多朋友估計(jì)都不會(huì)編寫(xiě)shader,阿趙我自己也只是看了個(gè)入門(mén),明白了它的原理,很多具體的效果都寫(xiě)不出來(lái)的。這次來(lái)介紹一個(gè)Unity3D的第三方shader編輯器:Strumpy。這個(gè)編輯器是完全可視化編輯,使用起來(lái)相對(duì)簡(jiǎn)單一點(diǎn)。
先來(lái)看看我們這次需要做的例子:
我們需要使用Strumpy,編輯出這樣一個(gè)shader:包括了漫反射通道、法線(xiàn)通道、高光通道,以及在模型的邊緣運(yùn)動(dòng)的光效。
很顯然,Unity3D自帶的shader沒(méi)有能直接實(shí)現(xiàn)這樣的功能的,最多也只能使用法線(xiàn)和高光通道而已。
由于這個(gè)例子稍微復(fù)雜,所以我們先來(lái)做一個(gè)更簡(jiǎn)單的例子,來(lái)熟悉一下strumpy的界面和基本操作。首先肯定是要先下載Strumpy插件了。在Asset Store里面有,免費(fèi)下載的。我這里使用的是4.0a版本。
下載完之后導(dǎo)入,會(huì)看到多了一個(gè)選項(xiàng):
選擇之后打開(kāi)了Strumpy的編輯窗口:
Flie的功能很直觀,新建,讀取,保存和導(dǎo)出的功能,我們可以先看看讀取功能
插件自帶了一些已經(jīng)編輯好的范例,有興趣的朋友可以逐個(gè)看看,會(huì)有很大的收益。
然后我們來(lái)正式開(kāi)始做這個(gè)簡(jiǎn)單的例子,我們準(zhǔn)備了一張帶有透明通道的貼圖(拿斬首大刀的阿趙),接下來(lái)我們做一個(gè)shader,把這張貼圖顯示在一個(gè)面片上面,使它實(shí)現(xiàn)漫反射通道和透明通道的顯示。
我們新建一個(gè)著色器編輯:
注意看,新建時(shí),在Settings的標(biāo)簽是紅色的,然后Shader Name也是紅色的,這是提醒我們,每一個(gè)shader必須要先有一個(gè)名稱(chēng),而這個(gè)名稱(chēng)就是以后你在材質(zhì)欄里面選擇的材質(zhì)名稱(chēng)了。比如你可以用“myshader/test”,這樣test材質(zhì)會(huì)出現(xiàn)在myshader下面。
輸入材質(zhì)名詞之后,我們先來(lái)Inputs里面,新建一個(gè)輸入。這個(gè)輸入,就是我們平常在Unity自帶的材質(zhì)球里面看到的輸入通道了。假如我們需要它能調(diào)節(jié)顏色,那么就要新建一個(gè)顏色的輸入,假如需要調(diào)用貼圖,就要新建一個(gè)貼圖的輸入。這里我們新建一個(gè)Unity預(yù)設(shè)的MainTexture。熟悉用腳本替換材質(zhì)貼圖的朋友估計(jì)很熟悉這個(gè)標(biāo)簽的含義了。
新建之后,我們可以看到,出現(xiàn)了一個(gè)貼圖選擇的通道,就像我們平常操作的自帶材質(zhì)球一樣。
接下來(lái)我們會(huì)新建一些節(jié)點(diǎn),然后對(duì)他們進(jìn)行編輯。
創(chuàng)建節(jié)點(diǎn)的方式有兩種:
第一種是在Nodes里面選擇相應(yīng)的節(jié)點(diǎn):
第二種是在節(jié)點(diǎn)編輯的窗口鼠標(biāo)右鍵單擊,選擇相應(yīng)的節(jié)點(diǎn)。
我個(gè)人比較習(xí)慣第二種方法。
我們選擇了一個(gè)Sampler2D的輸入
剛生成的時(shí)候,這個(gè)節(jié)點(diǎn)是紅色的,因?yàn)槲覀儧](méi)有指定輸入的來(lái)源。想起剛才我們新建的Input了吧?那個(gè)MainTexture指定在這里。
在選中該節(jié)點(diǎn)的情況下,來(lái)到Node的標(biāo)簽,會(huì)看到提示錯(cuò)誤了
我們選擇_MainTex
這時(shí)候,節(jié)點(diǎn)就不再是紅色了,而是出現(xiàn)了兩項(xiàng)輸出,分別是2D采樣和UV信息。節(jié)點(diǎn)名稱(chēng)里面,也會(huì)相應(yīng)的顯示出_MainTex,也就是我們剛才新建的Input的名稱(chēng)。
接下來(lái)我們新建一個(gè)Tex2D方法節(jié)點(diǎn)。
然后像上圖一樣,用鼠標(biāo)把他們之間連起來(lái)。
這時(shí)候,把我們預(yù)先準(zhǔn)備好的貼圖指定在貼圖通道里面
點(diǎn)擊預(yù)覽窗口的Update Preview,會(huì)看到預(yù)覽的物體上面出現(xiàn)了我們的貼圖
為了便于觀察,我們選擇一個(gè)片面模型。這時(shí)候,漫反射通道已經(jīng)完成了,接下來(lái)我們繼續(xù)做透明通道。
如上圖一樣,把A連接到Alpha通道。
然后來(lái)到Settings,按上圖設(shè)置一下。
打開(kāi)背景顯示,會(huì)看到透明通道已經(jīng)生效了。
在完成了以上的小例子之后,我們正式來(lái)解釋一下Strumpy各個(gè)部分的意思吧。
在master里面,分別是各個(gè)通道的最終輸出。
節(jié)點(diǎn)是通過(guò)有方向性的線(xiàn)條來(lái)連接的,分為輸入端和輸出端,上圖是一個(gè)單向輸入輸出的例子。
再來(lái)是一個(gè)運(yùn)算的例子,Add是相加的操作,這里是兩個(gè)輸入端進(jìn)入了相加,然后輸出一個(gè)結(jié)果。
在這里要說(shuō)明一下的是,這些操作很大一部分都是數(shù)學(xué)運(yùn)算的方法,比如加減乘除、sin、cos之類(lèi),各位在學(xué)習(xí)之前最好要先理解他們的意思。比如相加就是互相疊加,兩張圖相加會(huì)整張圖都變得更亮。相乘是波峰波谷的疊加,兩張圖相乘,會(huì)使亮的地方更亮,暗的地方更暗。其他的方法請(qǐng)各位自行百度去查閱了,就不一一說(shuō)明。
再來(lái)看看設(shè)置的選項(xiàng)
如果曾經(jīng)自己寫(xiě)過(guò)shader的朋友,對(duì)于這些選項(xiàng)應(yīng)該是很熟悉的。比如很多朋友問(wèn)的雙面顯示,其實(shí)就是把CullMode選擇為Off就行。
介紹完基本功能,我們正式的來(lái)做這次的目標(biāo)例子了。
這里我們準(zhǔn)備了一個(gè)模型。
模型帶有了漫反射貼圖和法線(xiàn)貼圖。
首先新建一個(gè)著色器編輯,然后給shader起名為:myShader
按照第一個(gè)例子的操作,我們完成了漫反射通道。
為了應(yīng)用在我們的模型上,我們需要先生成一個(gè)shader。選擇導(dǎo)出(Export As)
給shader起一個(gè)文件名。這個(gè)名稱(chēng)沒(méi)有太大的意義。
導(dǎo)出之后,我們來(lái)到材質(zhì)球選擇的地方,會(huì)看到了我們新建的myShader,選擇它。
然后指定漫反射貼圖,我們的模型變成了上圖的效果。
接下來(lái),我們?cè)贗nputs里面新建一個(gè)凹凸貼圖的輸入
然后完成法線(xiàn)通道節(jié)點(diǎn)的編輯。由于需要使用法線(xiàn)貼圖,所以需要加入一個(gè)UnPackNormal的節(jié)點(diǎn)。
這時(shí)候,我們會(huì)發(fā)現(xiàn)輸入通道處多了Normalmap通道,我們把法線(xiàn)貼圖賦予上去。模型變成上圖的效果。
我們?cè)傩陆ㄒ粋(gè)顏色輸入,作為高光的顏色。
完成高光通道和光澤強(qiáng)度的節(jié)點(diǎn)編輯。
這里我用了一個(gè)Multiply(相乘),目的是讓光澤強(qiáng)度范圍的對(duì)比度更大,顯得高光會(huì)更尖銳一點(diǎn)。高光顏色直接連接到Specular通道。
現(xiàn)在我們的模型已經(jīng)擁有了一定的質(zhì)感了。由于模型原來(lái)是沒(méi)有法線(xiàn)貼圖的,我拿了漫反射貼圖來(lái)直接轉(zhuǎn)換,所以效果差了點(diǎn),有興趣的朋友可以自己做法線(xiàn)貼圖增強(qiáng)效果。
接下來(lái)做有動(dòng)畫(huà)效果的光。
我們新建了幾個(gè)輸入:發(fā)光顏色(_LightColor),一個(gè)發(fā)光顏色的遮罩貼圖(_Light),一個(gè)浮點(diǎn)(_dir)作為光運(yùn)動(dòng)的方向,一個(gè)范圍選擇(_RimPow)作為發(fā)光強(qiáng)度的控制。
這張是發(fā)光遮罩貼圖,是一張黑白的梯度圖。
這一個(gè)步驟的節(jié)點(diǎn)編輯有點(diǎn)復(fù)雜,基本的思路是將顏色和遮罩貼圖混合在一起,并用時(shí)間控制UV動(dòng)畫(huà):
1、遮罩貼圖我用了ViewDirection和Fresnel結(jié)合控制顯示方向,并用_RimPow作為顯示方向的次冪控制顯示強(qiáng)度。
2、為了讓光會(huì)隨著時(shí)間自己做動(dòng)畫(huà),我是用來(lái)Time和_dir相乘,這樣可以控制動(dòng)畫(huà)的速度和方向。
3、為了讓UV移動(dòng)做動(dòng)畫(huà),我用了UV_Pan。記得UV_Pan需要選擇輸入的軸,這里我選擇了Y軸。
4、最后,我把發(fā)光顏色和遮罩運(yùn)算的結(jié)果相乘,達(dá)到疊加波峰改變顏色的目的。
最后,發(fā)布shader,根據(jù)需要選擇相應(yīng)的遮罩貼圖,指定發(fā)光的顏色、強(qiáng)度和方向,我們的例子就完成了。
補(bǔ)充說(shuō)明幾點(diǎn):
1、可能很多功能自帶的shader都有,不過(guò)有時(shí)候你就是會(huì)需要一些功能特殊一點(diǎn)的shader,具體需要什么輸入通道,和怎樣的操作,請(qǐng)根據(jù)實(shí)際情況考慮。
2、關(guān)于即時(shí)鏡面反射的shader,估計(jì)很多朋友都很感興趣。不過(guò)我這里不打算詳細(xì)介紹,因?yàn)閡nity沒(méi)有直接即時(shí)反射運(yùn)算的shader。
簡(jiǎn)單說(shuō)明一下其原理:
在自帶的水面和憤怒機(jī)器人場(chǎng)景里面,我們都看到了類(lèi)似鏡面反射的效果,其實(shí)這都是一種欺騙。做法不算復(fù)雜,其實(shí)是根據(jù)了當(dāng)前攝像機(jī)的位置,新建了一個(gè)相對(duì)角度的反射攝像機(jī),并把反射攝像機(jī)看到的內(nèi)容渲染成RenderTexture。最后把RenderTexture和位置矩陣輸入到普通材質(zhì)的貼圖通道,達(dá)到好像即時(shí)反射的效果。水面的例子做法會(huì)傻一點(diǎn),因?yàn)樗轻槍?duì)水面物體自己生成了一個(gè)反射攝像機(jī),所以的反射效果只會(huì)對(duì)水面本身有效果,每個(gè)可以反射的面,都要單獨(dú)生成。而憤怒機(jī)器人里面的例子會(huì)聰明很多,它會(huì)在攝像機(jī)的腳本里面根據(jù)預(yù)先選擇的可反射的圖層,統(tǒng)一生成了一張RenderTexture,并讓所有可以反射的shader使用。
結(jié)合著即時(shí)反射這個(gè)例子,可以看出實(shí)際上很多特殊的效果,都不是單獨(dú)的shader能直接實(shí)現(xiàn)的,還需要到其他的腳本去配合。