2013-02-19 72 views
3

我想在opengl中爲我的2D遊戲繪製大量的2D圓圈。他們都是相同的大小,並具有相同的紋理。許多精靈重疊。什麼是最快的方式來做到這一點?性能 - 在opengl中繪製許多2D圓圈

an example of the kind of effect I'm making http://img805.imageshack.us/img805/6379/circles.png

(應當指出的是,黑邊只是由於圈子的擴大爆炸,裏面裝着一會兒這個截屏拍攝後。

目前我我使用了一對帶紋理的三角形來製作每一個圓,我在紋理的邊緣有透明效果,使它看起來像一個圓圈,使用混合來證明這非常緩慢(並且z culling是不可能的,因爲它們是但是我沒有使用混合,而是讓我的片段着色器丟棄了alpha爲0的任何片段。這可以起作用,但這意味着早期的z不是poss ible(作爲碎片被丟棄)。

的速度由大量透支和GPU的填充率限制。圓圈的順序並不重要(假設它在創建閃爍的幀之間不會改變),所以我一直試圖確保屏幕上的每個像素只能寫入一次。

我試圖通過使用深度緩衝區。在每幀開始時,它被清除爲1.0f。然後當繪製圓時,它將深度緩衝區的那部分更改爲0.0f。如果通常會繪製另一個圓圈,則不是新圓圈的z爲0.0f。這不會低於當前深度緩衝區中的0.0f,因此不會被繪製。這是有效的,並且應該減少必須繪製的像素的數量。然而;奇怪的是它並沒有更快。我已經提出了一個關於這種行爲的問題(opengl depth buffer slow when points have same depth),並且建議在使用相等的z值時,z culling沒有被加速。

相反,我必須給所有我的圈子,從0向上分離假z值。然後當我使用glDrawArrays和默認的GL_LESS渲染時,由於z剔除,我們正確地獲得了速度提升(儘管早期的z不可能,因爲碎片被丟棄以使圓圈可能)。然而,這並不理想,因爲我不得不添加大量與z相關的代碼來進行2d遊戲,而這種遊戲根本不需要它(並且如果可能的話,不會傳遞z值更快)。然而,這是我目前找到的最快捷的方式。

最後,我使用模板緩衝區已經嘗試,這裏我用

glStencilFunc(GL_EQUAL, 0, 1); 
glStencilOp(GL_KEEP, GL_INCR, GL_INCR); 

當模板緩衝區被重置爲0的每個幀。這個想法是在第一次繪製像素之後。然後在模板緩衝區中將其更改爲非零。那麼該像素不應再次被繪製,從而減少透支量。然而,這已經證明不會比僅僅繪製沒有模板緩衝區或深度緩衝區的東西快。

什麼是最快的方法人們發現寫做什麼,我想?

+0

你是在一個批次中繪製它們嗎? – 2013-02-19 16:38:48

+0

是的,只有一個glDrawArrays(GL_TRIANGLES,0,100001 *(2 * 3));每幀畫出它們全部。 – Ellipsis 2013-02-19 16:52:06

+0

嗯我會期待相當好的結果 - 當窗戶較小時,它會更快? – 2013-02-19 17:01:23

回答

2

根本問題是,你是填充有限,這是GPU無法遮蓋你要求它在你期待的時間畫的所有片段。你是深度緩衝訣竅是無效的原因是,處理的時間最comsuming部分被遮蔽片段(無論是通過你自己的片段着色器,或通過固定功能着色引擎),發生之前深度測試。使用模板也會出現同樣的問題;在模版印刷之前着色像素。

有幾件事情,可能會有幫助,但取決於您的硬件:

  • 從正面採用深度緩衝來支持渲染你的精靈。現代GPU經常試圖確定在將它們發送給陰影之前是否可見碎片集合。粗略地說,檢查深度緩衝區(或其表示)以查看是否將要着色的片段可見,如果不是,則處理在該點處終止。這應該有助於減少需要寫入幀緩衝區的像素數量。
  • 使用一個片段着色器立即檢查你的紋理像素的alpha值,在此之前任何額外的處理丟棄的片段,如:

    varying vec2 texCoord; 
    uniform sampler2D tex; 
    
    void main() 
    { 
        vec4 texel = texture(tex, texCoord); 
    
        if (texel.a < 0.01) discard; 
    
        // rest of your color computations 
    } 
    

(你也可以使用Alpha測試中固定功能片段處理,但是不可能說是否在片段着色完成之前應用測試)。

+0

我可能一直不清楚。如果我給每個圓圈在z軸上的不同值,它實際上是兩倍的速度(在我的測試中),根本不使用深度緩衝。但是,對於圓圈,具有相同z值的深度緩衝並不明顯快於根本不做z緩衝。 (它看起來應該和它一樣工作?)這可能是因爲你的第一點。 (這很有趣,因爲這聽起來像早期的z?我認爲這是不可能的,如果你丟棄在片段着色器?)我的片段着色器就是這樣。感謝您的答覆。 – Ellipsis 2013-02-19 18:30:21

+0

@Ellipsis使用深度緩衝並不意味着:至少您可以將一堆讀取 - 修改 - 寫入循環保存到顏色和深度緩衝區,所以我並不感到驚訝。至於使用相同的z值,我不知道。這可能是因爲快速模式下的深度測試不到深度,或者相同模式下的結果與未進行深度測試的結果基本相同。最後,如果你使用這個技巧,那麼有些架構會禁用early-z,但它不是所有GPU的通用特性 - 這是一個實現問題,也是你通過測試發現的。而且,不客氣。 – radical7 2013-02-19 18:40:58