2012-01-28 81 views
9

桌面GLSL是否有可能將固定大小的浮點數組作爲屬性傳遞給頂點着色器?如果是,如何?GLSL每頂點固定大小的陣列

我想每個頂點的權重人物動畫有,所以我想有這樣的事情在我的頂點着色器中的以下內容:

attribute float weights[25]; 

我將如何填補屬性陣列從我的C++ &的OpenGL程序?我在另一個question中看到,我可以獲取數組屬性的屬性位置,然後將該索引添加到該位置。有人可以舉一個例子來說明我的漂亮陣列嗎?

謝謝。

回答

16

讓我們先從您的要求開始。

幾乎沒有硬件,目前存在將attribute float weights[25];編譯。雖然着色器可以具有屬性數組,但每個數組索引都表示一個新的屬性索引。並且在當前存在的所有硬件上,屬性索引的最大數量是... 16.您需要25,而這是只是的權重。

現在,您可以通過記住您可以使用vec4屬性輕鬆地減輕這一點。因此,您將每四個數組元素存儲在一個屬性中。你的陣列將是attribute vec4 weights[7];這是可行的。當然,你的體重獲取邏輯將不得不改變。

即便如此,你似乎沒有考慮到這對於你的頂點數據實際上的意思是的影響。每個屬性表示頂點數據的一個組件。渲染調用的每個頂點將具有相同數量的數據;該數據的內容將有所不同,但不是多少數據。

爲了做到你所建議,每個頂點在你的網將需要25輛彩車描述的重量。即使這是作爲標準化的無符號字節存儲的,那麼至少仍有25個額外字節的數據值。好多啊。特別是考慮到大多數頂點的巨大的,這些值中的大部分將是0.即使在最壞的情況下,你也會看到可能影響單個頂點的6-7個骨骼。

剝皮在頂點着色器通常做的方式是限制影響單個頂點骨骼數量。這樣,你不使用一組屬性;您只需使用vec4屬性作爲權重。當然,你現在也需要說哪個骨骼與哪個重量相關聯。因此,您有第二個vec4屬性指定該重量的骨骼索引。

這很好的平衡。您只需佔用2個額外的屬性(可以是大小無符號的字節)。對絕大多數頂點而言,你永遠都不會注意到,因爲大多數頂點只受1-3個骨骼的影響。少數使用4,少數仍使用5+。在這些情況下,您只需切斷最低權重並按比例重新計算其他權重。

+2

非常感謝。你回答了我所有的問題,甚至更多!我希望這會大大提高性能!再次感謝。 – Nicholas 2012-01-28 10:08:15

11

尼科爾布拉斯已經給了你一個答案如何重組你的任務。你應該這樣做,因爲處理25個浮點的頂點,可能通過一些四元數乘法會浪費很多GPU的處理能力;無論如何,頂點的大部分屬性都將轉化爲身份轉換。

然而,由於學術的原因,我要告訴你,如何通過每個頂點25浮點數。關鍵不在於使用屬性,而是從某個緩衝區(紋理)中獲取數據。 GLSL頂點着色器階段具有內建變量gl_VertexID,其傳遞當前處理的頂點的索引。使用最近的OpenGL,您也可以從頂點着色器訪問紋理。所以你有一個尺寸爲vertex_count × 25的紋理。在你的頂點着色器,你可以訪問它們使用texelFetch功能,即texelFetch(param_buffer, vec2(gl_VertexID, 3));

如果在骨骼動畫中使用該系統通常被稱爲質感蒙皮。但它應該謹慎使用,因爲它是一個真正的表演豬。但有時你無法避免它,例如在實現面部動畫系統時,如果要準確地模擬人臉,必須將所有頂點的重量減輕到26塊肌肉。

+0

非常有趣!我將在未來的工作中牢記這一點。 – Nicholas 2012-01-28 10:06:18