¿Cómo uso las pruebas de profundidad y la transparencia de texturas en mi mundo 2.5D?

11

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_TESTy GL_BLENDjuntos, 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).

problema de superposición de 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?

Nick Bolton
fuente
2
Solo un comentario para decirle que he seguido exactamente lo mismo que usted para mi motor 2D: primero tratando de ser inteligente y ordenar los mosaicos en Z yo mismo, luego me di cuenta de que no había razón para que la escena fuera plana, lo que le dio a mis mosaicos un Coordenada Z y prueba de activación de alfa. No estoy seguro de si tienes razón, pero no estás solo :-)
sam hocevar

Respuestas:

7

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).

create() {
    // ...
    // some other code here
    // ...

    Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL10.GL_ALPHA_TEST);
}

render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    Gdx.gl10.glAlphaFunc(GL10.GL_GREATER, 0);

    // ...
    // bind texture and create vertices
    // ...
}

Tenga en cuenta el uso de GL_ALPHA_TEST, y glAlphaFunc.

Nick Bolton
fuente
También resolvió mi problema. Gracias por compartir. Eres genial
Mathlover
2

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.

Lutero
fuente
1
Creo que dibujar cosas de atrás hacia adelante es fácil en un juego iso 2D solo cuando tienes un plano Y fijo, y el diseñador tiene el control total del mundo. Sin embargo, cuando las cosas pueden existir en cualquier parte del espacio 3D, y permite que el usuario cambie las cosas, se vuelve más complicado. Creo que usar el búfer de profundidad hará que mi vida sea mucho más fácil.
Nick Bolton