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