2011-01-10 16 views
35

¿Qué es mejor?Organizar sombreadores GLSL en el motor OpenGL

  1. Para tienen un programa de sombreado con una gran cantidad de uniformes especificando luces de usar, o asignaciones de hacer (por ejemplo, necesito uno de malla para ser mapeada paralaje, y otro paralaje/especular asignada). Haría una lista de uniformes en caché para transferencias perezosas, y solo cambiaría un par de uniformes por cada malla siguiente si fuera necesario.

  2. Para tienen una gran cantidad de programas de sombreado para cada caso necesario, cada uno con una pequeña cantidad de uniformes, y hacer el enlace perezoso con glUseProgram para cada malla si es necesario hacerlo. Aquí supongo que las mallas están correctamente agrupadas, para evitar interruptores redundantes.

Respuesta

28

La mayoría de los motores modernos que conozco tienen un "shader cache" y usan la segunda opción, porque aparentemente es más rápido.

También puede echar un vistazo a ARB_shader_subroutine que permite el enlace dinámico. Pero creo que solo está disponible en hardware de clase DX11.

+2

Creo que es correcto. Viendo que OpenGL4 representa algo de DX11 en las características, seguí y miré el "registro de cambios" para 4.1, y allí parece ser (http://en.wikipedia.org/wiki/Opengl#OpenGL_4.1): "Reducido tiempos de compilación de shaders con la capacidad de consultar y cargar un binario para objetos de programa de sombreado " –

15

En general, la opción 2 será más rápida/mejor a menos que tenga una cantidad realmente grande de programas. También puede usar objetos de búfer compartidos entre programas para que no tenga que restablecer ningún valor cuando cambie de programa.

Además, una vez que vincula un programa, puede liberar todos los sombreadores que ha vinculado en el programa. Esto liberará todo el código fuente y cualquier información previa al enlace que mantenga el controlador, dejando solo el programa completamente enlazado en la memoria.

+0

¿Qué son esos objetos de búfer? –

+0

Probablemente Vertex Buffer Objects. – Oscar

+7

Uniform Buffer Objects, una nueva característica en GL4. –

0

Tendería a creer que depende de la aplicación específica. Y sí, ya que sería más eficiente decir ejecutar 100 programas donde cada uno puede tener de 2 a 16 uniformes cada uno; puede ser mejor tener un intercambio de los dos. Me inclinaría a pensar que decir, tal vez, de 10 a 20 programas para sus técnicas de sombreado más comunes sería suficiente o un poco más. Por ejemplo, es posible que desee tener un programa/sombreador para hacer todo su mapeo de relieve, uno para hacer todos sus efectos de niebla, uno para hacer reflexiones, uno para hacer refracciones. Ahora, fuera del alcance de su pregunta, creo que también sería pertinente incluir una clase en el motor BatchProcess & BatchManager para reducir la cantidad de CPU - Llamadas de la GPU sobre el bus ya que esto demostrar eficiencia también. No creo que haya una solución que se adapte a todas las preguntas, ya que creo que sería específico de la aplicación así como establecer la relación entre cuántos lotes (cubos) de vértices (primitivos) tendría su motor y cuántos vértices que contendría cada uno de esos lotes.

Para intentar aclarar esto: un juego puede tener 4 contenedores o lotes donde cada lote puede contener hasta 10,000 vértices para que se considere lleno antes de que BatchManager decida vaciar ese cubo enviando todos esos vértices a la tarjeta gráfica para que se procese y dibuje la tubería de Representación, donde un juego diferente puede tener 10 cubos con 5.000 vértices, u otro juego podría tener 8 cubos con 12.0000 vértices.

Así que podría haber una compensación de tratar de combinar los dos de acuerdo a sus necesidades. Si tiene 1 programa individual con cientos de uniformes; el programa individual es más fácil de administrar dentro de la canalización, pero los sombreadores serían demasiado difíciles de leer y administrar.Por otra parte, tener sombreadores con muy pocos uniformes es bastante fácil de leer y administrar, pero tener 100s de programas es un poco más difícil de administrar en la CPU antes de vincularlos y enviarlos para que se reproduzcan correctamente. Personalmente, trataría de encontrar un término medio para que tenga suficientes programas para hacer cada tarea específica que sea completamente única entre sí, como hacer densidad de niebla en uno y un mapeo de sombra volumétrica en otro donde cada programa tiene suficientes uniformes para hacer los cálculos requeridos.

El siguiente paso sería hacer algunas pruebas de punto de referencia para ver dónde se equilibran la eficiencia y la sobrecarga para realizar los ajustes apropiados.

Cuestiones relacionadas