以前做過簡單的rim light勾邊,幾何勾邊,這次又做了后處理的勾邊,工程化的時候,都遇到很多問題,簡單總結一下。
首先是火炬之光勾邊效果,類似輪廓光的實現,簡單的卡通渲染也是通過類似的算法加采樣色階圖實現。
火炬中的勾邊相當於為角色添加內測光的效果,即通過計算標准散射點積運算來確定頂點法線N和光線向量L之間角度的余弦,用以確定頂點或像素接收到多少光線:s=L·N。
算法的優勢就是:
實現比較簡單,通過調整參數就可以開關內測勾邊光的效果。可以使用頂點法線,這樣更省,火炬中就是vertex Shader中處理的。
算法評估:
效果一般,而且勾邊的效果與模型本身的幾何關系密切。某些特殊的幾何效果很差,例如也無法處理片兒的勾邊。
方案簡單,使用的指令數有限
不同物體可以有不同勾邊的粗細,顏色。
與深度排序、半透明繪制等因素無關。
簡單粗暴的法線放大幾何勾邊法:
算法簡單描述:
將模型的頂點沿法線方向外移一定距離得到一個比原模型稍大的模型,繪制時采用剔除正面繪制背面的方式,將模型繪制為邊界顏色,
再按正常方式繪制原來的模型,結果就產生了一定寬度的勾邊,勾邊的寬度可以通過將頂點沿法線外移的距離來控制。
優點:
模型多繪制一遍,消耗較小,簡單粗暴。
缺點:
1、因為與模型表面法線相關,所以對於片兒的邊緣可能會有勾邊錯誤,例如扇子
2、繪制邊緣的pass不能寫深度且需要檢測深度,因此會產生因為渲染順序導致的遮擋問題。
后處理方法:
在場景繪制結束后,使用特定的shader再次繪制需要勾邊的角色一遍到某RenderTarget上,處理此Rendertarget找到模型輪廓邊界,並融合到場景中。
找邊的方法很多,例如可以對這張圖進行邊緣檢測算法(如Sobel)。或者直接對其做高斯模糊,通過alpha的值來找到編輯並且還能方便的融合到背景(暗黑三)
缺點就是:
增加了時空的消耗:
時間上:一次全屏的繪制,需要勾邊的模型多一次繪制。
空間上,需要申請一張全屏大小的RenderTarget。
問題:
第二次繪制模型時是否開啟深度檢測會有兩種不同的效果,均有一些問題:
一、關閉深度檢測:
勾出的邊不會被深度遮擋,因此不管在什么角度,都可以看到完整的模型的勾邊效果:
上圖,模型的邊界不會被石頭擋住
二、開啟深度檢測:
繪制純色模型時會被前置的角色或者模型擋住,因此在勾邊模型與前置模型的交界處會有勾邊。
蜘蛛與草的邊界處會有勾邊效果
繪制純色模型時會被前置的角色或者模型擋住,因此在勾邊模型與前置模型的交界處會有勾邊。
暗黑三中算法類似,例如暗黑中被模型擋住的門的勾邊效果:(為方便查看,勾了粗邊)。
暗黑中被角色遮擋的門的勾邊