對一個三維場景中的物體實現描邊特效,可以參考osg范例osgoutline
這個描邊特效使用了模板緩存Stencil來實現,參見源代碼osgFX/Outline.cpp
使用了兩個Pass
第一個Pass繪制第一遍模型,將模型覆蓋的模版區域寫入值1
第二個Pass繪制第二遍模型,並且用線框模式(PolygonMode::LINE)繪制,設置線寬(例如10),可以繪制的條件是在模版值不等於1的地方
這樣由於線寬的緣故,最外側的線框就保留了一半,看起來就是模型的輪廓
以上的實現的描邊效果是可以被遮擋的,就是說如果描邊物體前面有個物體,描邊效果將被遮擋
如果想實現描邊效果不被遮擋(類似於描邊關閉深度檢測),需要修改源代碼
osgFX/Outline.cpp中的119行附近
stencil->setOperation(osg::Stencil::KEEP,osg::Stencil::KEEP,osg::Stencil::REPLACE);
修改為
stencil->setOperation(osg::Stencil::KEEP,osg::Stencil::REPLACE,osg::Stencil::REPLACE);
也就是在深度測試失敗的時候,深度緩存寫入1
osgFX/Outline.cpp中的146行附近,關閉深度測試(源代碼中注釋掉的那一行)
//state->setMode(GL_DEPTH_TEST,Override_Off);
修改為
state->setMode(GL_DEPTH_TEST,Override_Off);
為了應對有些模型的描邊顏色是黑色的問題,需要將setColor中的_material全部設置成需要的描邊色
第二個pass中,cullFace->setMode(BACK)比較靠譜
polyMode->setMode(FRONT,LINE)比較靠譜
有些模型用到了兩個紋理單元,會引起描邊顏色變暗的問題
可以在state->setTextureMode(0,GL_TEXTURE_2D,OFF)之后添加
state->setTextureMode(1,GL_TEXTURE_2D,OFF)