在開(kāi)發(fā)過(guò)程中,美術(shù)提出了一個(gè)比較酷炫的邊緣發(fā)光的需求,如下:
平時(shí)比較熟悉的兩種邊緣算法:
- Unity Shader官方教程里面的例子:Rim Light色罚,核心算法為
half rim = 1.0 – saturate(dot (normalize(IN.viewDir), IN.worldNormal));
o.Emission = _RimColor.rgb * pow (rim, _RimPower);
IN.viewDir是當(dāng)前視角向量真仲,IN.worldNormal是物體的法線喇颁。dot是計(jì)算視角和法線的點(diǎn)積,等于視角和法線夾角的cos值嚎货。
這種算法的問(wèn)題在于橘霎,在平直的物體上,邊緣光就不見(jiàn)了厂抖。舉例來(lái)說(shuō)茎毁,正方體的每個(gè)面的法線都是一致的,這樣繪制出來(lái)的效果是一個(gè)面一個(gè)顏色忱辅,即體現(xiàn)不出輪廓效果了七蜘。
- 兩次pass,第一次將物體放大只繪制背面墙懂,第二次原來(lái)大小并打開(kāi)深度測(cè)試只繪制正面橡卤,這樣兩次繪制就能把輪廓顯示出來(lái)。
這個(gè)方法能解決上述問(wèn)題损搬,但是離美術(shù)提的需求還差一個(gè)模糊效果碧库。本著“不要重新發(fā)明輪子”的思想,搜羅出一個(gè)不錯(cuò)的插件:Highlighting System巧勤,官方正版要$30 嵌灰,當(dāng)然也可以找到別人分享出來(lái)的,這里就不提供下載了颅悉。我使用的版本是4.1沽瞭。
使用方法:
- 將Highlighting Renderer腳本掛載在相關(guān)Camera上;
- 將Highlighter腳本掛載在需要邊緣發(fā)光的根GameObject上剩瓶;
- 調(diào)用Highlighter的相關(guān)接口來(lái)控制發(fā)光效果:On/Off/Flash...
通過(guò)閱讀代碼驹溃,大概理解了下思路:
- 主要有兩次全屏效果:OnPreRender(), OnRenderImage();
- OnPreRender:
- 將所有掛載Highlighter的物體使用單色Shader進(jìn)行渲染一次
- blur:根據(jù)設(shè)置的邊緣寬度延曙,對(duì)當(dāng)前像素的左上豌鹤、右上、右下枝缔、左下進(jìn)行采樣布疙,取rgb的最大值,并疊加alpha愿卸。
- 多次迭代blur
- 將最終模糊結(jié)果進(jìn)行兩次pass: 放大拐辽,stencil test,結(jié)果只有漸變的邊緣擦酌,保存在RenderTexture中俱诸。
- OnRenderImage:將OnPreRender繪制的RenderTexture與當(dāng)前的RenderTexture混合,得出最終結(jié)果赊舶。
理解的可能有一些偏差睁搭,還望指出~