Problemas de prueba de OpenGL ES2 Alpha

Estoy renderizando en 3D objetos múltiples con texturas que tienen alfa. Todas las texturas se cargan bien, pero cuando bash renderizarlas una frente a la otra obtengo lo siguiente:

A la izquierda es lo que tengo. Derecha es lo que quiero

A la izquierda es lo que tengo. Correcto es lo que debería ser. La grilla es solo para ayudar a visualizar la perspectiva.

La textura frente a la textura del círculo rojo está recortada. Busqué una respuesta y me dice que use:

GLES20.glEnable( GLES20.GL_BLEND ); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA ); 

Pero lo estoy usando y todavía no está funcionando. Mi configuración en la que coloqué correctamente en la función onSurfaceCreated () es:

 GLES20.glClearColor( 0.75f, 0.85f, 1f, 1.0f ); GLES20.glEnable( GLES20.GL_BLEND ); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA ); GLES20.glEnable( GLES20.GL_DEPTH_TEST ); GLES20.glDepthFunc( GLES20.GL_LEQUAL ); GLES20.glDepthMask( true ); GLES20.glClearDepthf( 1f ); 

Mi fragmento sombreador es:

 uniform sampler2D texture; varying vec2 texCoord; void main(){ gl_FragColor = texture2D( texture, texCoord ); } 

¿Debo incluir algo en el manifiesto de Android para habilitar las pruebas alfa? No quiero terminar teniendo que organizar manualmente mis polígonos o usar descarte alfabético () porque necesito y quiero que algunos píxeles sean translúcidos.

¿Cómo puedo utilizar los búfers de profundidad de prueba Alpha 3D para que funcionen?

Aquí hay una descripción general de algunos métodos para renderizar con transparencia en OpenGL, con ventajas y desventajas para cada uno.

Prueba Alpha

Este es un método muy limitado, pero es suficiente para el caso específico sobre el que preguntó el afiche. El ejemplo que se muestra en realidad no necesita transparencia porque todo es totalmente opaco o completamente transparente (alfa = 1.0 o alfa = 0.0).

Solía ​​haber una prueba alfa para este propósito en OpenGL, pero esa es una característica obsoleta, y por supuesto no está en ES. Puedes emular lo mismo en tu sombreador de fragmentos, que se verá más o menos así:

 vec4 val = texture2D(tex, texCoord); if (val.a > 0.5) { gl_FragColor = val; } else { discard; } 

Ventajas:

  • Sencillo.
  • Sin trabajo adicional en el lado de la aplicación.

Desventajas:

  • Solo funciona para opacidad / transparencia total, no puede tratarse con semitransparencia.
  • Puede dañar el rendimiento porque, por lo general, significa que se deben realizar pruebas de profundidad antes de que el sombreador de fragmentos esté desactivado.

Clasificación y mezcla

La transparencia de representación es un caso de uso primario para la mezcla. El enfoque más común es establecer la función de combinación en SRC_ALPHA, ONE_MINUS_SRC_ALPHA , habilitar la mezcla y representar con el componente alfa de los fragmentos procesados ​​que contienen la opacidad deseada.

Si la escena contiene una mezcla de objetos totalmente opacos y objetos con transparencia, los objetos totalmente opacos se pueden representar primero, sin necesidad de ordenarlos. Solo los objetos con transparencia deben ser ordenados. La secuencia es entonces:

  1. Hacer una geometría completamente opaca.
  2. Renderizar geometría no opaca, ordenada de nuevo al frente.

Ventajas:

  • Puede manejar semitransparencia.
  • Puede manejar múltiples capas de geometría transparente.
  • La representación en sí misma es muy eficiente.

Desventajas:

  • Requiere clasificación para el resultado correcto. Para la función de mezcla mencionada anteriormente, la geometría debe representarse de nuevo al frente. Dependiendo de la aplicación, esto puede ser algo sin importancia y casi imposible. Por ejemplo, para renderizar correctamente la geometría de intersección, es posible que deba comenzar a partir triangularjs, lo que está lejos de ser atractivo.

Peeling de profundidad

Este es un uso muy inteligente de las características de OpenGL, en mi humilde opinión, y puede ser una buena solución práctica. Requiere múltiples pases de representación. La forma simple requiere 3 pases:

  1. Interpretar escena con la configuración habitual (prueba de profundidad habilitada, función de profundidad MENOS, escritura de color y profundidad habilitada), pero representa solo la geometría totalmente opaca. Si la opacidad es por objeto, puede manejar eso omitiendo llamadas de sorteo para objetos no opacos. De lo contrario, tendrá que descartar fragmentos no opacos con un sombreador similar al que se encuentra debajo de Alpha Testing.
  2. Renderice la geometría no opaca con la misma configuración que la anterior, excepto que la escritura del color está desactivada.
  3. Renderice la geometría no opaca nuevamente, pero esta vez con la función de profundidad EQUAL, la escritura de color habilitada nuevamente, la escritura de profundidad deshabilitada y el uso de fusión.

Se puede usar un shader mínimo para el pase 2, ya que no necesita producir ningún color de fragmento válido.

Ventajas:

  • Simple de implementar.
  • Razonablemente eficiente, no requiere clasificación.
  • Maneja correctamente la semitransparencia.

Desventajas:

  • La forma simple solo dibuja la capa más frontal de geometría transparente. Esto puede sonar como una limitación importante, pero los resultados en realidad pueden verse muy bien. Hay formas más avanzadas donde las capas adicionales se representan con pases adicionales. Más allá de la sobrecarga para esos pases adicionales, también se vuelve más complejo porque requiere múltiples memorias intermedias de profundidad. Creo que hay un libro blanco al respecto en el sitio web de NVIDIA.

Alfa a cobertura

No he usado esto por mí mismo, así que lo siguiente se basa en mi limitada comprensión teórica. Parece otro método interesante. Esto requiere una representación de múltiples muestras. La característica se habilita con glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) , que luego traduce los valores alfa en una máscara de cobertura, lo que da como resultado que solo se escriban partes de las muestras en función del valor alfa. Esto da como resultado un efecto de transparencia cuando el búfer de muestras múltiples se muestrea de forma descendente al búfer de color final.

Ventajas:

  • Puede manejar semitransparencia.
  • Correctamente maneja múltiples capas de transparencia.
  • Eficiente, particularmente si se hubiera usado MSAA de todos modos. No se requiere clasificación.

Desventajas:

  • Requiere MSAA. Las GPU modernas son muy efectivas en la renderización de MSAA, por lo que no es un gran problema. Muchas veces, es probable que desee utilizar MSAA de todos modos.
  • La resolución efectiva del valor alfa es muy pequeña, a menos que me falta algo. Por ejemplo, con 4x MSAA, solo puede representar 5 posibles valores alfa (0, 1, 2, 3, 4 muestras configuradas en máscara de cobertura).

La respuesta aceptada no lo cubre.

En su caso, la solución es desactivar las pruebas de profundidad y posiblemente revertir el orden que está dibujando.

El descarte del sombreador es un truco que se verá horrible si necesita un rango de valores alfa.