我認爲這裏有兩個可能的問題。
請記住,所有覆蓋線都在這裏混合兩次。一旦混合到FBO紋理中,並再次在場景中混合FBO紋理時。
因此,第一種可能性是,在FBO覆蓋圖中繪製一條線時不啓用混合。當您在混合關閉的情況下繪製RGBA曲面時,當前alpha將直接寫入FBO疊加層的Alpha通道。之後,當您將FBO的整個紋理融合到場景中時,該alpha會讓您的線條變得透明。因此,如果您對「世界」進行混合但不在疊加元素之間進行混合,則可能不會發生混合。
另一個相關問題:當您在FBO中以「標準」混合模式(src alpha,1 - src alpha)將另一條線疊加到另一條線上時,「混合」部分的Alpha通道將包含混合這兩個覆蓋元素的alpha。這可能不是你想要的。例如,如果您在覆蓋圖中相互繪製兩條50%alpha線,爲了在FBO blit時獲得等同效果,您需要FBO的alpha值爲... 75%。 (也就是1 - (1-.5)*(1-0.5),如果你在場景中畫了兩條50%的alpha線,會發生什麼,但是當你畫出兩條50%的線時,在FBO中獲得50%alpha(50%與... 50%的混合)
這帶來了最後一個問題:在將它們融合到世界之前,通過預先混合線條,改變繪製順序。而你可能有:
混合(混合(混合(背景色,模型),第一行),第二行);
現在你將有
混合(混合(第一行,第二行),混合(背景顏色,型號))。
換句話說,將疊加線預先混合到FBO中會改變混合的順序,從而以您不想要的方式改變最終外觀。
首先,解決這個問題的簡單方法是:不要使用FBO。我意識到這是一個「重新設計你的應用程序」的答案,但使用FBO並不是最便宜的,現代GL卡在繪製線條方面非常出色。因此,一種選擇是:將線條混合到FBO中,而不是將線條几何體寫入頂點緩衝區對象(VBO)。每次簡單擴展一下VBO。如果你一次畫的線數少於40,000行,那麼這幾乎肯定會像以前那樣快。
(一個提示,如果你走這條路線:使用glBufferSubData來寫入行,而不是glMapBuffer - 映射可能是昂貴的,並不適用於許多驅動程序的子範圍...更好的是讓驅動程序複製幾個新的頂點)
如果這不是一個選項(例如,如果您繪製混合的形狀類型或混合使用GL狀態,以便「記住」您所做的更復雜不僅僅是積累頂點),那麼你可能想要改變你如何繪製到VBO。
基本上你需要做的是啓用單獨的混合;將疊加層初始化爲黑色+ 0%alpha(0,0,0,0),並通過「標準混合」RGB進行混合,但對alpha通道進行疊加混合。這對alpha通道來說仍然不太正確,但它通常更接近 - 沒有這個,過度繪製的區域將會過於透明。
然後,在繪製FBO時,使用「預先倍增」的alpha,即(one,one-minus-src-alph)。
這就是爲什麼需要最後一步:當您繪製到FBO中時,您已經將每個繪製調用乘以其Alpha通道(如果混合處於打開狀態)。由於您正在繪製黑色,因此綠色(0,1,0,0.5)線現在變爲深綠色(0,0.5,0,0.5)。如果alpha處於打開狀態並且您再次正常混合,則重新應用alpha並且您將具有0,0.25,0,0.5。)。通過簡單地使用FBO顏色,可以避免第二個alpha乘法。
這有時稱爲「預先倍增」alpha,因爲alpha已經被乘以RGB顏色。在這種情況下,你希望它得到正確的結果,但在其他情況下,程序員使用它來提高速度。 (通過預倍增,當執行混合操作時,它消除了每個像素的多個像素)。
希望有幫助!當圖層沒有按順序混合時,正確混合就變得非常棘手,單獨的混合在舊硬件上不可用,因此每次簡單地繪製線條可能是最不痛苦的道路。
混合應該適用於framebuffer中的任何內容。 (這是什麼混合_does_)。提供更多的數據(你使用什麼混合模式,你稱之爲混合「不正確」?) – Bahbar 2010-01-31 10:10:45
我已經更新了更多的信息,感謝您的快速回復 – staticfloat 2010-01-31 20:28:26