


這個效果的制作主要學習了UVMapping的活用。
這個護盾的效果可以主要分為以下幾個模塊:首先在Maya中生成一個柏拉圖多面體,然后在y=0處用多切割把下半球分離出來并舍棄掉,得到使用的模型。使用的材質Shader隊列需要設置為Transparent,并且分兩個Pass(一個Cull Front一個Cull Back),用以正確顯示護盾后和護盾中的物體。兩個Pass都用的同一段代碼,并且模糊效果是直接寫在Shader里對
GrabPass得到的_GrabTexture處理的,因此在護盾內外都可以得到正確的效果。另外,每個面上的點的法線是未經(jīng)過插值的面法線,用之前學習過的ddx和ddy對世界空間的坐標求偏導叉乘得到法線即可。
然后就是接下來詳細分析的動態(tài)色彩/消融/UV扭曲/面描邊/輝光效果。
動態(tài)色彩/UV扭曲
我希望的效果是每個面都有互不相同、能夠變化的顏色,但是我嘗試采用shader內實時計算不僅效果不好,而且未免太大材小用。后來我采用了這種辦法:首先在Maya中將每個面的UV打散,并且放在UV空間的隨機位置,賦予隨機方向。

接下來在shader內使用這個UV加上隨時間變化的量,對如下的圖(Photoshop中中心點一個點然后高斯模糊)進行采樣。

然后,得到的采樣值再去采樣或者計算用戶自定義的Color Ramp即可。由于不同面之間的UV是全部分散毫無關聯(lián)的,因此就可以得到每個面互不相同顏色的效果。
我還增加了一個菲涅爾效果,面法線和視角接近垂直的面采用另一套Color Ramp。
對于表面類似折射扭曲的效果,同樣采用這一套UV加隨時間變化的量對法線貼圖采樣,使用法線的xy對grabPos扭曲即可。同樣的,因為每個面UV殼方向也是隨機的,因此我們能看到效果圖中每個面“流動方向”不同的效果。
消融
這個也算是比較常用的效果,首先用戶自定義一張消融數(shù)值圖,然后采樣這張圖的數(shù)值,如果這個值達不到shader預先規(guī)定的閾值就舍棄這個片元(或直接返回當前點采樣的_GrabTexture)。

這里我輸入的是一個柏林噪聲圖。但是,我們需要讓面與面之間的消融的“洞”或者剩下的“島”具有連續(xù)性,這時我們就不能采用上述的打散的UV了,而是使用直接對未剪開邊的網(wǎng)格unfold后的UV生成另一套UV集。

最后,我們還可以增加一個邊緣尺寸的量輸入shader,消融數(shù)值接近閾值的部分我們增加一個發(fā)光的效果。
另外,上面兩個灰度圖我們還可以放到同一張圖的不同通道里。

面描邊
重心坐標
這里涉及到一個三角形重心坐標系的概念,若重心坐標的某一個值接近0,說明這個值越靠近三角形邊緣。我們知道在fragment shader中是經(jīng)過插值處理的,但是我們還是沒有辦法能夠直接得到當前片元的重心坐標。
不過好在我們還可以讓模型有更多的UV集,只要我們把網(wǎng)格的每個三角面的UV殼頂點放到UV空間的(0,0)(1,0)(1,1)處我們就能輕易在shader中計算得到重心坐標了。
于是我們在Maya的UV編輯器中直接對全部拆開的面使用單位化,最后得到想要的結果儲存為第三套UV集。

在shader中,我們只需要使用如下方式就能得到重心坐標的最小分量:
float uvDist = min(min(i.uv3.y, 1 - i.uv3.x),(i.uv3.x - i.uv3.y)/1.414);
這個值小于預先設定的閾值的話,這個片元就是我們要描邊的片元。
輝光
沒有什么特別要說的,基本和之前寫的物體輝光效果一樣的方法,需要用到腳本處理,甚至沒有用到第二個相機。需要說明的是,在護盾自身的shader中我將發(fā)光處的alpha設為了0,并且在后處理輝光時只提取了alpha通道分量做模糊處理。因此,若是相機中會出現(xiàn)其他半透明/透明的物體時,這個方法就不適用了,那就需要使用另一個相機和更多的腳本工作去得到正確的效果,如果要考慮到還有Alpha Blending的話,情況就更復雜了。