So, nun folgt endlich der nächste Artikel zum Thema Computergrafik. Der letzte Artikel hat sich damit beschäftigt, wie mit Hilfe einfacher mathematischer Methoden ein gefülltes Dreieck auf den Bildschirm gezeichnet werden kann. Eine wichtige Sache fehlte dabei allerdings, nämlich die Einfärbung der Dreiecke zur Darstellung von Oberflächeninformationen – und darum soll es heute gehen.

Die einfachste Form der Einfärbung ist natürlich, beim Füllen der Dreiecke kein modisches Grau als Farbe zu verwenden, sondern eine beliebige andere Farbe. Viel gekonnt hat man damit allerdings nicht; aus einem Objekt mit grauen Dreiecken wird dann beispielsweise ein Objekt mit blauen Dreiecken – das ist nur in wenigen Fällen eine Verbesserung.

Hilfreicher wäre es dagegen, wenn jedes Dreieck mit einer anderen Farbe eingefärbt werden könnte. Auch das ist relativ leicht umsetzbar; hierfür wird für jedes Dreieck neben seinen 3 Eckpunkten noch die Information gespeichert, in welcher Farbe es eingefärbt werden soll. Beim Zeichnen eines Objektes muss nun lediglich die entsprechende Information beim Füllen der einzelnen Dreiecke berücksichtigt werden. Das könnte zum Beispiel im Ergebnis dann so aussehen:

Man sieht allerdings: so wirklich schön ist das nicht. Zwischen den verschiedenen Dreiecken gibt es nun harte Kanten, bedingt dadurch, dass jedes Dreieck eine einzige Farbe hat. Bei genügend großer Anzahl an Dreiecken würden diese Kanten zwar immer weniger auffallen, aber für eine ansehnliche Einfärbung (wie zum Beispiel hier zu sehen) bräuchte man eine derart große Anzahl an Dreiecken, dass selbst auf moderner Hardware keine größeren Szenen dargestellt werden könnten. Ein anderes Verfahren muss also her.

Die gängige Möglichkeit zur Einfärbung von Dreiecken ist Interpolation von Farben. Hierbei wird nicht mehr eine einzige Farbinformation pro Dreieck gespeichert, sondern für jeden Eckpunkt eine eigene Farbe definiert. Beim Füllen eines Dreiecks wird nun nicht eine einzige Farbe für das gesamte Dreieck verwendet, sondern zwischen den Farben der drei Eckpunkte interpoliert, das heißt, jeder Pixel des Dreiecks wird in Abhängigkeit zur Entfernung zu den Eckpunkten entsprechend eingefärbt. Für ein einzelnes Dreieck würde das Ergebnis also so aussehen:

Teilen sich zwei Dreiecke einen oder gemeinsame Eckpunkte (und damit auch die darin gespeicherten Farbinformationen), gibt es an den Berührungspunkten der beiden Dreiecke keine harte Farbkante mehr, sondern einen sanften Farbverlauf. Bezogen auf ein komplexeres Objekt könnte man also das folgende Bild erreicht werden:

Das sieht ja nun schon ganz brauchbar aus. Trotzdem sieht es natürlich noch nicht nach dem aus, was man an grafischer Darstellung aus gängigen 3D-Spielen gewohnt ist – es fehlen nach wie vor die Details bei der Darstellung. Zwar könnte man auch hier durch eine immense Erhöhung der Anzahl der Dreiecke mehr Oberflächendetails darstellen, aber der Rechenaufwand hierfür ist einfach zu groß (und das Ergebnis würde zweifelhaft bleiben). Es ist also nach wie vor ein besseres Verfahren zur Darstellung von Oberflächeninformationen nötig.

Die Methode der Wahl ist hier das sogenannte Texture Mapping. Bei diesem Verfahren wird ein Dreieck nicht einfach nur anhand der Eckpunkt-Farben eingefärbt, sondern es wird ein 2-dimensionales Bild – die Textur – auf das Dreieck gelegt. Dieses Bild enthält dabei benötigten Farbinformationen, um die gewünschte Oberflächenstruktur darzustellen. Zur Abbildung des Bildes auf das Dreieck – das Mapping – werden nun die drei Eckpunkte des Dreiecks auf drei Punkte im Bild projiziert und die dazwischenliegenden Farbinformationen – die Punkte des Bildes, sogenannte Texel – auf das Dreieck übertragen. Im einfachsten Fall erfolgt das Mapping immer nach einem festen Schema, bei dem zum Beispiel die linke untere Ecke des Bildes mit dem ersten Eckpunkt des Dreiecks, die rechte untere Ecke des Bildes mit dem zweiten Eckpunkt und der mittlere Punkt oben mit dem dritten Eckpunkt assoziiert wird. Das könnte dann z.B. so aussehen (links: die Textur mit darauf projiziertem Dreieck, rechts: das texturierte Dreieck):

