可以說我有2種,如人類和小馬。它們具有不同的骨骼系統,因此對於每個物種而言,統一的骨骼陣列必須是不同的。我是否必須實現兩個獨立的着色器程序,能夠正確渲染每個骨骼數組,或者是否有辦法動態聲明統一數組並反覆遍歷該動態數組?(OpenGL 3.1 - 4.2)動態均勻陣列?
記住性能(有所有的着色器在決策分支四處流竄)。
可以說我有2種,如人類和小馬。它們具有不同的骨骼系統,因此對於每個物種而言,統一的骨骼陣列必須是不同的。我是否必須實現兩個獨立的着色器程序,能夠正確渲染每個骨骼數組,或者是否有辦法動態聲明統一數組並反覆遍歷該動態數組?(OpenGL 3.1 - 4.2)動態均勻陣列?
記住性能(有所有的着色器在決策分支四處流竄)。
在OpenGL 4.3之前,GLSL中的數組必須是固定的編譯時大小。 4.3允許使用着色器存儲緩衝區對象,這允許它們的最終長度是「無界」的。基本上,你可以這樣做:
buffer BlockName
{
mat4 manyManyMatrices[];
};
的OpenGL將計算出有多少矩陣是這個數組在運行時根據您如何使用glBindBufferRange
。所以你仍然可以使用manyManyMatrices.length()
來獲得長度,但它不會是編譯時常量。
但是,此功能(在編輯時)非常新,只能在beta版本中實現。它還需要GL 4.x級硬件(又名:Direct3D 11級硬件)。最後,由於它使用着色器存儲塊,訪問數據可能比人們希望的要慢。
因此,我建議你只是使用一個統一的塊,並使用最多的矩陣。如果這成爲一個內存問題(不太可能),那麼你可以根據數組大小拆分着色器,或使用着色器存儲塊或其他。
您可以使用n-by-1-Textures作爲數組的替代品。紋理尺寸可以在運行時指定。我使用這種方法將任意數量的光傳遞給我的着色器。我很驚訝,儘管有許多循環和分支,它運行得有多快。有關示例,請參閱jReality源代碼中jogl3.glsl.nontransp中的polygon.f着色器文件。
uniform sampler2D sys_globalLights;
uniform int sys_numGlobalDirLights;
uniform int sys_numGlobalPointLights;
uniform int sys_numGlobalSpotLights;
...
int lightTexSize = sys_numGlobalDirLights*3+sys_numGlobalPointLights*3+sys_numGlobalSpotLights*5;
for(int i = 0; i < numDir; i++){
vec4 dir = texture(sys_globalLights, vec2((3*i+1+0.5)/lightTexSize, 0));
...