2012-03-28 16 views
5

Digamos que tengo 2 especies, como los humanos y los ponies. Tienen diferentes sistemas esqueléticos por lo que la matriz ósea uniforme tendrá que ser diferente para cada especie. ¿Tengo que implementar dos programas de sombreadores separados capaces de procesar cada matriz ósea correctamente o hay una forma de declarar dinámicamente matrices uniformes e iterar a través de esa matriz dinámica en su lugar?(OpenGL 3.1 - 4.2) Arrays uniformes dinámicos?

Teniendo en cuenta el rendimiento (Hay todos los sombreadores de succión en la ramificación de decisión).

Respuesta

12

Hasta OpenGL 4.3, las matrices en GLSL tenían que ser de un tamaño de tiempo de compilación fijo. 4.3 permite el uso de objetos de almacenamiento intermedio de sombreado, que permiten que su longitud final sea "ilimitada". Básicamente, usted puede hacer esto:

buffer BlockName 
{ 
    mat4 manyManyMatrices[]; 
}; 

OpenGL se darán cuenta de cuántas matrices que están en esta matriz en tiempo de ejecución en función de cómo se utiliza glBindBufferRange. Entonces todavía puede usar manyManyMatrices.length() para obtener la longitud, pero no será una constante en tiempo de compilación.

Sin embargo, esta característica es (en el momento de esta edición) muy nueva y solo se implementó en versión beta. También requiere hardware GL 4.x-class (también conocido como hardware Direct3D 11-class). Por último, dado que usa bloques de almacenamiento shader, el acceso a los datos puede ser más lento de lo que uno podría esperar.

Como tal, le sugiero que utilice un bloque uniforme con la mayor cantidad de matrices que usaría. Si eso se convierte en un problema de memoria (poco probable), puede dividir los sombreadores en función del tamaño de la matriz o usar bloques de almacenamiento de sombreado o lo que sea.

10

Puede usar n-by-1-Textures como reemplazo de las matrices. El tamaño de la textura se puede especificar en tiempo de ejecución. Uso este enfoque para pasar un número arbitrario de luces a mis sombreadores. Me sorprende lo rápido que funciona a pesar de los muchos bucles y ramas. Para ver un ejemplo, consulte el archivo shader polygon.f en jogl3.glsl.nontransp en las fuentes 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)); 

...

Cuestiones relacionadas