Nota: Ya encontré una respuesta (que publicaré después de esta pregunta). Me preguntaba si lo estaba haciendo bien o si hay una mejor manera.
Estoy haciendo un juego isométrico "2.5D" usando OpenGL ES (JOGL). Por "2.5D", quiero decir que el mundo es 3D, pero se representa con mosaicos isométricos 2D.
El problema original que tuve que resolver fue que mis texturas debían renderizarse en orden (de atrás hacia adelante), de modo que los mosaicos se superpusieran correctamente para crear el efecto adecuado. Después de leer un poco, rápidamente me di cuenta de que este es el enfoque 2D del "viejo sombrero". Esto se volvió difícil de hacer de manera eficiente, ya que el jugador puede modificar el mundo 3D (por lo que las cosas pueden aparecer en cualquier lugar del espacio 3D), por lo que parecía lógico que aproveche el búfer de profundidad. Esto significaba que no tenía que preocuparme por procesar las cosas en el orden correcto.
Sin embargo, me enfrenté a un problema. Si usa GL_DEPTH_TEST
y GL_BLEND
juntos, crea un efecto donde los objetos se mezclan con el fondo antes de que se "ordenen" por orden z (lo que significa que se produce un extraño tipo de superposición donde debería estar la transparencia).
Aquí hay un pseudocódigo que debería ilustrar el problema (por cierto, estoy usando libgdx para Android).
create() {
// ...
// some other code here
// ...
Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
Gdx.gl.glEnable(GL10.GL_BLEND);
}
render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// ...
// bind texture and create vertices
// ...
}
Entonces la pregunta es: ¿cómo resuelvo el problema de superposición de transparencia?
Respuestas:
OK, entonces aquí está mi solución (por favor comente si se puede hacer mejor) ...
Resulta que, de hecho, debería estar usando pruebas alfa (sin embargo, descubrí esto por accidente, así que no estoy completamente seguro de por qué funciona).
Tenga en cuenta el uso de
GL_ALPHA_TEST
, yglAlphaFunc
.fuente
La prueba alfa se utiliza para detener el renderizador que dibuja píxeles en cualquier búfer, incluido el búfer z. La combinación alfa es solo una cosa visual: los valores todavía se escriben en el zbuffer, lo que puede provocar problemas como este: los píxeles invisibles están delante de los píxeles renderizados posteriormente, lo que significa que fallarán la prueba z cuando dibuje los nuevos píxeles. Esto es lo que puedes ver en la imagen que diste, un error ztest.
Desactivar la escritura z también logrará los mismos fines, pero debe asegurarse de dibujar todo en el orden frontal. Esto debería ser lo suficientemente fácil de hacer en tu juego isométrico.
fuente