Texel Berechnung

Aus DGL Wiki
Wechseln zu: Navigation, Suche

Es gibt mehrere Unterschiedliche Arten wie Texturen verwendet werden können. Beispielsweise:

  1. Eine Textur = ein Bild: User Interface, Partikel, ...
  2. Wiederholen von Texturen: Zylinder, Kugeln, Detailtexturen, Wasser, wiederholendes Hintergrundbild
  3. Tiling, mehrere Texturen zusammen setzen: Iso-Engines, Farbtexturen bei Landschaften, zusammengesetzte Bilder (zB Hintergrund)

OpenGL sollte möglichst alle Bedürfnisse erfüllen und dennoch möglichst simpel sein. Bei der Anforderung nur eine Textur zu zeichnen stößt man sehr schnell auf das Bedürfniss, dass alle Texel einer Textur gleich viel Einfluss auf die Textur nehmen. Das heißt der Einflussbereich eines jeden Texels sollte genau 1/Texturgröße sein.
Für die 2te Anforderung (das wiederholen von Texturen) erwartet man eine (lineare) Interpolation des ersten und des letzten Texels einer Textur.
Für die 3te Art der Verwendung von Texturen benötigt man ohnehin einzelne Quads, wodurch es eher egal ist wie die Textur aufgeteilt wird, solange eine Interpolation zwischen 2 unterschiedlichen Texturen möglich ist.

In diesem Artikel wird darauf eingegangen wie OpenGL alle 3 Bedürfnisse erfüllt und natürlich auch was die für den Programmierer bedeutet.

Die Textur Koordinaten

OpenGL generiert aus einem 3eck mehrere Texel. Jedes Texel erhält eine ein (oder mehr) Dimensionale Texturcoordinate im Wertebereich [0|1]. Die Texturcoordinate(n) können beliebig sein, der Programmierer gibt jedoch nur einzelne Werte mitteln glTexImage2D vor. Nun muss OpenGL für die nicht angegebenen S-Koordinaten Farbwerte finden. Das finden des Farbwertes für eine S-Koordinate ist somit eine Funktion einer Texturcoordinate im Bereich [0|1] zu einem entsprechenden Farbwert bei dem X Werte bekannt sind (X ist hierbei die Texturbreite). Gleiches gilt für die t-, r- und ggf. die q- Koordinaten. Wie die anderen Werte gefunden werden hängt von verschiedenen Textur-Parametern ab. Hier wird nur auf die S-Koordinate eingegangen, jedoch gilt das selbe Prinzip auch für alle anderen Koordinaten (t, r und q) bzw. Dimensionen (2te, 3te und 4te).

GL_NEAREST

GL_NEAREST ist der Fall wo es am offensichtlichsten ist, dass jedes Texel gleich viel Einfluss nehmen sollte. Bei einer Textur die 2 Texel breit ist, sollte das linke Texel den Wertebereich [0|0,5] abdecken und das rechte Texel den Wertebereich [0,5|1] abdecken. Damit dies möglich ist, musst sich das Zentrum des Texels natürlich im Zentrum des entsprechenden Wertebereiches befinden. Bei 2 Texel Breite befindet sich also das linke Texel an der Position 0,25 und das rechte Texel an der Position 0,75. Dies ist unumgänglich für den ersten unserer Anwendungsfälle und ist förderlich für den dritten.

GL_LINEAR

GL_LINEAR liefert schönere Ergebnisse wenn die Textur zu klein geraten ist. Um den zweiten Anwendungsfall erreichen zu können müssen jedoch das erste und das letzte Texel ebenfalls Interpoliert werden. Dies wiederspricht sich glücklicherweise nicht mit GL_NEAREST und den anderen beiden Anwendungsfällen, jedoch folgt aus der Beobachtung, dass bei einer 2 Texel breiten Textur der erste Wert für 0.25 gegeben wurde und der zweite Wert für 0.75, dass sowohl die Texturkoordinate 0.0 als auch die Texturkoordinate 1.0 eine lineare Interpolation des ersten und des zweiten Texels ist. Dies hindert uns jedoch nicht daran beispielsweise 10 Wiederholungen ein und derselben Textur zu machen indem wir Texturkoordinaten von 0.0 und 10.0 angeben. Jedoch ist dies sehrwohl für die beiden anderen Anwendungsfälle von Bedeutung.

GL_CLAMP

Bei GL_CLAMP wird die S-Koordinate im Bereich von [-Unendlich|+0,5/Breite] durch das linkeste Texel ersetzt und der Wertebereich von [1-(0,5/Breite)|+Unendlich] durch das rechteste Texel ersetzt. Gleiches gilt für die Tiefe und T-Koordinate bzw. Tiefe und R-Koordinate. Bei GL_NEAREST wird aufgrund der Funktion "Wähle nähesten gegebenen Wert zu S-Koordinate" natürlich der Bereich [-Unendlich|1/Breite] vom linkesten Texel abgedeckt, bzw. der Bereich [1-(1/Breite)|+Unendlich] vom rechtesten Texel abgedeckt. Dies hilft uns ggf. beim ersten Anwendungsfall, sofern es erwünscht ist, dass die Randtexel den Rand abdecken und nicht interpoliert werden. GL_LINEAR entspricht einem

if( Texturkoordinate < 0 )
 Texturkoordinate = 0
else if (Texturkoordinate > 1 )
 Texturkoordinate = 1

GL_REPEAT

Bei GL_REPEAT wurde auf diejenigen Rücksicht genommen die keine einzelnen Quadrate für jede Texturwiederholung zeichnen möchten. Dies ist natürlich insbesondere für den 2ten Fall der Anwendung wichtig, da ansonnsten enorme Performance einbusen bezüglich der Vertex- bzw. 3ecks-Anzahl in kauf genommen werden müssten. Bei der Wiederholung von Texturen ist es sehr hilfreich wenn man ein Quadrat zeichen kann, dessen Texturkoordinaten beispeilsweise links 0.0 und rechts 10.0 sind und die Textur 10 mal wiederholt wird, anstatt 10 Quadrate zu zeichen (im 2D-Texturen Fall 100 Quadrate). Bei GL_REPEAT wird das linkeste Texel mit dem rechtesten Texel genau so interpoliert wie alle anderen Texel, und die Texturen werden wiederholt. Dies entspricht einem

Texturkoordinate = Texturkoorinate modulo 1

Beispiele

Alle Beispielbilder wurden mit einer Textur mit 4 Texeln erstellt.

TexturkoordinateNearestClamp.PNG
GL_NEAREST und GL_CLAMP

TexturkoordinateNearestRepeat.PNG
GL_NEAREST und GL_REPEAT

TexturkoordinateLinearClamp.PNG
GL_LINEAR und GL_CLAMP

TexturkoordinateLinearRepeat.JPG
GL_LINEAR und GL_REPEAT

Texturkoordinatenberechnung

Wie aus der obigen Beschreibung und den Beispielen ersichtlich sein sollte, werden die Werte die bei glTexImage2D angegeben wurden für die S-Werte:

0,5/Breite + Texel/Breite

angegeben.