2012-03-10 185 views
2

所以我試圖找出在OpenGL中渲染3D模型的最佳方式,其中一些紋理應用於Alpha通道。在OpenGL中渲染具有Alpha的紋理的3D模型

當我啓用了深度緩衝區並開始繪製3D模型中的所有三角形時,如果它在模型中繪製了另一個三角形前面的三角形,它在獲取後三角形時不會渲染它到它。問題在於前三角形具有透明度,並且應該能夠看到它後面的三角形,但後面的三角形仍然不呈現。

禁用深度緩衝區可以消除這個問題,但會產生一個明顯的問題,即如果三角形不透明,那麼如果渲染之後它仍然會在頂部渲染三角形。

例如,我試圖渲染一棵松樹,基本上是一些錐體堆疊在彼此的頂部,有一個透明的基地。下圖顯示了啓用深度緩衝時所產生的問題:

Depth Buffer Enabled

你可以看你怎麼還能看到透明三角形的輪廓。

下圖顯示了深度緩衝區禁用時的樣子。

Depth Buffer Disabled

在這裏你可以看到一些在樹後面的三角形都在樹的其餘部分的前面渲染。

任何想法如何解決這個問題,並正確渲染松樹?

P.S.我正在使用着色器渲染一切。

回答

5

如果您沒有使用任何部分透明度(一切都是0或255),您可以使用 glEnable(GL_ALPHA_TEST) ,這應該對您有所幫助。問題是,如果你先渲染頂錐,它會將整個四邊形存放到z緩衝區(甚至是透明部分),所以下面的下面的分支在被繪製的時候被拒絕。如果Alpha測試未通過alpha測試 (使用glAlphaFunc設置) ,則啓用alpha測試不會將像素寫入z緩衝區。

如果您想要使用部分透明度,則需要從後到前或從下到上對呈現對象的順序進行排序。

您還需要啓用z-buffer。

哎呀,我意識到這些功能我不相信在你使用着色器時工作。在着色器的情況下,如果alpha值接近於零,則要在片段着色器中使用丟棄函數。

if(color.a < 0.01) { 
    discard; 
} else { 
    outcolor = color; 
} 
+3

...或者在片段着色器中使用「丟棄」,如果alpha在任何環境中低於所需的閾值(不支持alpha測試(如ES 2.0或WebGL))。 – Tommy 2012-03-10 02:56:02

+1

當你有着色器時(在桌面OpenGL中)它們可以工作。當你使用[核心OpenGL 3.1或更高版本](http://www.opengl.org/wiki/Core_And_Compatibility_in_Contexts)時,不起作用的是alpha測試。 – 2012-03-10 03:28:07

+0

@Tim所以我嘗試使用放棄,它似乎刪除片段着色器執行的任何顏色更改。但是,它似乎完全不影響深度緩衝區。使用放棄時,我會得到與深度緩衝區已啓用的圖片中顯示的結果相同的結果。 – Jeremy 2012-03-10 03:28:57

-2

我可能是錯的,但是這是因爲當你在3D渲染使用的DirectX的默認設置,你就沒有渲染三角形的背面,當Z爲刪除 - 它吸引過來,從而,與Z上它不再繪製三角形的背面。 即使啓用了Z,也可以顯示三角形的兩側,但我想這可能是它通常啓用的原因..例如速度..

Device->SetRenderState(D3DRS_CULLMODE, Value); 

值可以等於

D3DCULL_NONE - Shows both sides of triangle 
D3DCULL_CW - Culls Front side of triangle 
D3DCULL_CCW - Default state 
0

您需要實現雙通道算法。

第一次只渲染背面,而第二次渲染只渲染正面。

通過這種方式,您不需要對三角形進行排序,但是根據您的幾何體是否凸起,某些工件可能會出現。