Die Nachteile dieser Methode liegen auf der Hand: zum einen würde man so für jedes Dreieck ein eigenes Bild benötigt, von dem dann auch noch immer nur die Hälfte ausnutzen kann. Das wäre natürlich eine enorme Verschwendung von Speicherplatz und gleichzeitig ein ziemlich großer Aufwand, um komplexere Objekte mit Oberflächendetails zu versehen. Das Mapping der Bilder auf die Dreiecke muss also anders erfolgen. Zu diesem Zweck bedient man sich in der Praxis der Texturkoordinaten.

Vereinfacht gesagt sind Texturkoordinaten ganz ähnlich zu den bereits bekannten dreidimensionalen Koordinaten der Eckpunkte der Dreiecke, mit dem Unterschied, dass sie keine Position in der Welt beschreiben, sondern eine Position auf der Textur; dementsprechend sind sie auch nicht dreidimensional, sondern es reichen 2 Werte, einer für die Breite und einer für die Höhe (es gibt auch dreidimensionale Texturkoordinaten, wenn etwa volumetrische oder prozedurale Texturen zum Einsatz kommen – das soll an dieser Stelle aber nicht weiter interessieren). Über die Texturkoordinaten kann also angegeben werden, auf welche Positionen in der Textur die 3 Eckpunkte eines Dreiecks projiziert werden sollen. Damit können viele Dreiecke über ein einziges Bild effektiv eingefärbt und zudem der ungenutzte Platz in einem Bild minimiert werden. Texturkoordinaten werden üblicherweise im Intervall [0,1] angegeben, wobei der Punkt (0,0) z.B. die linke obere und der Punkt (1,1) die rechte untere Ecke der Textur markiert (das ist allerdings kein festes Gesetz und kann in der Praxis auch anders definiert sein); üblicherweise werden Texturkoordinaten mit den Variablen u und v (und w, wenn es 3 davon gibt) bezeichnet, analog zu x, y und z der Positions-Koordinaten – man spricht daher auch vom UV-Mapping.

Auch hierzu ein kleines Beispiel; die folgende Abbildung zeigt die bereits bekannte Textur, auf die mehrere Dreiecke projiziert wurden, die zusammengesetzt einen Würfel ergeben würden:

 

Wendet man diese Projektion nun beim Zeichnen des Würfels an, so erhält man (ungefähr – das Mapping ist hier nicht ganz exakt, was aber dem Beispiel keinen Schaden tut) das folgende Bild:

 

Dem aufmerksamen Beobachter fällt natürlich auch hier die harte Kante in der Textur des Würfels an seinem oberen Rand auf;  die ist durch die Projektion der Dreiecke auf die Textur bedingt (die Dreiecke liegen in der Textur ja nicht alle direkt nebeneinander) und es ist die Aufgabe des Modellierers (also desjenigen, der die Objekte erstellt), dafür zu sorgen, dass die Textur passend auf das Objekt projiziert wird.

Damit wissen wir nun endlich, wie man nicht nur die Geometrie auch komplexer Objekte darstellt, sondern auch, wie man die Objekte mit geeigneten Oberflächenstrukturen versieht. Damit möchte ich prinzipiell die Serie zur Computergrafik auch vorerst abschließen. Wenn allerdings noch Wünsche zu bestimmten Themen aus diesem Themenkomplex bestehen, so können die natürlich gern in den Kommentaren gepostet werden.

Ansonsten geht es das nächste mal (hoffentlich) mit einem mindestens ebenso spannenden Thema weiter. Um einen Hinweis zu geben: es wird um die Frage gehen, wie die Informatik genutzt werden kann, um wissenschaftliche Theorien zu untersuchen.

