2013-01-05 71 views
11

我有接受以下屬性的頂點着色器:OpenGL:多個頂點的單頂點屬性?

  • a_posCoord:頂點位置
  • a_texCoord:紋理座標(傳遞到片段着色器)
  • a_alpha:透明度因子(傳遞到片段着色器)

我渲染的對象都是「廣告牌」(一對用於製作矩形的直角三角形)。

我使用一個電話glDrawArrays來渲染許多廣告牌,每個廣告牌可能具有唯一的alpha值。一個廣告牌有6個頂點。下面是一些僞代碼來說明我如何組織頂點屬性緩衝區單個廣告牌:

vertexAttributes = [ 

    px1,py1,pz1, // vertex 1: a_posCoord 
    tx1,ty1,  // vertex 1: a_texCoord 
    alpha,  // vertex 1: a_alpha 

    px2,py2,pz2, // vertex 2: a_posCoord 
    tx2,ty2,  // vertex 2: a_texCoord 
    alpha,  // vertex 2: a_alpha 

    px3,py3,pz3, // vertex 3: a_posCoord 
    tx3,ty3,  // vertex 3: a_texCoord 
    alpha,  // vertex 3: a_alpha 

    px4,py4,pz4, // vertex 4: a_posCoord 
    tx4,ty4,  // vertex 4: a_texCoord 
    alpha,  // vertex 4: a_alpha 

    px5,py5,pz5, // vertex 5: a_posCoord 
    tx5,ty5,  // vertex 5: a_texCoord 
    alpha,  // vertex 5: a_alpha 

    px6,py6,pz6, // vertex 6: a_posCoord 
    tx6,ty6,  // vertex 6: a_texCoord 
    alpha  // vertex 6: a_alpha 

    // ... Many more billboards not shown ... 
]; 

注意到同樣的alpha值是如何重複6次,每次一個頂點。

有沒有一種方法可以爲所有6個頂點指定一個屬性,而無需爲每個頂點重複該屬性?

這是我希望我的頂點屬性緩衝區的樣子,在減少緩衝區的大小的興趣是什麼:

vertexAttributes = [ 
    px1,py1,pz1, // vertex 1: a_posCoord 
    tx1,ty1,  // vertex 1: a_texCoord 

    px2,py2,pz2, // vertex 2: a_posCoord 
    tx2,ty2,  // vertex 2: a_texCoord 

    px3,py3,pz3, // vertex 3: a_posCoord 
    tx3,ty3,  // vertex 3: a_texCoord 

    px4,py4,pz4, // vertex 4: a_posCoord 
    tx4,ty4,  // vertex 4: a_texCoord 

    px5,py5,pz5, // vertex 5: a_posCoord 
    tx5,ty5,  // vertex 5: a_texCoord 

    px6,py6,pz6, // vertex 6: a_posCoord 
    tx6,ty6,  // vertex 6: a_texCoord 

    alpha  // vertex 1-6: a_alpha 

    // ... Many more billboards not shown ... 
]; 

對於它的價值,我目前的解決方案工作得很好,但讓我感覺髒。我剛剛開始處理使用glVertexAttribPointer,並想知道它是否支持這樣的事情,或者如果有一種不同的方法或技術我可以用來實現更少的暴力行爲。


這是更具體的是WebGL的問題,但我很好奇的OpenGL一般意義上的。

我知道一個幾何着色器真的是我需要的這個特定的例子,但它是沒有問題的,因爲它們目前在WebGL中不受支持。

+0

[渲染與多個索引網]的可能重複(http://stackoverflow.com/questions/11148567/rendering-meshes-with-multiple-indices) –

+1

非常接近被確實是一個副本,但我想保留它幾天,看看有沒有其他的知識,因爲我的問題是更具體一些,有人可能有一個完全不同的方法,我不知道。我猜我必須堅持使用冗餘數據,直到WebGL利用ES3的幾何着色器支持。 – namuol

+0

我注意到glVertexBindingDivisor不是WebGL 1.0或ES 2.0(我正在使用)的一部分...... :( – Andy

回答

6

頂點不是位置頂點是由多重屬性組成的長向量。更改一個屬性,最後得到一個不同的頂點。所以不,你不能爲多個頂點使用單個頂點屬性,因爲這在語義上沒有意義。

然而,OpenGL的新版本有可能設置某個頂點屬性的緩衝區偏移量前進的速率。實際上,這意味着給定頂點數組的數據會在屬性的緩衝區偏移量提前之前被複制到n個頂點。設置該除數的函數是glVertexBindingDivisor。在你的情況下,你會爲​​alpha數組設置一個Binding Divisor 。但重要的是,這不會爲多個頂點使用單個屬性,但它會使OpenGL做到您爲您做的重複。

+1

我認爲這一點也很重要,注意這種重複只發生在渲染過程中,所以存儲的綁定除數爲6的alpha值將使用更少的內存(除非我嚴重誤解了這個特性!) – Andy

+0

OpenGL做重複而不是單一屬性用於多重tiple頂點?這是否意味着GPU上的頂點緩衝區以某種方式展開並且內存不被保存?如果不是,那麼可觀察到的差異是什麼? – Ruslan

0

如果某個頂點屬性對於每個頂點都是常量,爲什麼不使用統一變量?如果它是恆定的,它是統一的!通過這種方法,您只需設置統一值一次,並減少數據集。

+1

這不會工作,因爲我只爲整個包含_many_廣告牌的緩衝區對象調用'glDrawArrays',每一個都有自己的alpha值 – namuol

+0

這對我來說並不清楚,我認爲你的運氣不好對不起 – Luca

+0

是的 - 在重讀我的問題之後,我意識到我沒有強調重要的部分。 ! – namuol

0

我通過實例化渲染實現了這種效果。 glVertexAttribDivisor(1);使openGL每個實例讀取一次頂點屬性。如果你的壓力板有不同的幾何形狀,你可以考慮把模型矩陣作爲一個屬性與alpha相同。

+1

這似乎沒有WebGL的支持,但我會研究它,謝謝! – namuol

0

一對夫婦的想法:

1)硬着頭皮更新頂點緩衝區,但只有當阿爾法改變。

2.)休息四邊形的列表轉換成批次,僅重建改變批次..

3.)控制廣告牌的數量和α值的陣列結合到一個均勻... 在頂點數據的alpha,或者在一些未使用的通道/附加通道中,在您的統一數組中存儲該廣告牌的alpha的索引 。至少你可能只上傳n個alpha值。

4)結合2和3 ...

我只是瞎猜......我想看看別人有很好的解決方案!

0

我還沒有詳細研究過這個,但我認爲你也可以使用glDrawElementsInstanced。有了這個,你可以將你的alpha值放到一個大的統一數組中,並且實例索引將以某種方式傳遞給着色器。檢查了這一點:

http://sol.gfxile.net/instancing.html