2012-09-29 67 views
1

我實現了一個簡化的延遲着色(我沒有計算點光源的邊界),其中填充g-buffer後的 我只是使用全屏四元組計算照明。我在第二階段使用 混合(glBlendFunc(GL_ONE,GL_ONE))來處理多個燈光。 然後,glClearColor中的rgb值應設置爲0,以獲得正確的結果。填充緩衝區 glClearColor可以是任何顏色(某些顏色可能只會改變最終圖像中的背景顏色)。 現在我想知道我應該如何在最終圖像中設置背景顏色。要做到這一點 一種方式是填充G-緩衝過程中使用glClearColor(0,0,0),然後使用在片段着色器follwing if語句:延期着色和背景顏色

if((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0)) 
{ 
    fragColor = vec4(1, 0, 0, 1); // here we can set a background color 
} 
else 
{ 
    fragColor = computeLighting(worldPos, normal, diffM, specM, specMS); 
} 

它工作正常,但如果語句可能導致一些性能損失。這是設置 背景顏色的唯一方法嗎?

回答

3

不知道我是否明白問題是什麼,但這裏有一些想法和很多假設。

你在考慮做這樣的事情嗎? :

  • 清除與你想要的背景顏色你gbuffer您瀰漫附件(!Howevery ..你不想用這個值來清除其他材質如法線)
  • 盡顯你gbuffer,什麼都沒有後由幾何圖形覆蓋仍應具有背景顏色(在漫反射附件中)
  • 如果沒有爲片段定義法線,則在最後階段手動編寫硬編碼顏色。

我想你渲染器執行以下操作:

  • 填充gbuffer(漫反射,法線,在FBO深度等與多個附件)
  • 對於渲染全屏四添加劑共混每個光到一個單獨的FBO(光蓄積緩衝區)。
  • 然後,最後您將gbuffer中的漫反射附件與光線累積緩衝區結合起來,將最終結果呈現在屏幕上。

真的沒有理由讓你的着色器負責編寫像這樣的背景顏色。我也會實際渲染背景中的內容,並始終清除0值的gbuffer。我認爲在最後階段將漫反射和光線結合起來可能會出現問題,因此可能會更簡單地採用模板方法進一步解釋。我個人將材質索引存儲在漫反射顏色的Alpha通道中,然後將所有材質屬性上傳到紋理中。

在我的材料中,我有兩個標量(以及更多...):

  • AmbientWeight
  • 輕質

當組合漫緩衝器和光緩衝器(大大簡化):

FinalColor = Diffuse * AmbientWeight + Diffuse * Light * LightWeight 

如果您的背景使用材料0與AmbientWeight = 1和LightWeight = 0時,FinalColor將始終是漫反射緩衝區中的原始值。

許多簡單的延遲渲染只計算最後的結果是這樣的:

FinalColor = Diffuse * Light(片段從光緩衝漫緩衝*片段)

在你的情況,這當然會導致你的背景顏色消失因爲這些碎片將永遠不會被點亮。 (Diffuse * 0始終是結果)您可以在漫反射緩衝區中使用Alpha通道作爲AmbientWeight以獲得一些快速結果。

FinalColor = Diffuse * Diffuse.a + Diffuse * Light 

當涉及到性能:

這真的很難預測。跳過着色器中的最終光照計算可能會給你一些東西,但在你到達這個階段之前,你已經完成了所有的gbuffer讀取和解包。無論着色器如何返回,您最終都會通過混合操作影響整個光緩衝區,並且每光讀取整個gbuffer。檢查正常緩衝區中的所有組件是否只會觸發沒有幾何體的區域。當每個燈使用全屏四合一時,您將遇到不少瓶頸。

通過讀取位置緩衝區(或從深度緩衝區重建位置)開始,然後確定您的指示燈是否無法到達碎片並丟棄它,然後再執行其他任何操作都可能有所幫助。對於較小的燈光,您不會最終從每個片段的gbuffer讀取所有內容。這取決於你的gbuffer多麼胖,你渲染的是什麼,你的燈光有多大以及你渲染多少燈光。

動態分支也可能會導致性能下降,但有時可能是「較小的惡意」。我儘可能避免它。

附加:

當涉及到「背景顏色」我個人使用模板緩存,以填補了天空盒或類似的背景。在編寫漫反射緩衝區時創建模板遮罩,當使用逆遮罩渲染背景時,只有背景碎片受到影響(沒有深度測試或深度寫入)。如果我的整個場景被幾何體所覆蓋,則不會有任何片段被寫入。這假設您將最終結果寫入第三個使用與gbuffer相同深度附件的FBO。 (Depth24 + Stencil8緩衝區)

您也可以使用帶光信息的UBO發送陣列,而不是使用全屏四元組(使用混合)繪製每個燈光。然後用一個全屏四邊形繪製所有點光源。你最終做同樣數量的光計算,但讀寫量總是不變的。(UBOs仍然有大小限制雖然)

你也可以找到自己感興趣的瓷磚Deferreed底紋作爲一個潛在的下一個步驟: http://www.cse.chalmers.se/~olaolss/main_frame.php?contents=publication&id=tiled_shading (你只能從gbuffer讀一次,並只寫一個片段的通光)

紙:http://www.cse.chalmers.se/~uffe/tiled_shading_preprint.pdf