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. 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.
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:
Desventajas:
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:
Ventajas:
Desventajas:
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:
Se puede usar un shader mínimo para el pase 2, ya que no necesita producir ningún color de fragmento válido.
Ventajas:
Desventajas:
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:
Desventajas:
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.