2012-06-06 85 views
1

我試圖在「霧中創建洞」效果。我有一個背景網格圖像,疊加到我有一個「霧」紋理,我用它來顯示某些區域不在視野內。我正試圖從「霧」中剪下一塊,以顯示當前正在查看的區域。我試圖「屏蔽」屏幕上的一部分霧。使用半透明紋理「掩蓋」出背景的一部分

我做了一些圖像,以幫助解釋我是什麼後:
背景:

BG

「掩模圖像」(全透明必須是在裏面,而不是爲了外緣什麼我將用它來):

Mask

霧(對不起,很難看到..幾乎透明):

Fog

我想,作爲最終產品是什麼:

Final Product

我曾嘗試:

  • 模板緩衝液:我這只是一個事實完全工作..我無法弄清楚如何保留「蒙版」圖像的褪色透明度。我試過很多不同版本的參數和許多其他方法(glColorMask,glBlendEquation,glBlendFuncSeparate)我開始使用我在這個網站上找到的一些參數:here。我使用了「glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_ALPHA);」因爲這似乎是我在尋找的東西,但是......結果發生了這樣的結果:(很難說這裏發生了什麼,但是......背景中有霧覆蓋網格。面膜是剛剛結束了作爲一個完全不透明的黑色斑點時,其應該是在霧中的透明部分
    Result of glBlendFunc

以前的一些代碼:

glEnable(GL_BLEND); // This is not really called here... It is called on the init function of the program as it is needed all the way through the rendering cycle. 
renderFogTexture(delta, 0.55f); // This renders the fog texture over the background the 0.55f is the transparency of the image. 
glBlendFunc(GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA); // This is the one I tried from one of the many website I have been to today. 
renderFogCircles(delta); // This just draws one (or more) of the mask images to remove the fog in key places. 

(我會發布更多的代碼但是在我嘗試了很多東西之後,我開始刪除一些舊代碼,因爲它變得非常混亂(我在塊註釋中將其備份)

回答

1

這是可行的,只要你沒有對幀緩衝區當前的alpha做任何事情。

步驟1:確保幀緩衝區的alpha值清零爲。所以你的glClearColor調用需要將alpha設置爲零。然後像平常一樣調用glClear。

第2步:繪製掩模圖像之前你畫「霧」。正如蒂姆所說,一旦你和你的霧混合在一起,你就無法撤消它。所以你首先需要掩模數據。

但是,您還需要專門渲染蒙版。您只需要希望掩碼修改幀緩衝區的alpha。你不想讓它混淆RGB顏色。要做到這一點,請使用此功能:glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)。這將關閉寫入顏色的RGB部分;因此,只有alpha會被修改。

你的面具紋理似乎有零,它是可見的,一個它不是。然而,該算法需要相反的,所以你應該修復你的紋理或使用glTexEnv模式,這將有效地翻轉阿爾法。

經過這一步後,你的framebuffer應該有一個我們想要看到霧的alpha值,而alpha值是1,而我們沒有。

此外,不要忘記撤銷掩模渲染後調用glColorMask。你需要重新獲得這些顏色。

第3步:渲染霧。這很簡單,爲了進行掩蔽工作,您需要一種特殊的混合模式。像這樣:

glEnable(GL_BLEND); 
glBlendEquation(GL_FUNC_ADD); 
glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_ONE); 

RGB和A混合部分之間的分隔很重要。你不想改變 framebuffer的阿爾法(以防萬一你想渲染一層以上的霧)。

你完成了。

+0

如果您使用RGB混合方程(ONE_MINUS_DST_ALPHA,DST_ALPHA),並且正如您所說「alpha在我們想要看到霧的地方是0」,則結果顏色將爲((1-0) * fog_rgb + 0 * dst_rgb)。這將使霧完全不透明,不是嗎?在RGB計算中不需要使用霧層的Alpha值嗎? – Tim

+0

雖然我即將對此進行測試,但我相信顛倒面具可能對我無效。 renderFogCircles()渲染多個圓,它們可能重疊也可能不重疊。這會不會以alpha倒置的奇怪圖形問題結束?無論如何...我會盡快測試以確保。 – Zachar543

+0

目前的面具(但白色而不是黑色)似乎能夠產生理想的效果。在上面的面具上反轉alpha似乎給出了完全相反的效果。 (邊框是透明的)儘管如此,仍然存在一些問題......無論我用什麼透明度值,這段代碼都有可能將所有的霧都變成不透明的白色。 http://img707.imageshack.us/img707/751/screenshot2012060615012.png(我用我在其他地方使用的參數撤消上面的glBlendFunc「glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);」)霧似乎不再與背景。 – Zachar543

1

您目前所採用的方法將不起作用,因爲一旦您在整個屏幕上畫霧,就無法「擦除」它。

如果您使用固定的管道:

您可以使用固定的管道多紋理(glTexEnv)的霧和圓紋理單程結合起來。如果你之前沒有使用過這個函數,那麼這個函數可能會讓你感到困惑,你可能不得不花一些時間來學習這個手冊頁。你會做一些像bind fog到glActiveTexture 0,以及mask到glActiveTexture 1,啓用multitexturing,然後將它們與glTexEnv結合起來。我不記得完全正確的參數。

如果您使用的着色器:

使用多重紋理着色器,你與圓的紋理乘霧α(零出在圈內區域的alpha),然後混合該組合的質地爲背景在一次通過。這可能是一個更概念上更簡單的方法,但不確定是否使用着色器。

我不確定有什麼辦法可以做到這一點,因爲它們都具有自己的alpha值,因此它們在單獨的通道中繪製霧和蒙版時很難將它們組合以獲得正確的顏色結果。

+0

multitexturing是否允許我移動mask實時?它是否允許多個蒙版圖像? – Zachar543

+1

如果你想使用很多的面具,我可能會嘗試渲染所有的面具到一個FBO紋理,然後用它來代替。用任意數量的texcoords來使用多紋理將會很困難。你可以放棄一兩個,但更重要的是我認爲這不是真的可行。 – Tim

+0

@NicolBolas我將我的系統轉換爲將面具預渲染爲FBO。雖然,我似乎有一些問題。 http://img204.imageshack.us/img204/6534/screenshot2012060621210。PNG是在我的屏幕上繪製FBO的結果。 (只有紅色通道和alpha打開)如果我關閉alpha通道,通過「glColorMask」,奇怪的重疊不再存在。然後我留下一張不透明的圖像。雖然,當我打開alpha時,我在上圖中找到了問題。第二個繪製的掩碼似乎覆蓋已經吸入FBO的alpha。混合似乎不起作用 – Zachar543