Kommentare (6)

  1. #1 camil7
    September 22, 2012

    Danke für die Artikelserie! Was mich noch interessieren würde, ist, wie bei mehreren (eventuell bewegten) Objekten/Flächen sich feststellen lässt, wann ein Dreieck eines Objektes hinter dem anderen liegt, also gar nicht dargestellt werden braucht. (Mit dem “bewegt” meine ich nur, dass es dann bei der Berechnung eines Frames recht schnell gehen sollte – und ausserdem lässt sich eventuell die Information eines Frames in das nächste herüberretten von wegen “das Dreieck ist so weit von dem vorderen Objekt überdeckt, das kommt so schnell nicht dahinter vor, also schauen wir erst fünf Frames später wieder nach.)
    Außerdem, ob es bei überlappenden Flächen (eine hintere Fläche wird nur teilweise von einer vorderen überdeckt) inzwischen ein besseres Verfahren gibt, die “hintere” Fläche darzustellen, ausser “wir zeichnen erstmal die hintere Fläche komplett in den Buffer, und überschreiben den überdeckten Teil mit der vorderen Fläche.

  2. #2 Marcus Frenkel
    September 22, 2012

    Das klingt schon fast nach fortgeschritteneren Themen, zumindest die 2. Frage. 😉
    Ich werde sehen, was sich machen lässt.

  3. #3 Stefan W.
    September 24, 2012

    Das sogenannte Wort “sogenannt” hilft beim Verstehen der gar nicht. Es suggeriert, dass der Name irgendwie unpassend ist, wie dies gelegentlich für “der sogenannte Arbeitnehmer” getan wird. Wieso eine “sogenannte” Textur? Wie würdest Du das nennen?

    Einfach weglassen das Wort. Ob der Leser das Wort schon kennt oder nicht weißt Du eh nicht, und jedes neue Wort mit einem “sogenannt” zu dekorieren wirkt doch bloß einfallslos.

  4. #4 Marcus Frenkel
    September 24, 2012

    Das Wort “sogenannt” hat neben der in den heutigen Medien meist negativ konnotierten Bedeutung auch noch eine (seine ursprüngliche) Bedeutung, nämlich den Sinn, die Bezeichnung eines Dinges oder Vorganges anzukündigen. In unserer zynischen Kultur ist diese Bedeutung wohl aber langsam aber sicher auf dem Rückzug…

    Aber ja, es wurde etwas häufig verwendet im aktuellen Artikel. Er wurde angepasst.

  5. #5 Sim
    September 29, 2012

    Interessant ist: So ein Dreieck als zweidimensionales Gebilde welches aber eingebettet in einen dreidimensionalen Raum ist und von diesem aus, auf den Bildschirm projeziert wird, ist ja mehreutig. Ein und das selbe Dreieck welches auf dem Bildschirm angezeigt wird, kann ja verschiedene Tiefeninformationen besitzen. Die Punkte des Dreiecks müssen also nicht alle notwendigerweise auf der Bildschirmebene oder auf einer Ebene parallel zum Bildschirm liegen sondern können da ganz verschieden sein. Und diese Information muss man berücksichtigen, wenn man die Dreieckspunkte auf die Texel abbildet. Sonst sieht die Textur verzerrt aus. Das ist nämlich nem Kumpel von mir mal passiert, als wir solche 3D-Modelle mal von Hand programmiert hatten. Also obacht ^^

    Ansonsten schöne Serie Marcus. Ich hätt gern noch einiges mehr dazu gelesen. Phongshading wär ja auch noch eine interessante Sache. Und Transformationsmatrizen und Verdeckungsberechnung oder Raytracing. Ist doch total spannend 😀

  6. #6 Marcus Frenkel
    September 29, 2012

    @Sim
    Ja,das wäre dann die Perspektivenkorrektur beim Texture Mapping. Ich wollte nur nicht zu sehr ins Detail gehen – ist ja immerhin hier ein Wissenschaftsblog und kein Informatik-Blog. 😉

    Transformatationsmatrizen kamen in einem früheren Teil der Serie schon (teilweise) dran, allerdings auch ohne die genauen mathematischen Details (gleiche Begründung). Verdeckungsberechnung wurde schon gewünscht, Shading kann ich auch noch machen.
    Raytracing…mal sehen. Darüber wurde auch schon diskutiert, eventuell mache ich da auch noch einen Artikel irgendwann.