Schulfächer
Gefällt dir Schulzeug.at?
| 3D Grafik |
|
|
| Autor: unbekannt |
| Wörter: 5322 |
|
Inhaltsverzeichnis:
10. TRANSFORMATIONEN 11. DRAHTMODELLE 12. GLASKÖRPER 13. HIDDEN LINES 14. LICHTQUELLEN-SCHATTIERUNG 15. TEXTUREN 16. BIBLIOGRAPHIE
Ebenfalls 1981 kam der CGA (Color Graphics Adapter) auf den Markt. Diese Karte konnte, wegen der niedrigen Frequenzen, noch über einen speziellen Ausgang an einen normalen Fernseher angeschlossen werden. Im Textmodus schaffte der CGA, genau wie MDA, 80 x 25 Zeichen, die aber auf einer kleineren Punktmatrix basierten. An Grafikmodi standen 320 x 200 (Punkte) x 4 (Farben) sowie 640 x 200 x 2 zur Verfügung. MDA und CGA basierten auf dem MC6845 von Motorola. 1982 erschien die weitestgehend zum MDA kompatible Hercules Graphics Card. Sie konnte zusätzlich noch zwei Grafikseiten bei einer Auflösung von 720 x 348 monochrom darstellen. Diese Karte war sehr einfach zu programmieren und verfügte auch über eine parallele Schnittstelle. Sie stellt heute den Monochrom-Standard dar. 1985 wurde der EGA (Enhanced Graphics Adapter) vorgestellt. Er ist voll kompatibel zu MDA und CGA und kann monochrome und farbige Grafiken darstellen. Im Grafikmodus schafft die EGA-Karte bei 640 x 350 Punkten 16 Farben gleichzeitig aus einer Palette von 64. Der Video-RAM ist standardmäßig 64 KB groß, die Karte kann aber mit bis zu 256 KB bestückt werden, um mehrere Grafikseiten im Speicher unterzubringen. Das Bild ist wesentlich schärfer als bei einer CGA-Karte, außerdem kann der EGA mit variablen Schriftsätzen arbeiten. Erstmals hat die EGA-Karte ein eigenes ROM-BIOS onboard, um den Zugriff auf die erweiterten Leistungsmerkmale zu erleichtern, auch wenn die Programmierung über ROM-Routinen langsam ist. 1987 wurde schließlich der VGA (Video Graphics Array) vorgestellt, der wiederum zu allen seinen Vorgängern kompatibel ist. Die VGA-Karte ist heute Standard und der kleinste gemeinsame Nenner, zu dem alle SVGA-Karten kompatibel sein müssen. Der VGA sendet erstmals ananloge Signale an den Monitor, was eine große Farbenvielfalt ermöglicht. Die höchste Standardauflösung ist 640 x 480 x 16, im Mode 13h können bei 320 x 200 Bildpunkten 256 Farben gleichzeitig aus einer Palette von 262.144 dargestellt werden. Dieser Modus diente ursprünglich der Kompatibilität zu MCGA, wobei der VGA mit einem Trick durch Setzen von zwei Registern die tatsächliche Auflösung von 640 x 400 halbiert. Grafikprofis verschafften sich dadurch bald durch Löschen der beiden Register einen sehr einfachen hochauflösenden Modus. Ursprünglich wurden VGA-Karten mit 256 KB Video-RAM bestückt, heute sind aber auch 8 MB keine Seltenheit mehr. Diese Karten sind sämtlich bereits SVGA (Super VGA) -Karten, die erweiterte Möglichkeiten bieten, die aber leider nicht genormt sind. Die Auflösungen reichen bis 1600 x 1200 Bildpunkte, bei bis zu 16,7 Millionen Farben gleichzeitig. Dabei sind bei Karten der Luxusklasse Bildwiederholraten von bis zu 200 Hz problemlos möglich, sofern dies der Monitor verkraftet. Außerdem verfügen heute viele Karten auch schon über intelligente Grafik-Prozessoren, die eine ganze Menge zusätzliche Möglichkeiten bieten. In Verbindung mit den neuen MMX-Prozessoren (mit erweitertem Befehlssatz, speziell für Multimedia-Anwendungen) sind deshalb in naher Zukunft noch weitere Leistungssteigerungen zu erwarten. Windows-Beschleuniger erledigen die typischen Windows-Funktionen nur mehr auf der Grafikkarte, ohne den Hauptprozessor zu belasten. AVI-Beschleiniger kümmern sich speziell um die “Briefmarken-Videos” und bieten häufig auch Hardware-Zoom. MPEG-Decoder spielen MPEG-Videos ab, ohne den Prozessor zu belasten. Dabei werden Videos manchmal, speziell in Verbindung mit einer Video-Grabber-Karte, auch als Hardware-Overlays über das normale Bild gelegt. 3D-Beschleuniger bieten heute auch schon hardwaremäßige 3D-Funktionen, die komplett auf der Grafikkarte Perspektive, Schatten, Texturen, Filter und vieles mehr erledigen. Leider sind alle diese Funktionen nicht genormt. Deshalb wurde für DOS 1989 das VESA-Komitee (Video Electronics Standard Association) gegründet, das den VESA-Standard entwickelte. Dieser wird entweder über das Video-BIOS oder einen eigenen Treiber implementiert und bietet eine genormte Schnittstelle zum Zugriff auf SVGA-Karten und mit der Version 2.0 auch auf viele Zusatzfunktionen. Unter Windows stellen sich alle diese Probleme nicht, da hier einfach jeder Karten-Hersteller einen Treiber für seine Hardware mitliefert, der sich um die optimale Darstellung der Daten aus dem Windows-GDI kümmert. Fürs Programmieren werden bei Standard-VGA Teile des Video-RAMs, die über Register selektiert werden, in den konventionellen Speicher eingeblendet. Dabei liegt der Grafikbereich zwischen A000 und AFFF, der Monochrom-Textbereich (der häufig von manchen Memorymanagern verwendet wird) zwischen B000 und B7FF und der Farb-Textbereich zwischen B800 und BFFF. Auf der Grafikkarte wird die lineare Adressierung dann in eine planare umgewandelt und die Punkte abhängig von den Registereinstellungen gesetzt. Bei SVGA ist das teilweise etwas anders, zum Beispiel werden manchmal Selektoren verwendet, um Speicherbereiche zu adressieren. Da diese Methode der Grafikausgabe auch relativ langsam ist, bietet Windows 95 mit DirectX eine eigene Funktionsbibliothek, die eine direkte Ansteuerung der Hardware ermöglicht. Auch die Bibliotheken WinG und Win32s bieten einige Möglichkeiten, und Video für Windows ist bei Windows 95 gleich fix eingebaut. Für 3D-Effekte besonders wichtig ist Direct3D, ein Bestandteil von DirectX, der die Möglichkeiten spezieller 3D-Karten ausnutzt. Offset = Y * 320 + X Am entsprechenden Offset steht der Farbwert des Punktes aus der Palette. Diese bietet Platz für 256 Farben und enthält für jede den entsprechenden Rot-, Grün- und Blauwert. Da an der Punktadresse nur ein Pointer auf den Paletteneintrag steht, spart dieses Modell bei 256-Farbenmodi sehr viel Platz. VGA-intern wird die lineare Adressierung dann wieder in eine planare umgewandelt. Dazu werden Bit 0 und 1 des Offsets zur Selektion der Schreib- bzw. Lese-Plane verwendet, die restlichen sechs Bit (2 - 7) werden als physikalische Adresse innerhalb der Plane verwendet. Ein ähnliches Verfahren (Odd/Even-Adressierung) verwenden übrigens auch sämtliche Textmodi. Dabei dient Bit 0 zur Selektion zwischen Plane 0 und 1, so daß sich aus Sicht der CPU Zeichen- und Attribut-Byte jeweils direkt hintereinander befinden, intern jedoch Zeichen in Plane 0 und Attribute in Plane 1 abgelegt werden, Plane 2 und 3 dienen als Zeichensatzspeicher. Im Mode X werden bei einem Byte-Zugriff vier Pixel auf einmal kopiert, außerdem werden Read-Mode 0 und Write-Mode 1 verwendet, die weder aufwendige interne Adreßumwandlungen erfordern noch Daten an die CPU schicken, was den Geschwindigkeitsvorteil gegenüber 32-Bit-Zugriffen der CPU ausmacht. Zur Initialisierung wird der Chain-4-Mechanismus abgeschaltet, so daß wieder freier Zugriff auf einzelne Planes möglich ist, außerdem muß sichergestellt werden, daß der Odd/Even-Mode (Plane-Selektion durch unterstes Offset-Bit) ausgeschaltet ist, dazu muß nur im TS-Register 4 (Memory Mode) Bit 3 (Enable Chain4) gelöscht und Bit 2 (Odd/Even-Mode) gesetzt werden. Je nach Grafikkarte muß noch der Speicherzugriff auf Byte-Adressierung geschaltet werden, also zunächst Doubleword-Adressierung aus Bit 6 in CRTC-Register 14h (Underline Row Address) löschen und Bit 6 in CRTC-Register 17h (CRTC-Mode) setzen. Sinnvollerweise wird jetztnoch der Bildschirmspeicher gelöscht, weil an den vom Mode 13h unbenutzten Stellen, die jetzt sichtbar werden, noch Byte-Müll aus anderen Videomodi stehen kann. Am einfachsten erfolgt das über das Write Plane Mask Register 2 des Timing-Sequenzers, in dem alle Planes eingeschaltet werden, so daß 32.000 Word-Zugriffe oder 16.000 DWord-Zugriffe ausreichen, um alle vier Bildschirmseiten zu löschen. Ab nun muß man sich allerdings um alles selbst kümmern, da weder vom BIOS noch einer Hochsprache irgendwelche Unterstützung zu erwarten ist. In sämtlichen Plane-basierten Grafikmodi verbergen sich hinter einer Speicheradresse gleich 4 Byte, jeweils eins pro Plane. Die 4 Bytes liegen quasi übereinander an einer Adresse. Sie lassen sich einzeln ansprechen, werden aber parallel verwendet. Die Adressierung erfolgt allerdings gänzlich anders als in den 16-Farbenmodi. Die Punktnummer läßt sich im Mode X errechnen wie im Mode 13h, Plane und Offset lassen sich nach folgenden Formeln berechnen: Plane = X mod 4 Offset = Y * 80 + X div 4 Dieses Verfahren entspricht dem des Mode 13h, mit dem Unterschied, daß der Offset durch Shiften der Punktnummer um 2 Bit nach rechts statt durch Maskieren berechnet wird, so daß im Speicher keine Lücken zwischen den Punkten entstehen und somit vier Seiten in die 256 KB Video-RAM passen. Bei der Selektion der Plane im Mode X muß allerdings noch zwischen Schreib- und Lesezugriffen unterschieden werden: Beim Lesen wird die Plane-Nummer in Register 4 (Read Plane Select) des GDC geschrieben, beim Schreiben dagegen ist es möglich, mehrere Planes gleichzeitig anzusprechen. Daher wird eine Maske in Register 2 (Write Plane Mask) des TS gesetzt, die erst aus der Plane-Nummer erzeugt werden muß, nach folgender Formel: Maske = 1 shl Plane-Nummer Die byteweise Adressierung seitens der CPU ist notwendig aufgrund der vier Latches des VGA. Die einfachste Methode, die Tiefeninformation umzurechnen, die der Monitor ja nicht darstellen kann, ist, sie komplett zu ignorieren. Dabei werden die zweidimensionalen Koordinaten der Eckpunkte jeder Fläche aus den x- und y-Koordinaten der dreidimensionalen Definition gewonnen. Bei dieser Methode erscheinen parallele Geraden des dreidimensionalen Raums als parallele Geraden auf dem Bildschirm - daher der Name Parallelprojektion. Das hat gewisse Vorteile (und wird z. B. in der Architektur benutzt), hat aber mit der Wirklichkeit wenig zu tun; schließlich erzeugen weiter entfernte Objekte ein kleineres Bild auf der Netzhaut des Auges. Diese Eigenschaft muß nun durch die Abbildung simuliert werden, indem die Tiefe eben nicht mehr ignoriert wird, sondern zur Verkleinerung des Bildes dient. Den benötigten Algorithmus kann man sich anhand des Strahlensatzes leicht veranschaulichen: a = y´ Þ y´ = a y entspr.: x´ = a x z y z z Hier betrachtet man die dreidimensionale Welt als hinter dem Bildschirm stehend. Von dieser Welt sieht man zunächst nichts, aber die Abbildung auf dem Bildschirm ist sichtbar. Alle Strahlen, die vom Objekt ausgehen, müssen dabei letztendlich beim Auge ankommen, so daß im Bild hier der Ursprung liegt. Jede Koordinate des Objekts (hier beispielhaft für die y-Koordinate der oberen und unteren Ecke) muß in eine zweidimensionale Bildschirmkoordinate (hier y´) übergeführt werden. Dazu bedient man sich des Strahlensatzes, der eine eindeutige Beziehung zwischen y, y´, a (Abstand Auge - Bildschirm) und z (Tiefe des Objekts) herstellt. Es ist offensichtlich, daß bei diesem Algorithmus eine größer werdende Tiefe (z) den Winkel zwischen den Strahlen verkleinert und somit auch das Bild auf dem Schirm, so daß hier die gewünschte Fluchtpunktperspektive erreicht ist. Dieser Fluchtpunkt, an dem alle parallelen Linien in der Ferne zusammenlaufen, befindet sich bei dieser Methode allerdings immer auf der z-Achse, er ist nicht beliebig plazierbar, was für die meisten Anwendungen auch gar nicht nötig ist. Bei der Berechnung anhand dieser Formel kann man viel Rechenzeit sparen, wenn man für den (ohnehin willkürlichen) Abstand a eine Zweierpotenz einsetzt. In diesem Fall läßt sich die Multiplikation durch Shiften (SHL / SHR) erheblich beschleunigen. Eine Translation ist nichts weiter als eine Verschiebung in eine bestimmte Richtung, zum Beispiel eine Bewegung durch einen langen Gang. Mathematisch gesehen baut die Translation auf einer Vektoraddition auf: Die Verschiebung wird durch einen Vektor, den Translationsvektor, bestimmt. Dieser Vektor wird einfach auf alle Ortsvektoren (Punkt-Koordinaten) des zu verschiebenden Objekts addiert. Eine Bewegung des Betrachters wird dabei ganz genauso erreicht, die Sichtweise ist jedoch umgekehrt: Möchte man sich als Betrachter um eine Einheit in z-Richtung bewegen, verschiebt man einfach die gesamte 3D-Welt um eine Einheit in negative z-Richtung. Die Rotation ist da schon etwas komplizierter, vor allem, wenn man um jeden Preis mit Matrizen rechnen will, wie das oft propagiert wird. Matrizen fassen in einer Art Tabelle die notwendigen Rechenschritte für eine Transformation zusammen; Translationen, Rotationen, Skalierungen, alles hat seine Matrize. Das hat den Vorteil, daß man mehrere Matrizen zusammenfassen und damit etwas Rechenzeit sparen kann - wenn von vornherein feststeht, welche Transformationen in welcher Reihenfolge durchgeführt werden sollen. Weil das jedoch selten der Fall ist, werden die Rotationsmatrizen hier nur der Vollständigkeit halber erwähnt. Bei der Rotation muß grundsätzlich unterschieden werden, um welche der drei Achsen rotiert werden soll, es werden jeweils andere Verknüpfungen durchgeführt. Um die x-Achse: Die entsprechende Matrix: x´ = x 1 0 0 y´ = y * cos (a) - z * sin (a) 0 cos (a) - sin (a) z´ = y * sin (a) + z * cos (a) 0 sin (a) cos (a) Um die y-Achse: Die entsprechende Matrix: x´ = x * cos (a) + z * sin (a) cos (a) 0 sin (a) y´ = y 0 1 0 z´ = - x * sin (a) + z * cos (a) - sin (a) 0 cos (a) Um die z-Achse: Die entsprechende Matrix: x´ = x * cos (a) - y * sin (a) cos (a) - sin (a) 0 y´ = x * sin (a) + y * cos (a) sin (a) cos (a) 0 z´ = z 0 0 1 Diese Formeln betrachten zunächst einmal nur die Rotation um die Koordinatenachsen. Durch eine Kombination mehrerer Rotationen kann aber jede beliebige durch den Ursprung verlaufende Gerade eine Achse bilden. Möchte man auch noch die Einschränkung der Ursprungsgeraden umgehen, muss man die Rotation noch mit einer Translation verbinden. Dazu wird vor der Rotation die Welt so weit verschoben, dass der Punkt, um den gedreht werden soll, sich im Ursprung befindet. Nach der Rotation wird dann gegebenenfalls wieder zurückverschoben, wobei allerdings auch der Translationsvektor vorher rotiert werden muß. Bei der aufeinanderfolgenden Rotation um mehrere Achsen müssen selbstverständlich jeweils die errechneten Koordinaten der vorherigen Rotation als Quellkoordinaten in die folgende eingesetzt werden. Verwendet man immer wieder die eigentlichen Weltkoordinaten als Quelle, dürfte man recht ungewöhnliche Ergebnisse erhalten, die mit der eigentlich darzustellenden Welt nicht viel gemeinsam haben. Gerade die Rotation mit ihren vielen Sinus- und Cosinus-Berechnungen stellt einen besonders geeigneten Anwendungsfall der Tabellen-Rechnung dar. Wollte man all diese Berechnungen mit gewöhnlichen Pascal-Funktionen programmieren, käme nie eine flüssige Bewegung zustande. Also werden alle Sinus- und Cosinus-Werte aus der (gleichen) Tabelle entnommen und mit den Koordinaten entsprechend der jeweiligen Rechenvorschrift multipliziert. Außer den reinen Translationen sind die genannten Transformationen grundsätzlich nicht kommutativ, d. h. ihre Reihenfolge ist nicht gleichgültig. Rotiert man beispielsweise den auf der x-Achse liegenden Punkt (1/0/0) zunächst um 90 Grad um die x-Achse, dann um den gleichen Winkel um die z-Achse, liegt das Ergebnis auf der y-Achse. Bei umgekehrter Reihenfolge liegt es auf der z-Achse. Daher sollte man eine einheitliche Reihenfolge festlegen, nach der rotiert wird, zweckmäßigerweise erst um die x-, dann y- und schließlich z-Achse. Auch bei gemischten Transformationen muß die Reihenfolge beachtet werden. Bei einer Translation mit folgender Rotation kommt sicher ein anderer Punkt heraus als bei umgekehrter Reihenfolge, daher sollte man sich auch hier festlegen. Am sinnvollsten ist in diesem Fall die Folge Translation - Rotation, weil sich dann die Translations-Werte auf die bekannten Weltkoordinaten bezeiehen und nicht auf deren rotierte Abbildungen. Zusammenfassend kann man also folgende Reihenfolge als geeignetste ansehen:
Drahtmodelle: Bei den Füllalgorithmen gibt es zwei grundsätzliche Kategorien: zum einen die allgemeine Füllung, die beliebige, vorgezeichnete Flächen füllt und häufig in Malprogrammen zum Einsatz kommt, zum anderen aber die Füllung eines durch Koordinaten definierten Polygons. Letzterer Algorithmus ist für diese Zwecke eindeutig der bei weitem schnellere. Im wesentlichen baut die hier beschriebene Methode auf dem Zeichnen von Linien auf. Dazu wird, ausgehend vom Punkt mit der niedrigsten y-Koordinate, der linke und rechte Rand des Polygons abgetastet, bis der Punkt mit der größten y-Koordinate erreicht ist. Dabei werden die Begrenzungslinien des Polygons nur berechnet und nicht gezeichnet. Ist man auf diese Weise auf beiden Seiten um eine Zeile weitergekommen, kann eine horizontale Linie zwischen dem linken und rechten errechneten Punkt gezogen werden. Dabei macht man sich zunutze, daß gerade im Mode X horizontale Linien mit sehr hoher Geschwindigkeit gezeichnet werden können. Eine Füllroutine muß also sowohl am linken als auch am rechten Polygonrand ständig Linien berechnen. Ist eine Linie fertig “gezeichnet”, wird die nächste, deren Startpunkt ja dem letzten Eckpunkt entspricht, begonnen d = sin ß´ ß´ = ß - 90 d = sin (ß - 90) = - cos ß Das Verhältnis d / f ist hier proportional zur Helligkeit der Fläche. Wie die Herleitung zeigt, ist dieses Verhältnis gleich dem negativen Cosinus des Winkels zwischen Lichtvektor und Normalvektor der Fläche. Der Normalvektor ist ein Vektor, der senkrecht auf der Fläche steht. Er läßt sich leicht durch ein Kreuzprodukt zweier in der Ebene liegender Vektoren bestimmen. Daß hier der Cosinus des Winkels benötigt wird und nicht der Winkel selbst, vereinfacht die Berechnung enorm, da als Ergebnis einer Winkelbestimmung (durch das Skalarprodukt) der Cosinus des Winkels herauskommt. Die Vorgehensweise zur Bestimmung der Helligkeit ist also wie folgt:
Das Ergebnis der Winkelberechnung ist im gezeichneten Fall negativ. Ist die Fläche aber dem Licht abgewandt (ß < 90 Grad), so ist das Ergebnis positiv, und es darf nur die Grundfarbe der Fläche benutzt werden, weil sie im Schatten liegt und daher nur Streulicht abbekommt. Gleich zu Beginn der Prozedur wird die Hauptdeterminante gebildet. Mit deren Hilfe wird später die relative Koordinate des Punktes innerhalb der Fläche bestimmt. Dazu ist es wichtig zu wissen, daß jeder Punkt auf einer Fläche eine Lösung des folgenden Gleichungssystems ist: x1 = lambda1 * a1 + lambda2 * b1 x2 = lambda1 * a2 + lambda2 * b2 x3 = lambda1 * a3 + lambda3 * b3 Dabei sind x1 - x3 die Koordinaten des Punktes, a1 - a3 die Komponenten des ersten Flächenvektors und b1 - b3 die des zweiten. lambda1 und 2 geben die affinen Koordinaten relativ zu den beiden Flächenvektoren an und können direkt zum Zugriff auf die Textur benutzt werden. Um lambda1 und lambda2 auszurechnen, benötigt man lediglich zwei der Gleichungen, die dritte ist dann in jedem Fall erfüllt, weil der Punkt ja in der Ebene liegt. Nimmt man zum Beispiel die ersten beiden Gleichungen, so kann man die Lösung sehr einfach durch Determinanten finden: Die Hauptdeterminante beträgt D = a1 * b2 - a2 * b1, die erste Nebendeterminante D1 = x1 * b2 - x2 * b1 und die zweite Nebendeterminante D2 = a1 * x2 - a2 * x1. Die beiden Unbekannten ergeben sich nun als lambda1 = D1 / D und lambda2 = D2 / D. Die Hauptdeterminante ist jetzt für die ganze Fläche gleich, so daß sie hier direkt ausgerechnet werden kann. Dabei tritt jedoch noch ein Problem auf: Unter Umständen kann die Wahl der ersten beiden Gleichungen ungünstig sein, was sich dadurch zeigt, daß die Hauptdeterminante dann 0 beträgt. In diesem Fall muß einfach eine andere Kombination benutzt werden.
( 0 Votes ) |

