Nach dem Vertexshader wird es Zeit
für den Triangle Setup. Über
eine Clippingeinheit wird bestimmt,
ob ein Primitiv derzeit sichtbar
ist oder nicht. Es wird also kontrolliert,
ob ein Primitiv außerhalb
des Sichtbereiches eines Spielers
ist oder ob es z.B. von der falschen
Seite (Hinterseite einer Mauer)
sichtbar ist. Einige unter euch
dürften das in Form von Fehlern
schon mal gesehen haben. Wenn ihr
u.a. durch eine Wand schauen könnt
oder Texturen ständig auftauchen
und wieder weg gehen.
|
Zum
Vergrösssern ins Bild
klicken
|
|
|
Ist der Triangle Setup
abgeschlossen, wird der nächste
Schritt, die Rasterisierung, eingeleitet.
Bei diesem Prozess wird den Primitiven
der Pixelinhalt zugeordnet. So entsteht
aus einer schräg liegenden
Linie oder Seite eines Dreiecks
ein treppenartiges Gebilde. Glatte
Linien eines Primitives wirken deshalb
ziemlich kantig. Bei Bewegung entsteht
so das berüchtigte Treppenwandern.
Je nach Größe des Rasters
(die Bildschirmauflösung),
auf das die Primitive gelegt werden,
wird das Bild fürs Auge grober
oder feiner. Bei einer hohen Auflösung
(einem großen Raster) fällt
mehr Zuweisungsarbeit für die
Primitive an, dafür ist das
Bild schöner.
|
Zum
Vergrösssern ins Bild
klicken
|
|
|
Während der Rasterisierung
wird mit Hilfe eines "Hidden
Surface Removal" (Versteckte
Oberflächen entfernen) entschieden,
ob bestimmte Pixel weiter berechnet
werden müssen. Hier wird das,
was nicht sichtbar ist - wir erinnern
uns ans Triangle Setup - endgültig
entfernt. Durch dieses Verfahren
spart man sich Rechenleistung, da
diese Pixel von der weiteren Berechnung
ausgeschlossen werden. Aber wie
weiß eine Grafikkarte, was
denn nun verdeckt ist und was nicht?
Dies wird über den Z-Buffer
bestimmt. Der Z-Buffer enthält
Informationen über die Tiefe
eines Pixels, sprich wie weit es
im Bild "drin" ist. Mit
diesem Tiefenwert wird dann bestimmt,
ob ein Objekt durch ein anderes
verdeckt wird. Je nach 3D Karte
kann hier mehr oder weniger Platz
für andere zu berechnende Pixel
geschaffen werden. Aber wie gut
das ganze dann in die Tat umgesetzt
wird, bestimmt die 3D Engine eines
Programmes.
Und
so sieht das ganze HSR-Verfahren
dann aus:
|
Zum
Vergrösssern ins Bild
klicken
|
|
|
Der rote Strich stellt
eine Wand dar. Im linken Bild wird
das gelbe Objekt, da es im Sichtfeld
liegt, berechnet obwohl der Spieler
es gar nicht sieht. Rechts wird
nur der wirklich sichtbare Bereich
berechnet.
Kommen wir nun zum
wichtigsten Arbeitsschritt einer
GPU, dem Fragmentshader. Wie schon
weiter oben erwähnt, führt
der Fragmentshader Berechnungen
auf Pixelebene bzw. pixelweise durch.
Sämtliche Anweisungen für
die Fragmentshader sind in der jeweiligen
Programmierschnittstelle, dem Pixelshader
im DirectX, festgelegt. Leider kann
nur für ein 2x2 Pixelblock
oder ein Pixelquad dieselbe Berechnung
durchgeführt werden, so dass
also ein Verbund von 4 Pixelpipelines
an einem Pixelquad arbeitet. Dies
ist zurückzuführen auf
eine unzureichende Steuerlogik,
was sich in Zukunft allerdings ändern
könnte.
Diese Quadpipelines
sind nun für den Großteil
der Geschwindigkeit einer Grafikkarte
zuständig. Zum einen spielt
die Anzahl der Pipelines eine sehr
große Rolle, denn mehr Einheiten
können mehr gleichzeitig berechnen,
zum anderen ist aber hier die gewählte
Bildschirmauflösung sehr ausschlaggebend.
Unabhängig von der Anzahl der
vielen Polygone verändert sich
die Anzahl der Pixel je nach Auflösung.
Ebenso ist aber entscheidend, wie
eine Pipeline ihre Berechnungen
durchführt. Das ist aber von
Hersteller zu Hersteller unterschiedlich.
Führt z.B. eine
nVIDIA GeForce6 Karte eine Texturberechnung
durch, wird die entsprechende Pipeline
bis zur Fertigstellung der Berechnung
blockiert d.h. sie ist in dieser
Zeit nicht ansprechbar. Eine aktuelle
Radeon x800 Karte besitzt für
diesen Zweck eine zusätzliche
Textur ALU (Arithmetic Logical Unit).
Das ermöglicht der Karte Berechnungen
parallel zu erledigen. Alle nötigen
Texturdaten werden von einer TMU
(Textur Mapping Unit) aus dem Grafikkartenspeicher
ausgelesen und in beliebig vielen
Durchgängen verrechnet.
Hier wären wir
bei den Texturfiltern angelangt.
Je nach der Anzahl der durchgeführten
Berechnungen spricht man von bilinearer
(2fache), triliniearer (3fache)
oder anistroper (mehrfache) Filterung.
Das Ergebnis sieht man in der deutlich
höheren Texturschärfe,
spürt man aber deutlich in
der Performance. Aber was macht
jetzt der Fragmentshader? Nun, der
Fragmentshader ist zuständig
für die Verrechnung von Pixelinformationen.
Diese sind erstmal die Farben rot,
blau, grün sowie einer vierten
Information, dem Alphaanteil (Transparenz).
Ist nun ein Datenpaket
bzw. ein Pixelblock fertig berechnet,
wird dieser weiter zu den ROPs (Rasteroperatoren)
gesendet. Der Rasteroperator ist
nun für das Fertigstellen des
gesamten Bildes zuständig.
Er übernimmt das zusammenfügen
der einzelnen "Texturfetzen",
was im Fachjargon als Blending bezeichnet
wird. Weitere Operationen sind das
Verrechnen des Z-Buffers (Tiefeninformation
der Textur) sowie das Anwenden diverser
Stenciloperationen, welche für
die Darstellung von Schatten verantwortlich
sind.
Auch findet hier
das sehr sinnvolle Kantenglätten
statt. Wie das funktioniert, erkläre
ich ein anderes mal ;P . Sind auch
diese Arbeitsschritte getan, kommt
das ganze über den Framebuffer
in den Speicher, wo dann später
die Daten an den Bildschirm ausgegeben
werden.
Hiermit endet der
erste Teil unserer Grundlagenserie.
Habt Ihr noch Fragen
zum Review? Antworten gibt es im
Forum.
|
Artikel:
Copyright März 2006 by
3DChip
|
| Logo
Copyright März 2006 by
Jesse |
|
Bilder:
Copyright März 2006 by
Löschzwerg
|
|
Autor:
Dominik Schreiber alias "Löschzwerg"
|