Mezcla vs Muestreo de Textura

No creo que esta pregunta haya sido formulada antes ya que no pude encontrar información sobre esto en Internet.

Digamos que quiero mezclar dos texturas juntas:

  • Una textura que contiene el resultado del cálculo de SSAO.
  • Una textura que contiene la escena renderizada.

Podría hacerlo de dos maneras:

  1. Use un sombreador que muestree tanto el SSAO como las texturas de la escena, las mezcle y arroje el color final a un objective de renderizado.
  2. Interprete la textura que contiene la escena y use un modo de fusión para mezclar la textura SSAO en la parte superior. Solo la textura SSAO será muestreada dentro del sombreador.

¿Es posible dar una respuesta general sobre qué versión es más rápida o depende mucho del hardware?

En realidad es una pregunta muy interesante. Inicialmente pensé que una respuesta definitiva ni siquiera existe; después de todo, solo es cierto que la diferencia de velocidad entre estos methods se desvía según el hardware y la versión del controller, al igual que para cualquier otra cosa.

Pero, ¿qué hace exactamente esa desviación de velocidad? Veamos la diferencia entre la fusión de funciones fijas a la antigua y la fusión de progtwigs de fragments personalizados. Tal vez surja algún tipo de conclusión.

Comparación aproximada

La fusión de funciones fijas usa una de las ecuaciones pnetworkingefinidas para mezclar salidas de color de fragments con los valores de color del framebuffer:

  1. renderizar la primera textura al framebuffer;
  2. establecer la function de mezcla y los parameters para una mezcla alfa simple;
  3. renderizar una segunda textura al framebuffer. Tenga en count que la fusión de funciones fijas se realiza directamente en el framebuffer, lo testing y lo modifica al mismo time.

La mezcla basada en Shader usa un progtwig de fragments personalizado para convertir un fragment en colors y un valor de profundidad:

  1. renderizar la primera textura a un buffer de textura previamente asignado;
  2. cambie el progtwig de sombreado a uno con combinación personalizada de cualquier complejidad;
  3. renderizar una segunda textura al framebuffer mientras lee buffer de texturas del paso 1.

¿Lo que da?

Puede parecer que la fusión de funciones fijas debe ser más rápida, debido al hardware especial de la GPU para la mezcla simple, las lecturas directas de framebuffer y la falta de un búfer de memory adicional.

Sin embargo, hoy en día la memory de video suele ser abundante, y el hardware está realmente optimizado para la tubería personalizable, por lo que no hay ganancia en la velocidad de lectura. La velocidad de la GPU para una mezcla simple depende mucho del hardware, pero también lo es el performance de los sombreadores.

Todavía falta un detalle importante: la mezcla de framebuffer tiene su propia etapa en el pipeline de renderizado : es independiente de los sombreadores de fragments. Lo que significa que la fusión de funciones fijas se puede considerar generalmente como "siempre más rápida" simplemente porque puede realizar operaciones de mezcla mientras el progtwig de sombreado de fragments personalizado procesa fragments posteriores.

Esto también significa que la fusión de funciones fijas contribuye a su recuento de ROP y, en consecuencia, al ancho de banda del framebuffer . Y los sombreadores de fragments contribuyen a los costos de sombreado de su fragment . El ancho de banda de frame-buffer es una function del reloj de memory GPU, y la velocidad de sombreado de fragments es una function del reloj core GPU.

Por lo tanto, en caso de problemas de performance con dos técnicas relacionadas, es posible que estén vinculados con ROP o con sombreado de fragments. (En realidad, hay otros límites de resources posibles, como el límite en las transformaciones de vértices, pero estos no importan en el context de la pregunta).

Solo en aras de la exhaustividad y los posibles efectos sobre el performance del muestreo de textura, también vale la pena señalar que el ancho de banda de textura se consume cada vez que una request de obtención de textura se va a la memory . El ancho de banda de textura también es una function del reloj de memory GPU.

Conclusión

En conclusión, utilice la mezcla para operaciones simples de fusión o cuando necesite combinar algo con el framebuffer completo, y no estará vinculado a ROP. Utilice el muestreo de texturas cuando sea necesario o cuando mejor se adapte a su código, y no estará sujeto a sombreado de fragments.

Obviamente, si tiene un límite de ancho de banda de textura, es mejor evitar muestras de textura innecesarias, por lo que la mezcla basada en framebuffer es preferible.

Su caso específico

Mientras no estés obligado a esas tres cosas mencionadas anteriormente, la velocidad relativa de tus dos methods debería ser idéntica. # 1 sería más fácil de modificar y corregir, en mi opinión.

Además, no he visto su código, pero generalmente SSAO debe aplicarse solo a la parte ambiental de la iluminación, por lo que mezclarla en la escena final suena mal. Razón de más para probar la textura de SSAO en su sombreador de iluminación.

La respuesta estándar a "que es más rápido" es "perfilar y ver". Porque todo varía mucho según la plataforma, el patrón de encoding, & c. (El método 2, con el modo de fusión, podría tener soporte directo de hardware … pero nunca se sabe. Las tarjetas modernas, detrás de escena, podrían hacer exactamente el mismo trabajo que harías con tu sombreador).

El Método 1 podría, en general, "bloquear" para tres sorteos (color, ssao, combinar), mientras que el método 2 solo espera en dos sorteos (color, ssao-with-blendmode). Pero cómo esto afecta el performance debería ser medido.

Este es el tipo de cosas que hará una vez por cuadro, probablemente, por lo que no será lo más importante para optimizar. Cualquiera de las dos está casi seguro bien.

Usar el método 1 le dará más flexibilidad sobre cómo combinar las dos pantallas, ya que usted hace todos los cálculos en su sombreador. Esto podría ser aún más valioso para usted que los ciclos de conteo, ya que le permite controlar el aspecto de su producto.