Wie verwende ich Tiefentests und Texturtransparenz zusammen in meiner 2.5D-Welt?

11

Hinweis: Ich habe bereits eine Antwort gefunden (die ich nach dieser Frage veröffentlichen werde). Ich habe mich nur gefragt, ob ich es richtig gemacht habe oder ob es einen besseren Weg gibt.

Ich mache ein isometrisches "2.5D" -Spiel mit OpenGL ES (JOGL). Mit "2.5D" meine ich, dass die Welt 3D ist, aber mit isometrischen 2D-Kacheln gerendert wird.

Das ursprüngliche Problem, das ich lösen musste, war, dass meine Texturen in der richtigen Reihenfolge (von hinten nach vorne) gerendert werden mussten, damit sich die Kacheln richtig überlappten, um den richtigen Effekt zu erzielen. Nach einigem Lesen wurde mir schnell klar, dass dies der "alte Hut" 2D-Ansatz ist. Dies wurde schwierig, da die 3D-Welt vom Player geändert werden kann (so dass überall im 3D-Raum Dinge angezeigt werden können) - daher schien es logisch, dass ich den Tiefenpuffer nutze. Dies bedeutete, dass ich mich nicht darum kümmern musste, die Dinge in der richtigen Reihenfolge zu rendern.

Ich hatte jedoch ein Problem. Wenn Sie GL_DEPTH_TESTund GL_BLENDzusammen verwenden, wird ein Effekt erzeugt, bei dem Objekte mit dem Hintergrund gemischt werden, bevor sie nach z-Reihenfolge "sortiert" werden (was bedeutet, dass Sie eine seltsame Art von Überlappung erhalten, wo die Transparenz sein sollte).

Transparenzüberlappungsproblem

Hier ist ein Pseudocode, der das Problem veranschaulichen soll (ich verwende übrigens libgdx für 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
    // ...
}

Die Frage ist also: Wie löse ich das Problem der Transparenzüberlappung?

Nick Bolton
quelle
2
Nur ein Kommentar, um Ihnen zu sagen, dass ich für meine 2D-Engine genau den gleichen Weg wie Sie gegangen bin: Zuerst habe ich versucht, klug zu sein und selbst K-sortierte Kacheln zu erstellen, dann wurde mir klar, dass es keinen Grund gibt, warum die Szene flach sein sollte, und meine Kacheln mit a versehen Z-Koordinate und Aktivierung des Alpha-Tests. Ich bin mir nicht sicher, ob du Recht hast, aber du bist nicht allein :-)
Sam Hocevar

Antworten:

7

OK, hier ist meine Lösung (bitte kommentieren Sie, ob es besser geht) ...

Es stellt sich heraus, dass ich tatsächlich Alpha-Tests verwenden sollte (obwohl ich dies zufällig entdeckt habe, bin ich mir nicht ganz sicher, warum es funktioniert).

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
    // ...
}

Beachten Sie die Verwendung von GL_ALPHA_TESTund glAlphaFunc.

Nick Bolton
quelle
Es hat auch mein Problem gelöst. Danke für das Teilen. Sie sind großartig
Mathlover
2

Alpha-Tests werden verwendet, um zu verhindern, dass der Renderer Pixel in einen beliebigen Puffer zeichnet, einschließlich des z-Puffers. Alpha-Blending ist nur eine visuelle Sache - Werte werden immer noch in den Z-Puffer geschrieben, was zu solchen Problemen führen kann - unsichtbare Pixel befinden sich vor anschließend gerenderten Pixeln, was bedeutet, dass sie den Z-Test beim Zeichnen der neuen Pixel nicht bestehen. Dies ist, was Sie in dem Bild sehen können, das Sie gegeben haben, ein ztest fehlgeschlagen.

Wenn Sie das z-Schreiben ausschalten, werden auch die gleichen Ziele erreicht, aber Sie müssen sicherstellen, dass Sie alles in die vordere Reihenfolge zurückziehen. Dies sollte in Ihrem isometrischen Spiel einfach genug sein.

Luther
quelle
1
Ich denke, dass das Zeichnen von Sachen von hinten nach vorne in einem 2D-ISO-Spiel nur dann einfach ist, wenn Sie eine feste Y-Ebene haben und der Designer die volle Kontrolle über die Welt hat. Wenn jedoch irgendwo im 3D-Raum etwas vorhanden sein kann und Sie dem Benutzer erlauben, etwas zu ändern, wird es komplizierter. Ich denke, die Verwendung des Tiefenpuffers wird mein Leben viel einfacher machen.
Nick Bolton