2012-07-24 111 views
11

我目前正在做一些關於OpenGL和着色器的研究,但我似乎無法弄清楚在混合使用glBlendMode或在着色器中編寫自己的混合模式之間是否存在任何根本區別。OpenGL混合模式vs着色器混合

什麼是選擇前者還是後者的原因是什麼?是否有任何性能瓶頸,通過選擇其中一個?或者這只是個人喜好的問題?

回答

13

與glBlendFunc傳統的混合不能在着色器進行復制。混合需要在對目標幀緩衝區進行修改之前對其進行採樣,而這在目前的硬件上是無法完成的。

當前,您只能傳遞一種顏色,並且選擇一種有限的混合模式選擇(glBlendFunc/glBlendEquation)之一,在寫入幀緩衝之前,GPU的光柵器將應用這些模式。

+1

這是否意味着着色器不能混合兩個紋理並將混合模式應用於它們並輸出1個新紋理?如果人們在Web上發佈Photoshop混合模式着色器,我覺得有點奇怪。你能否詳細說明一下?謝謝! – polyclick 2012-07-25 08:16:35

+0

不,您仍然可以在着色器中混合兩種紋理,但這不是混合。混合將當前像素與幀緩衝區混合。您仍然可以通過其他方式實現相同的效果(繪製紋理和混合)。 @bartcla – Tim 2012-07-25 15:52:51

+0

好吧,如果我理解正確:通過'glBlendFunc'進行混合與在着色器中混合紋理完全不同。假設我想用「乘法」混合模式混合兩張照片。這應該在着色器中完成,而不是使用'glBlendFunc'?你能舉一個例子,說明使用'glBlendFunc'嗎? – polyclick 2012-07-26 09:24:29

1

它可以模擬的OpenGL在三種情況下的着色器內混合我所知道的:

  1. 你有Direct3D11或OpenGL相當,綁定渲染目標的讀取寫入紋理在你的像素着色器中。這可以實現任意複雜的混合操作,但在進行簡單混合時性能不高,因爲您繞過GPU的專用硬件進行簡單混合。

  2. 你有一個奇特的「瓦爲本」的GPU,甚至簡單的混合是通過做「阿爾法着色器。」在這種情況下,OpenGL中的簡單混合與等效着色器代碼之間沒有性能差異。但是你不太可能擁有這樣的GPU,而且OpenGL也不會公開這個功能。

  3. 你迴避整個固定功能硬件光柵化管道,並編寫您自己作爲一個複雜的「計算着色器。」如果你能解決這個問題,像「alpha shader」這樣的東西就會成爲你的基於tile的管道的一部分,但是到那時爲止,如此多的工作以至於Alpha混合將成爲你關注的最少部分。

+0

1:更不用說,如果多個着色器調用訪問同一像素,則必須明確同步訪問。 – 2012-07-24 19:13:58

+0

平鋪光柵化的一個很好的方面是,通常像素之間不存在競爭條件的可能性。但是,如果您正在談論的是1,那麼您是對的:在這種情況下,保證三角柵格化將連續完成。 – bmcnett 2012-07-24 22:49:12

6

當着色器從紋理中讀取同時呈現相同紋理的紋理時,結果未定義。這就是爲什麼與glBlendFunc和glBlendEquation混合的「傳統」或固定功能是有用的。

爲了混合使用傳統的混合兩個圖像,則呈現第一圖像,設置混合模式,功能和方程,並呈現第二圖像。這是保證給出正確的結果,並且通常是實現透明度等效果的最快方式。

爲了達到與着色器相同的效果,您需要將第一個圖像渲染到輔助紋理,更改着色器,並將第二個圖像渲染到實際的幀緩衝區,將混合作爲片段着色器中的最後一步。由於紋理讀取的額外開銷,這通常會更慢,並且會爲輔助紋理使用更多的GPU內存。

在現代化的硬件,這兩種技術之間的差異變小。

0

這實際上可以使用gl 3來完成。0擴展使用紋理屏障功能:

http://www.opengl.org/registry/specs/NV/texture_barrier.txt

基本上,你寫的背景後,可以將TextureBarrierNV()函數,以確保紋理像素被刷新,那麼就可以在一個執行讀/寫操作單一着色器階段(確保避免多重採樣緩衝器,因爲實際上只允許一次寫入操作)。