¿Cuáles son algunos métodos para representar la transparencia en OpenGL?

14

La combinación alfa se puede activar para hacer que las superficies sean transparentes, así:

glDisable(GL_DEPTH_TEST); //or glDepthMask(GL_FALSE)? depth tests break blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Pero esto solo funciona si los objetos se representan en orden de atrás hacia adelante. De lo contrario, las cosas en el fondo aparecen frente a objetos más cercanos, como el piso en la imagen a continuación. Para las partículas y los elementos de la GUI, la ordenación estaría bien, pero para las mallas triangulares parece que sería demasiado esfuerzo y lento, como se explica aquí: https://www.opengl.org/wiki/Transparency_Sorting .

¿Cuáles son los métodos comunes para lidiar con esto? Sé que esto es bastante amplio y no busco detalles de implementación en profundidad, solo una breve descripción de algunos enfoques y lo que podría estar involucrado.

ingrese la descripción de la imagen aquí

jozxyqk
fuente
No estoy seguro de si esto debería ser una respuesta o no, pero los errores en su imagen son causados ​​por el procesamiento sin pruebas de profundidad en todas las primitivas. Debería renderizar la escena en 2 pasos: Primero renderice normalmente toda la geometría sólida. Después, deshabilite las escrituras de profundidad (no GL_DEPTH_TEST) y renderice la geometría translúcida en un orden aproximado de atrás hacia adelante. Esto asegurará que la geometría transparente no se dibuje frente a la geometría sólida que está frente a ella.
yuriks
@yuriks En este caso, probablemente sea un mal ejemplo de mi parte, pero todo está destinado a ser transparente. Quería algo que mostrara cuán incorrecta podría verse la transparencia cuando se hace mal. También un ejemplo donde la geometría de clasificación sería increíblemente difícil (por ejemplo, aquí el piso es un polígono gigante y cubre todo el rango de profundidad).
jozxyqk

Respuestas:

10

Un conjunto de técnicas para evitar pedidos explícitos se denominan Orden de Transparencia Independiente (OIT para abreviar).

Hay muchas técnicas de la OIT.

Históricamente uno es el peeling de profundidad . En este enfoque, primero se representan los fragmentos / píxeles más frontales, luego se encuentra el más cercano al que se encontró en el paso anterior y así sucesivamente, pasando con tantas "capas" como sea necesario. Se llama pelado de profundidad porque en cada pasada se "pela" una capa de profundidad. Toda su capa se puede recombinar normalmente de atrás hacia adelante. Para implementar este algoritmo, debe tener una copia del búfer de profundidad.

Otro conjunto de técnicas son las combinadas de la OIT. Una de las más recientes e interesantes es la OIT Blended ponderada propuesta por McGuire y Bavoil . Básicamente aplica una suma ponderada para todas las superficies que ocupan un fragmento dado. El esquema de ponderación que proponen se basa en el espacio de cámara Z (como una aproximación a la oclusión) y la opacidad.
La idea es que si puede reducir el problema a una suma ponderada, realmente no le importa ordenar.

Además del documento original, un gran recurso para detalles de implementación y problemas de Weighted Blended OIT está en el blog de Matt Pettineo . Como puede leer en su publicación, esta técnica no es una bala de plata. El principal problema es que el esquema de ponderación es central y debe ajustarse de acuerdo con su escena / contenido. A partir de sus experimentos, aunque la técnica parece funcionar bien para una opacidad relativamente baja y media, falla cuando la opacidad se acerca a 1 y, por lo tanto, no se puede utilizar a partir de materiales donde gran parte de la superficie es opaca (hace el ejemplo del follaje).

Una vez más, todo se reduce a cómo ajustar sus pesos de profundidad y encontrar los que se ajustan perfectamente a sus casos de uso no es necesariamente trivial.

En cuanto a lo que se necesita para la OIT mezclada ponderada, nada más que dos objetivos de procesamiento adicionales. Uno que llene con el color alfa premultiplicado (color * alfa) y alfa, ambos ponderados en consecuencia. El otro solo para las pesas.

cifz
fuente
6

Una opción es usar pelado en profundidad.

Esencialmente, uno procesa la escena varias veces (digamos, n veces) para determinar el nfragmento más cercano, el segundo más cercano, hasta los fragmentos más cercanos de la escena.

Este procesamiento se realiza aplicando primero una prueba de profundidad regular a toda la escena (que, naturalmente, devuelve la superficie más cercana). Luego se usa el resultado de la prueba de profundidad para filtrar la primera capa, ignorando todo con una profundidad menor que la que se obtiene en la prueba de profundidad.

Al volver a aplicar la prueba de profundidad, se devolverá la segunda capa. Repita según sea necesario.

Una vez que tenga las capas, puede dibujar todas las capas en orden inverso (suponiendo que realizó un seguimiento de los colores RGBA para cada capa), mezclando normalmente, ya que las capas están en orden de adelante hacia atrás.

es1024
fuente
1
¡Gracias! Parece que necesitaré dos amortiguadores de profundidad para esto. Es decir, una para almacenar y filtrar las últimas profundidades, y otra para realizar la prueba de profundidad para el renderizado actual. Corrígeme si me equivoco, pero supongo que necesitaré dos texturas de profundidad para el FBO que cambio entre cada pase de pelado.
jozxyqk
1
@jozxyqk Correcto, dos buffers de profundidad son necesarios para este procedimiento.
es1024
1

La creme de la creme de un solo paso no (o pocos) compromete la transparencia en OpenGL es un búfer A. Con OpenGL moderno, es posible implementar:

http://blog.icare3d.org/2010/06/fast-and-accurate-single-pass-buffer.html

Evita los múltiples pases de pelado en profundidad y no requiere una clasificación onerosa.

Xenón de Ártico
fuente
3
Idealmente, las respuestas deben ser independientes y depender vitalmente de enlaces externos. Tener enlaces es bueno para el material complementario, pero una respuesta no debería consistir solo en una palabra clave. Si pudiera incluir algunos detalles sobre qué es un búfer A y cómo funciona, eso mejoraría enormemente su respuesta.
Martin Ender