2012-03-28 8 views
5

Diciamo che ho 2 specie come umani e pony. Hanno diversi sistemi scheletrici quindi la matrice ossea uniforme dovrà essere diversa per ogni specie. Devo implementare due programmi shader separati in grado di eseguire correttamente il rendering di ogni array di osso o esiste un modo per dichiarare in modo dinamico array uniformi e scorrere invece attraverso quella matrice dinamica?(OpenGL 3.1 - 4.2) Array dinamici uniformi?

Prestare attenzione alle prestazioni (ci sono tutti gli shader che aspirano a fare il giro della decisione).

risposta

12

Fino a OpenGL 4.3, gli array in GLSL dovevano essere di dimensioni fisse e in fase di compilazione. 4.3 consente l'uso di oggetti buffer di memoria shader, che consentono la loro lunghezza massima "illimitata". In sostanza, si può fare questo:

buffer BlockName 
{ 
    mat4 manyManyMatrices[]; 
}; 

OpenGL sarà capire quanti matrici sono in questo array in fase di esecuzione in base a come si utilizza glBindBufferRange. Quindi puoi ancora usare manyManyMatrices.length() per ottenere la lunghezza, ma non sarà una costante in fase di compilazione.

Tuttavia, questa funzione è (al momento della modifica) molto nuova e implementata solo in versione beta. Richiede anche hardware GL 4.x-classe (noto anche come hardware Direct3D di classe 11). Infine, poiché utilizza blocchi di archiviazione shader, l'accesso ai dati potrebbe essere più lento di quanto si possa sperare.

Come tale, suggerirei di utilizzare solo un blocco uniforme con il maggior numero di matrici che usereste. Se questo diventa un problema di memoria (improbabile), allora è possibile dividere gli shader in base alle dimensioni dell'array o utilizzare blocchi di storage shader o altro.

10

È possibile utilizzare n-by-1-Textures in sostituzione degli array. La dimensione della trama può essere specificata in fase di esecuzione. Io uso questo approccio per passare un numero arbitrario di luci ai miei ombreggiatori. Sono sorpreso dalla velocità con cui corre nonostante i numerosi loop e rami. Per un esempio vedere il file shag poligono.f in jogl3.glsl.nontransp nelle origini jReality.

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)); 

...