Texelgenaue Texturkoordinate: Unterschied zwischen den Versionen
K (Überschriften-Markup repariert) |
K (Tabellenmarkup verbessert) |
||
Zeile 44: | Zeile 44: | ||
{|{{Prettytable_B1}} width="100%" | {|{{Prettytable_B1}} width="100%" | ||
− | !Kriterium | + | !Technik / Kriterium |
!Kein ''bleeding'' | !Kein ''bleeding'' | ||
!Pixelgenaue Darstellung bei 1:1 Rendering | !Pixelgenaue Darstellung bei 1:1 Rendering | ||
!Mipmap-Kompatibilität | !Mipmap-Kompatibilität | ||
|- | |- | ||
− | |Normal | + | ! style="text-align:left" |Normal |
|✘ | |✘ | ||
|✔ | |✔ | ||
|✔ | |✔ | ||
|- | |- | ||
− | |Lösung 1: Ausschnitt verkleinern | + | ! style="text-align:left" |Lösung 1: Ausschnitt verkleinern |
|✔ | |✔ | ||
|✘ | |✘ | ||
|✔ | |✔ | ||
|- | |- | ||
− | |Lösung 2: Rahmen hinzufügen | + | ! style="text-align:left" | Lösung 2: Rahmen hinzufügen |
|✔ | |✔ | ||
|✔ | |✔ |
Version vom 27. Mai 2014, 14:04 Uhr
Texelgenaue Texturkoordinaten werden immer dann gebraucht, wenn man mehrere Bilder in einer Textur hat, z.B. bei einer Tilemap oder wenn man zur Laufzeit einen dynamischen Texturatlas erzeugt.
Inhaltsverzeichnis
Anwendungsgebiet
Ein häufiges Anwendungsgebiet ist wie schon erwähnt das Addressieren von Texturen in einem Texturatlas. Dazu muss man Pixelgenau die einzelnen Teilbilder herausschneiden, um sie auf Objekten anzubringen.
Wenn der Ausschnitt die Pixel im Rechteck x0..x1, y0..y1 abdeckt, dann ist die intuitive Methode um die Texturkoordinaten u0,u1,v0,v1 für eine Textur der Breite w und Höhe h zu erhalten:
u0 = x0 / w u1 = x1 / w v0 = y0 / h v1 = y1 / h
Problematik
Diese Koordinaten bergen allerdings Probleme in sich, sobald man einen anderen Texturfilter als GL_NEAREST verwendet und die Texel nicht 1:1 auf Pixel übertragen werden (also irgendeine Form der Skalierung der Textur statt findet).
Dann kommt es zu bleeding-Effekten, bei denen die nebenanliegenden Texturen in das gewollte Bild reinblenden. In dem Beispiel oben wurde das zweite Tile von links ganz unten (64 px×64 px) auf ein Quad welches mit 256 px×256 px gerendert wurde mit GL_LINEAR aufgebracht. Man kann deutlich erkennen wie die nebenanliegenden Tiles in das Tile hineinbleeden.Lösung 1: Texturaddressierung verändern
Eine Lösung für dies, die oft genannt wird, ist, den Rahmen der Texturaddressierung in die mitte der Texel zu legen. Dazu addiert bzw. subtrahiert man von den Texturkoordinaten einen halben Texel:
u0 = (x0 + 0.5) / w u1 = (x1 - 0.5) / w v0 = (y0 + 0.5) / h v1 = (y1 - 0.5) / h
Dann liegen die Ränder des angezeigten Quads genau auf der Texelmitte, es findet also keine Überblendung mit nebenanliegenden Tiles statt. Dieser Ansatz hat allerdings ein anderes Problem: Die Texturen verschwimmen schon bei einer 1:1 Abbildung, wie im Screenshot rechts zu sehen.
Lösung 2: Rahmen hinzufügen
Man kann den bleeding-Effekt auch beheben, indem man einen 1 px Rahmen um die Texturen im Atlas hinzufügt, welcher die Farbe des anliegenden Texturpixels hat (und in den Ecken eventuell eine lineare Überblendung). Obiges Bild demonstriert, dass dies das Problem löst.Allerdings hilft diese Lösung nicht, wenn man (automatisch generierte) Mipmaps verwendet. Dafür muss man den Rahmen für jedes Mipmap-Level verdoppeln, was ab einem gewissen Mipmap-Level zu viel Platz benötigt. Oft ist es allerdings so, dass man, wenn man Mipmaps braucht (also unterschiedliche Skalierungen einer Textur anzeigen will) sowieso keine pixelgenaue Darstellung benötigt.
Zusammenfassung
Technik / Kriterium | Kein bleeding | Pixelgenaue Darstellung bei 1:1 Rendering | Mipmap-Kompatibilität |
---|---|---|---|
Normal | ✘ | ✔ | ✔ |
Lösung 1: Ausschnitt verkleinern | ✔ | ✘ | ✔ |
Lösung 2: Rahmen hinzufügen | ✔ | ✔ | ✘ |