OpenGL - weiße Kanten an Würfeln

12

In einem Minecraft-ähnlichen Spiel bekomme ich weiße Ränder auf meinen Würfeln:

Bildbeschreibung hier eingeben

Bei dunkleren Texturen macht sich dies deutlich bemerkbar. Die Texturen werden wie folgt eingerichtet: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Irgendeine Hilfe?

Luis Cruz
quelle
3
Können Sie Code zeigen, wie Sie die einzelnen Würfel rendern und wie Sie die Würfel platzieren?
Joncodo
1
Verändert sich das Umwickeln der Texturen? Wie sieht die Textur / Größe aus, an die Sie binden?
Chuck D
Ich wollte nur darauf hinweisen, dass ich gesehen habe, dass dies auch in großen Texturatlanten geschieht, die kleine Kacheln verwenden. Angenommen, Sie haben ein 1024 * 1024-Kachelset / Atlas und verwenden Kacheln mit 32 * 32. Sie erhalten Rundungsfehler, weil der Dezimalpunkt, der dieser Kachel zugeordnet ist, ein sehr kleines Doppel ist. Dies macht Präzision nahezu unmöglich. Eine Lösung? Teilen Sie den Fliesenatlas in einzelne Fliesen auf. Dies ist, was Minecraft tut oder früher tat. Sie hatten ein großes Tileset und zur Laufzeit haben sie es in einzelne Texturen zerlegt.
Krythic

Antworten:

19

Es gibt zwei mögliche Ursachen für diese Art von Problem, abhängig davon, um welches Problem es sich handelt. Ich werde beide auflisten:

1. An den Rändern der Kacheln sehen Sie andere Farben aus Ihrer Textur.

Dies scheint mir das Problem in diesem Fall zu sein, da alle Kantenpixel eine von drei Farben sind, die in Ihrer Textur plausibel sind: Weiß, Schwarz und Braun.

Wenn Sie mehrere Kachelbilder direkt nebeneinander in einer einzelnen Textur (einem Texturatlas) verwenden, wie ich es nehme, ist dies unvermeidlich. Dies liegt daran, dass die GPU die Interpolation entlang der Kante eines Dreiecks nicht perfekt mit der Interpolation entlang der Textur in Einklang bringt und Sie kleine Teile der benachbarten Textur erhalten.

Es gibt eine Reihe von Dingen, die Sie tun können.

  • Verwenden Sie eine Array-Textur anstelle eines Texturatlas. Eine Array-Textur besteht aus einem Stapel von 2D-Bildern derselben Größe, und Sie geben eine dritte Koordinate an, um eine auszuwählen. Es ist genau als Ersatz für Texturatlanten ohne Filterproblem gedacht. Array-Texturen sind jedoch eine neuere Funktion, die in der von Ihnen verwendeten OpenGL-Version möglicherweise nicht verfügbar ist.
  • Generieren Sie in jeder Ihrer Texturkacheln einen Rand von 1 Pixel, der die Farbe des benachbarten regulären Pixels repliziert. (Dies implementiert im Wesentlichen die GLs neuCLAMP[_TO_EDGE] , jedoch in einer Weise, die Texturatlanten berücksichtigt - Ihre Verwendung hat keine Auswirkung, da sich die meisten Ihrer Kachelkanten nicht am Rand der Textur befinden.) Dies ist die Lösung, die ich in meinem eigenen Eintrag verwende im Genre Würfel . Ich kenne keine besonderen Nachteile, außer dass mehr Texturspeicher verwendet wird.
  • Setzen Sie Ihre Texturkoordinaten ganz leicht ein, damit sie nicht bis zum Rand der Texturkachel reichen. Wenn Sie zu viel tun, werden die Kanten der Textur im Vergleich zu Pixeln in der Mitte deutlich dünner.
  • Verwenden Sie eine einzelne Textur pro Kacheltyp. Dies verursacht Texturwechselkosten.

2. Sie sehen durch Lücken zwischen Kacheln.

Ich denke nicht, dass dies das Problem in diesem Fall ist, da durch die Lücken kein grüner Grund zu sehen ist, aber der Vollständigkeit halber beziehe ich ihn ein.

Dies kann auftreten, wenn Sie nicht genau die gleichen Koordinaten für die Eckpunkte der Meeting-Kanten benachbarter Kacheln angeben, was normalerweise auf Gleitkommafehler zurückzuführen ist. Wenn Sie beispielsweise Kacheln der Größe 0,6 haben und den rechten Rand der Kachel x=100mit (100*0.6) + 0.6und den linken Rand der Kachel x=101mit berechnen (100*0.6), erhalten Sie nicht die exakt gleiche Antwort, und der Unterschied kann als kleine Flecken von sichtbar sein Lücken.

Die Lösung besteht darin, sicherzustellen, dass Ihre Arithmetik konsistent ist. Einige Möglichkeiten, dies zu tun, sind:

  • Stellen Sie sicher, dass Sie nicht (auch nur indirekt) rechnen index*size + size, sondern nur (index+1)*size.
  • Stellen Sie sicher, dass Ihre Arithmetik exakt ist. Der einfachste Weg, dies zu tun, besteht darin, die Kachelgröße auf genau 1,0 zu setzen. Dies führt zu einer exakten Ganzzahlarithmetik, selbst wenn Sie mit 32-Bit-Gleitkommazahlen rechnen (ohnehin bis zu 16 Millionen Blöcke vom Ursprung entfernt).
  • Verwenden Sie für die Berechnung der Scheitelpunktkoordinaten tatsächliche Ganzzahlen. das bringt dir noch mehr reichweite.
Kevin Reid
quelle
Sieht für mich nach Lücken aus - keine Texturblutung (es sei denn, es handelt sich um eine ziemlich hochauflösende Textur), wenn man die winzigen und scharfen Stellen berücksichtigt.
Mario
Vielen Dank, dass Sie die Texturkoordinaten ein wenig verschoben haben, um das Problem zu beheben.
Luis Cruz
@ Mario Ich nehme an, dies ist mit der NÄCHSTEN Vergrößerung - beachten Sie den scharfen Rand auf der Innenseite der Kachel. Für diese Perspektive ist es also eine Textur mit unendlicher Auflösung.
Kevin Reid
Sie können auch ein Texturarray verwenden, um Kosten zu vermeiden.
Danijar