-
Die
Erfindung betrifft ein Verfahren zur Übertragung von Tiefeninformationen
in den Tiefenspeicher einer Grafikkarte für die Darstellung von 3D-Panoramabildern.
-
Die
Erfindung ist insbesondere in Verfahren zur schnellen Darstellung
eines Landschaftsbildes bei gleichzeitiger Darstellung einer oder
mehrerer Flugobjekte anwendbar. Da sich die Flugobjekte im Raum
vor dem Betrachter relativ frei bewegen können, müssen sie vom Landschaftsbild
teilweise überdeckt
werden können – abhängig von
ihrer Entfernung zum Betrachter. Das Landschaftsbild liegt in Form
einer zweidimensionalen Fotographie vor, beinhaltet also keinerlei
Informationen über
die Entfernung der darauf sichtbaren Gegenstände zum Betrachter. Die Information über die
Entfernung zum Betrachter („Tiefeninformation") muss daher auf
einem zweiten Weg in das System eingespeist werden. Für den Anwender
am einfachsten geht dies mittels einer Art „Tiefenbild", in dem in Farben
kodiert die Tiefeninformation individuell für jedes Pixel enthalten ist.
Bei dieser Art der Datengenerierung kann der Anwender sehr leicht
eine neue Landschaft mittels einer 360°-Fotographie integrieren und muss hierzu
nur ein passendes Tiefenbild erzeugen.
-
Anwendung
finden derartige Verfahren u. a. in Visualisierungssystemen von
militärischen
Ausbildungsgeräten.
Der Ubungskampfraum ROLAND 2 z.B. hat ein einkanaliges optisches
Visier. Das Visierbild zeigt eine auf einen festen Augenpunkt basierende
360°-Landschaft
mit einer fotorealistischen Geländedarstellung.
Der Betrachter kann sich um eine virtuelle Achse drehen, so dass
das Visierbild einen beliebigen Ausschnitt der Landschaft darstellt.
Innerhalb dieses Visierbildes können
sich Flugziele bewegen. Mit dem Einbringen von Informationen über die
Entfernung zum Betrachter können
die Flugziele teilweise von der Geländedarstellung überdeckt
werden. Weitere Randbedingungen für das Visierbild sind eine
Animationsrate von mindestens 60 Bilder pro Sekunde, eine Auflösung von
mindestens 768 × 768
Bildpunkten und die Möglichkeit, dass
der Betrachter sich bis zu 90° pro
Sekunde um seine Achse drehen kann.
-
Aus
Kostengründen
ist für
die Darstellung der Landschaft und der Flugobjekte Standard-PCs
(so genannte COTS-Produkte: Commercial Oft The Shelf) anzustreben.
Aufgrund der rasanten Entwicklung der Computertechnik in den letzten
Jahren wurde die Leistungsfähigkeit
dieser Systeme – insbesondere
im Grafik-Bereich – so
stark gesteigert, dass eine Realisierung grundsätzlich möglich erscheint. Allerdings
sind derartige COTS-Produkte nicht für diese spezielle Aufgabe der
Grafikgenerierung zur Erzeugung von 3D-Bildern mittels einer Fotographie
und einem „Tiefenbild" entworfen worden,
so dass es in der Regel an der notwendigen Schnelligkeit fehlen
wird.
-
In
der
DE 196 20 858
A1 ist ein Verfahren zur Farbaufbereitung in Computergrafiksystemen
dargestellt, und zwar insbesondere zur Erzeugung einer Farbdarstellung,
die den Abstand des Betrachters zu dem dargestellten Objekt mit
einbezieht. Dieser Abstand wird durch die Tiefeninformation des
Objekts approximiert.
-
Die
WO98/40848 beschreibt ein Verfahren zur Speicherung von Pixeldaten
für eine
dreidimensionale Darstellung eines Bildszene, nach dem derselbe
Speicherbereich sowohl als Tiefenspeicher als auch als Bildspeicher
benutzt werden kann. Da die Tiefeninformationen im Laufe des Verfahrens
von den Darstellungsinformationen (Farbwerte) überschrieben werden, werden
die Darstellungsinformationen als solche markiert, um ein erneutes Überschreiben
zu verhindern.
-
Aufgabe
der Erfindung ist es, ein Verfahren zu schaffen, das unter Einsatz
von Standard-Hardware aus dem Consumer-Bereich eine schnelle Darstellung
der 3D-Landschaft
bei einer Auflösung
von mindestens 768 × 768
Bildpunkten mit mindestens 60 Bildern pro Sekunde ermöglicht.
Der Betrachter soll sich dabei sehr schnell (d.h. bis zu 90°/s) um seine
Achse drehen können.
-
Diese
Aufgabe wird mit dem Verfahren nach Patentanspruch 1 gelöst. Eine
vorteilhafte Ausführung des
Verfahrens ist Gegenstand eines weiteren Patentanspruchs.
-
Erfindungsgemäß erfolgt
innerhalb des 3D-Visualisierungsprozesses die Übertragung der Tiefeninformationen
des darzustellenden 3D-Panoramabilds in den Tiefenspeicher (z.B.
dem Z-Buffer, es gibt jedoch auch andere Formen von Tiefenspeicher
wie z. B. den W-Buffer) der Grafikkarte auf Pro-Pixel-Basis unmittelbar
auf dem Grafikchip der Grafikkarte mittels eines auf dem Grafikchip
ausgeführten
Programms. Hierzu werden dem Programm als Eingabedaten mindestens
eine Textur, die in kodierter Form die Tiefeninformationen des darzustellenden
3D-Panoramabilds
enthält,
zur Verfügung
gestellt.
-
Da
der Darstellungsprozess bei der Darstellung der Landschaft keine
Bildbereiche mehrfach überschreibt,
kann das Landschaftsbild in nahezu konstanter Geschwindigkeit inkl.
der Tiefeninformationen dargestellt werden. Hierdurch werden Garantien
für die
Darstellungsgeschwindigkeit möglich.
Die Darstellungsgeschwindigkeit der Landschaft inkl. der Tiefenwerte
ist nur von der Verarbeitungsgeschwindigkeit des Programms und der
notwendigen Zeit für
den Transfer der Daten vom Hauptspeicher des PC in den Grafikspeicher
der Grafikkarte (in aktuellen PC-Systemen kommt der AGP-Bus zum
Einsatz) abhängig.
-
Das
auf dem Grafikchip ausgeführte
Programm kann insbesondere ein in der modernen 3D-Visualisierungstechnik
verwendeter so genannter „Pixel
Shader" (in der
Literatur oft auch als Textur Shader, Fragment Shader oder nur als
Shader bezeichnet) sein. „Pixel
Shader" steht allgemein
als Synonym für
ein auf der Grafikkarte vorhandenes Assembler-Programm, welches
einen darzustellenden Punkt eines Polygons berechnet. Der Name leitet
sich aus zwei Teilen ab. „Pixel" bezieht sich auf
die Berechnung eines Punktes. „Shader" bezieht sich auf
den eigentlichen Verwendungszweck eines Pixel Shaders – der Berechnung
von Schattierungen bzw. Beleuchtungs- und Farbinformationen eines
Punktes.
-
Mit
Einführung
von High-End-Grafikkarten der Geforce4-Familie hat der Hersteller
nVidia ein Verfahren namens „Z-Correct
Bump Mapping" vorgestellt,
dass speziell das Problem der Durchdringung von Wasseroberflächen beheben
soll. Einzelheiten hierzu findet sich auch auf der Internetseite
des Herstellers www.nvidia.com. Mit dieser Technik wurde erstmals
eine Möglichkeit
geschaffen, auf Pro-Pixel-Basis Einfluss auf den Tiefenwert eines
Pixels im Inneren eines Polygons zu nehmen. Die vorliegende Erfindung
beruht darauf, die für
das „Z-Correct
Bump Mapping"-Verfahren vorgesehenen
Pixel-Shader-Befehle einem gänzlich
anderen Zweck, nämlich
für die
schnelle Übertragung
der Tiefenwerte in den Tiefenspeicher der Grafikkarte, zuzuführen.
-
Dies
gelingt durch eine geeignete Kodierung der Eingabedaten. Da die
verwendete Textur Tiefeninformationen enthält, wird sie im Folgenden auch
als Tiefentextur bezeichnet. Dies zur Abgrenzung zu Texturen, welche
die eigentlichen Bilddaten des darzustellenden 3D-Panoramabilds
enthalten, wie sie üblicherweise
von Pixel-Shadern
verarbeitet werden.
-
Aufgrund
der vorgegebenen Funktionalität
der Pixel-Shader-Befehle entsprechend dem „Z-Correct Bump Mapping"-Verfahren müssen die
in der Tiefentextur enthaltenen Werte derart kodiert werden, dass
die vom Pixel-Shader daraus generierten und in den Tiefenspeicher übertragenen
Werte den tatsächlichen
Tiefenwerten der einzelnen Pixel entsprechen. Liegen zum Beispiel
die vom Pixel-Shader generierten und in den Tiefenspeicher übertragenen
Tiefenwerte in der Form eines Quotienten zweier in der Tiefentextur
enthaltener Werte vor, so müssen
die beiden Werte der Tiefentextur so vorbesetzt werden, dass ihr
Quotient gerade dem tatsächlichen
Tiefenwert eines Pixels entsprechen.
-
Gemäß der Erfindung
erfolgt die Generierung der Tiefeninformation für die individuellen Pixel nicht durch
Interpolation der nur in den Eckpunkten eines Polygons definierten
Tiefeninformationen (Letzteres entspricht der Standard-Rendering-Pipeline gemäß dem Stand
der Technik in der 3D-Visualisierungstechnik, wie unten näher erläutert),
sondern durch Zugriff auf eine vorgefertigte Tiefentextur, die die
Tiefenwerte auf Pro-Pixel-Basis und in einer der Verarbeitung durch
den Pixel-Shader
angepassten Form enthält.
Die Verarbeitung der Tiefeninformationen mittels Pixel-Shader erfolgt
auf dem Grafikchip der Grafikkarte in einem speziell hierfür optimierten
Prozessorbereich und ist deshalb sehr schnell.
-
Tests
bei der geforderten Auflösung
von 1024 × 768
Punkten mit einem Landschaftsbereich von 768 × 768 Punkten bei einer Farbtiefe
von 16 Bit und einer Geforce4 Ti4600-Grafikkarte haben gezeigt,
dass die gewünschte
Bilddarstellungsfrequenz von 60 Hz erreicht werden kann. Dies konnte
auch bei einer Auflösung des
Landschaftsbereiches von 1024 × 1024
Punkten gezeigt werden.
-
Das
erfindungsgemäße Verfahren
kann insbesondere unter beiden großen Graphikstandards (Open GL,
DirectX) auf verschiedenen Betriebssystemen eingesetzt werden.
-
Es
kann u. a. bei Verwendung eines Grafikprozessors der Firma nVidia
als auch der Firma ATI eingesetzt werden.
-
Die
Erfindung wird anhand konkreter Ausführungsbeispiele und unter Bezug
auf Figuren näher
erläutert.
Sie zeigen:
-
1 die
Rendering-Pipeline von DirectX 8.1,
-
2 die
vorgeschriebene Instruktionsreihenfolge eines Pixel-Shader-Programms.
-
Zum
besseren Verständnis
wird zunächst
allgemein die moderne 3D-Visualisierung, auf der auch das erfindungsgemäße Verfahren
aufbaut, näher
erläutert.
Die Punkte, an denen das erfindungsgemäße Verfahren vom den Standardverfahren
abweicht, werden ausführlich
erläutert.
-
Die
moderne 3D-Visualisierung basiert auf der Darstellung von Dreiecken
(allgemein: Polygone). Alle Körper,
die dargestellt werden sollen, werden in Dreiecke zerlegt. Gebogene
oder runde Oberflächen
werden durch ein Netz von Dreiecken angenähert und durch die verwendeten
Beleuchtungsverfahren „rund
gemacht". Eine darzustellende
Szene wird daher durch relativ wenige Elemente beschrieben:
- – Eine
Menge von 3D-Koordinaten: Sie beschreiben alle Eckpunkte (Vertices)
der verwendeten Dreiecke.
- – Koordinaten-Systeme:
Sie beschreiben den Zusammenhang von Mengen von 3D-Koordinaten. Jedes
bewegliche darzustellende Objekt verwendet sein eigenes lokales
Koordinatensystem. Dieses wird mittels einer Transformationsvorschrift
in das Welt-Koordinatensystem eingebracht. Dieser Vorgang ist rekursiv,
so dass ein bewegliches Objekt bewegliche Teile haben kann.
- – Dreiecks-Listen:
Eine Beschreibung, welche 3D-Koordinaten zu einem Dreieck zusammengefasst
werden.
- – Oberflächen-Beschreibungen:
Jedes Dreieck bildet eine Fläche
im Raum. Die Oberfläche
wird beschrieben durch Farbeigenschaften, Beleuchtungseigenschaften
und Texturierungseigenschaften. Für die Beleuchtungseigenschaften
kann die Angabe von Normalen-Vektoren in den Eckpunkten der Dreiecke
notwendig sein. Diese können
nicht nur relativ zur Fläche
des Dreiecks ausgerichtet sein, sondern auch relativ zur durch das
Dreieck nachgebildeten gebogenen Oberfläche. Damit lässt sich über die
Fläche
des Dreiecks die Beleuchtung der gebogenen Fläche berechnen und so den Eindruck
der Krümmung
vermitteln. Alle verwendeten Informationen bezüglich der Oberflächen-Beschreibung
werden in den Eckpunkten des Dreiecks abgelegt. Es ist nicht möglich, einem
beliebigen Punkt innerhalb des Dreiecks eine individuelle Beschreibung
zuzuordnen.
- – Umweltparameter:
Lichtquellen, Nebel etc.
-
Eine
so beschriebene Szene wird von der Grafikhardware in mehreren Schritten
verarbeitet. Zuerst werden alle Koordinaten transformiert, so dass
deren Positionen relativ zur aktuellen Kamera bekannt sind. Da der
Bildschirm nur zweidimensional ist, müssen die Koordinaten anschließend auf
den sichtbaren zweidimensionalen Bereich projiziert werden. In der
Regel verwendet man hierzu eine Zentralprojektion, da sie dem natürlichen
Sehverhalten des Menschen entspricht. In einem weiteren Schritt
werden die resultierenden zweidimensionalen Abbilder der Dreiecke
so „zurechtgeschnitten", dass sie auf den
Bildschirm passen, d.h. nicht über
die Ränder
hinausragen. Anschließend
werden die noch sichtbaren Dreiecke gezeichnet. Beim Zeichnen der
Dreiecke stellt sich das Problem ein, dass sich diese teilweise überdecken.
Steht z.B. ein Haus in einer Landschaft, so ist auch die Landschaft
hinter dem Haus vorhanden, im resultierenden Bild muss das Haus
aber vor diesen Landschaftsbereichen dargestellt werden. Es ist
sehr aufwändig
bzw. sogar unmöglich,
die Dreiecke ihrer Entfernung zum Betrachter nach zu sortieren,
um sie anschließend
von hinten nach vorne zu zeichnen. Stattdessen verwenden fast alle
modernen Grafiksysteme einen so genannten Z-Buffer bzw. Tiefenspeicher.
Jedem Bildpunkt auf dem Bildschirm wird ein Tiefenwert im Z-Buffer
zugeordnet. Alle Dreiecke werden einfach berechnet und der Tiefenwert
für jeden
berechneten Bildpunkt wird mit dem für diesen Bildpunkt bereits vorhandenen
Wert verglichen. Ist der Wert kleiner, so ist der berechnete Bildpunkt
näher am
Betrachter, als der an dieser Stelle zuvor berechnete Bildpunkt
und wird daher inkl. Tiefenwert gespeichert. Auf diese Weise kann
sehr leicht die Überdeckung
der Dreiecke berechnet werden. Allerdings führt dies meistens auch zu großen Bildteilen,
die mehrfach gezeichnet werden. Um ein Dreieck zeichnen zu können, wird
dieses „gerastert", d.h. dass – ausgehend
von den Eckpunkten – das
Dreieck in horizontale und vertikale Linien in Bildschirmauflösung zerlegt
wird, um die zum Dreieck gehörenden
Bildpunkte zu bestimmen. Da sämtliche
Informationen bezüglich
des Erscheinungsbildes des Dreiecks in den Eckpunkten liegen, müssen diese
zwischen den Ecken interpoliert werden. Insbesondere die Tiefeninformation
wird nur zwischen den Eckpunkten interpoliert, d.h. dass ein Dreieck
immer eine ebene Fläche
im Raum ergibt. Bezogen auf die der Erfindung zugrunde liegende Problemstellung
der 3D-Darstellung mittels einer zweidimensionalen Textur (Fotographie)
und einem Tiefenbild, in der die Tiefeninformationen pixelweise
in Farben kodiert sind, bedeutet dies, dass man das Tiefenbild nicht
einfach übernehmen
kann.
-
In
den letzten Jahren haben sich zwei große Standards zur 3D-Visualisierung
durchgesetzt: OpenGL und DirectX. Beide arbeiten auf sehr ähnliche
Weise und unterscheiden sich in erster Linie auf die unterstützen Hardware-Plattformen,
die Treiberunterstützung
durch die Hersteller der Grafikkarten und die Art der Ansteuerung.
-
Im
Folgenden wird die Arbeitsweise von DirectX beschrieben. Die Verarbeitung
der Grafikdaten, d.h. der 3D-Koordinaten, Dreiecks-Listen, Oberflächenbeschreibungen
etc., erfolgt in der so genannten Rendering-Pipeline. In DirectX
8.1 unterteilt sie sich in drei Hauptbereiche, die jeweils in verschiedene
Teilbereiche untergliedert sind. Diese werden von der Grafikhardware
parallel in Form einer Pipeline verarbeitet, d.h. dass verschiedene
Bereiche der Grafikhardware gleichzeitig an unterschiedlichen Aufgaben
arbeiten, um eine möglichst
gute Gesamtperformance zu erreichen. In 1 sind die
drei Hauptbereiche vereinfacht dargestellt und die für die Erfindung
besonders relevanten Teilbereiche markiert. Die dargestellte Reihenfolge
der Teilbe reiche kann je nach Hardware-Implementierung von DirectX
durchaus von der letztendlich verwendeten Reihenfolge abweichen.
-
Geometrie-Pipeline
-
Die
Geometry Pipeline ist auf allen modernen Grafikkarten vorhanden.
Oft wird sie auch als „T&L"-Einheit (Transform & Lightning) bezeichnet.
Als Eingabedaten erhält
diese Pipeline-Stufe die untransformierten 3D-Koordinaten (Vertices)
und Beleuchtungsparameter einer Szene. Daraus generiert sie die
Position und Beleuchtung dieser Koordinaten auf dem Bildschirm aus
Sicht der verwendeten Kamera.
-
In
der neusten Version von DirectX werden so genannte Vertex Shader
eingesetzt. Dies sind kleine Programme in einem speziellen Assembler-Dialekt
(Vertex Shader-Assembler),
die auf jede 3D-Koordinate angewendet werden. Der Befehlssatz der
Assembler-Sprache umfasst Befehle zur Koordinatentransformation, Beleuchtungsberechnungen
und einige andere für
3D-Koordinaten nützliche
Dinge.
-
Das
Ergebnis der Geometry Pipeline sind die transformierten und beleuchteten
Koordinaten bzw. Vertices inkl. der zu den Vertices korrespondierenden
Texturierungsinformationen, aus denen die Polygone erzeugt werden.
-
Pixel and
Texture Blending
-
Das
Ergebnis der Geometry Pipeline sind die transformierten und beleuchteten
Koordinaten bzw. Vertices inkl. der zu den Vertices korrespondierenden
Texturierungsinformationen, aus denen die Polygone erzeugt werden.
Mit diesen Informationen werden die darzustellenden Polygone gerastert.
Dieser Prozess erfolgt in mehreren Schritten. Im ersten Schritt
werden die Eckpunkte (Vertices) des Polygons mit allen korrespondierenden
Daten entlang der Verbindungskanten der Eckpunkte interpoliert,
so dass für
jede darzustellende Zeile ein Paar von Kanteninformationen entsteht – die Zustandsdaten
am Beginn einer Zeile und die Zustandsdaten am Ende einer Zeile.
Zu diesen Zustandsdaten gehören
Informationen über
die Entfernung vom Betrachter, Texturierungsinformationen und die
Raumkoordinate des entsprechenden Punktes auf der Kante des Polygons.
Im zweiten Schritt wird jede darzu stellende Zeile zwischen dem Paar
von Kanteninformationen berechnet. Hierzu werden die Kanteninformationen
entlang der Zeile interpoliert. Dieser Prozess korrespondiert zu
der Interpolation entlang der Kanten. Hierbei entstehen die Informationen
zur Berechnung jedes darzustellenden Punktes im Inneren des Polygons.
Der letzte Schritt ist die Berechnung der für die Darstellung eines Punktes
benötigten
Informationen. Hierzu zählen
die Farbinformationen des Punktes, dessen Alphawert und die Entfernung
zum Betrachter.
-
Mit
DirectX Version 8 werden für
diese Schritte die bereits erwähnten
Pixel Shader eingesetzt. Ähnlich wie
bei den Vertex Shadern kommen hier kleine in Pixel Shader-Assembler geschriebene
Programme zum Einsatz, die in erster Linie die Berechnung des Farbwertes
und des Alphawertes eines Punktes beschreiben. Mit Pixel Shadern
ist es möglich,
komplexe Berechnungen und Verknüpfungen
von Texturen zu realisieren. Insbesondere können so realistisch wirkende
Beleuchtungseffekte erzielt werden.
-
Rasterization
-
In
der letzten Stufe der Rendering-Pipeline werden die berechneten
Informationen für
einen Bildpunkt in die dafür
vorgesehen Speicherbereiche geschrieben. Bevor dies geschieht, können einige
Tests erfolgen, um zu bestimmten, ob die berechneten Informationen überhaupt
in das endgültige
Bild gelangen sollen. Die Tests können von der Applikation jederzeit
einzeln aktiviert bzw. deaktiviert werden.
-
Es
werden drei Arten von Tests unterschieden:
- • Alpha-Test:
Sofern der Alpha-Test aktiviert ist, wird der Alphawert des Punktes
mit einem Referenzwert verglichen. Ist die Bedingung des Vergleiches
erfüllt,
so gilt der Test als Bestanden. Andernfalls wird der Punkt nicht
dargestellt und verworfen. Dieser Test wird häufig verwendet, um Punkte die
sehr bzw. vollständig
durchsichtig sind, möglichst
frühzeitig
von der Darstellung und weiteren Tests bzw. Berechnungen auszuschließen.
- • Stencil-Test:
Der Stencil-Test dient dem Maskieren von Bildschirmbereichen. Ist
dieser Test aktiviert, wird überprüft, ob die
Zielposition des Punktes in der resultierenden Grafik gültig ist.
Es wird ein der Zielposition korrespondierender Wert aus dem so
genannten Stencil-Buffer mit einem Referenzwert mittels eines Operators
verglichen. Ist die Bedingung erfüllt, kann der Punkt dargestellt
werden, andernfalls wird er verworfen.
- • Depth-Test:
Der abschließende
Test überprüft, ob der
darzustellende Punkt weiter vom Betrachter entfernt ist, als ein
an der entsprechenden Position bereits dargestellter Punkt. Ist
dies der Fall, wird der Punkt verworfen und nicht dargestellt. Mittels
dieses Tests wird die Überdeckung
von Bildbereichen bestimmt. Die Tiefeninformationen für diesen
Test werden im Z-Buffer gespeichert.
-
Sind
alle aktivierten Tests erfolgreich bestanden, kann der Punkt dargestellt
werden. Die Farbinformationen des Punktes werden in den Framebuffer
geschrieben. Die Tiefeninformation des Punktes wird in den Z-Buffer
geschrieben und der Alphawert wird nicht weiter benötigt und
verworfen.
-
Wie
vorhergehend beschrieben, muss in der Standard-Rendering-Pipeline
die Generierung der Tiefeninformationen über die Polygone erfolgen.
Um jedem Bildpunkt individuell einen bestimmten Tiefenwert zuzuordnen,
müsste
man für
jeden Bildpunkt ein eigenes Polygon definieren. Bei einer Auflösung von
768 × 768 =
589.824 Bildpunkten müssten
so mindestens 35.389.440 Polygone pro Sekunde dargestellt werden,
um die zugrunde liegende Aufgabe (Animationsrate von 60Hz) zu erreichen.
In Anbetracht der Tatsache, dass für die Berechnung dieser Polygone
auch deren Basisdaten, d.h. Positionsinformationen der Ecken und
Texturierung benötigt
werden, ist keine heute verfügbare
Grafikkarte in der Lage die Tiefeninformationen für das 2D-Foto auf
dieser Basis darzustellen.
-
Um
nicht für
jeden Bildpunkt ein Polygon zu verwenden, wurde das erfindungsgemäße Verfahren
zur Übertragung
der Tiefeninformationen in den Tiefenspeicher entwikkelt. Es realisiert
hinsichtlich der Gewinnung der Tiefeninformation eine alternative
Rendering-Pipeline, die sich vorteilhaft auf Pixel-Shader stützt, die
auf eine kodierte Tiefentextur des darzustellenden 3D-Panoramabilds
zugreifen. Die aus der polygonalen Berechnung erhaltenen Tiefeninformation
werden dabei überschrieben.
-
Der
Pixel Shader-Assembler ist eine Programmiersprache, die auf die
Bedürfnisse
der Textur- und Beleuchtungsberechnungen in einer Rendering-Pipeline
zugeschnitten ist. Die Programme werden DirectX in textueller Form
als ASCII-Text übergeben
und dort in den Binärcode
des Grafikprozessors übersetzt.
Der erzeugte Binärcode
kann anschließend
unter Verwendung eines diesem Binärcode zugeordneten Identifikators
verwendet werden.
-
Die
Pixel Shader-Assembler-Sprache besteht aus einem Satz von Instruktionen,
die auf Punktdaten operieren, die in Registern gehalten werden.
Jede Operation besteht aus einer Instruktion und einem oder mehreren
Operanden. Die Instruktionen verwenden Register, um Daten mit der
ALU (arithmetic logic unit) zu verarbeiten, und um temporäre Ergebnisse
zwischen zu speichern. Die gesamte Verarbeitung erfolgt auf dem Grafikchip
der Grafikkarte in einem speziell hierauf optimierten Prozessorbereich.
Die Ausführung
von Pixel Shader-Programmen erfolgt daher sehr performant. Die Länge eines
Pixel Shader-Programmes ist jedoch streng limitiert, um die für einen
Punkt aufzuwendende maximale Verarbeitungszeit zu begrenzen. Bei
Pixel Shader-Programmen der Version 1.3 sind z.B. nur max. 12 Instruktionen
erlaubt.
-
Die
Technik der Pixel Shader ist noch sehr jung und erfährt eine
schnelle Entwicklung. Unter DirectX 8.1 hat dies bereits zu fünf verschiedenen
Versionen geführt:
1.0, 1.1, 1.2, 1.3 und 1.4. Die Versionen 1.0 bis 1.3 bauen aufeinander
auf und verwenden eine sehr ähnliche
Architektur. Version 1.4 basiert auf einer neuen Architektur, die
auch die Basis für
die kommende Version 2.0 stellen soll.
-
Das
gemäß der Erfindung
entwickelte Pixel Shader-Programm basiert auf einer „Zweckentfremdung" eines Befehls zur
Simulation „rauher" Oberflächen mittels „Z-Correct Bump Mapping". Es handelt sich
hierbei um ein Verfahren, bei dem – ähnlich wie eine Textur mit
Bildinformationen – eine
Art „Ablenkungstextur" auf das Polygon
aufgebracht wird.
-
Die
grundlegende Idee der Erfindung liegt nun darin, die speziell für „Z-Correct
Bump Mapping" entwickelten
und an sich bekannten Pixel-Shader-Befehle für die schnelle Übertragung
von Tiefeninformationen für das
darzustellende Landschaftsbild zu verwenden. Dies gelingt durch
geeignete Wahl der Eingabedaten und einem geeigneten Datenformat
für die
verwendeten Texturen, wie im Folgenden am Beispiel eines nVidia-Grafikchips
unter der Pixel-Shader Version 1.3 näher erläutert wird.
-
In 2 ist
die vorgeschriebene Instruktionsreihenfolge eines Pixel Shader-Programmes der Version 1.3
dargestellt. Jedes Programm hat sich an diese Vorgabe zu halten
und erzeugt aus den Eingaben in den Eingaberegistern durch Ausführung der
Instruktionen mit Hilfe von temporären Registern Ausgaben in den Ausgaberegistern.
-
Die
Eingaberegister sind im Einzelnen:
- • cn: Konstanten-Register. Es stehen min. 8
Konstanten-Register (c0-c7)
zur Verfügung.
Sie können
vom Pixel Shader nicht verändert
werden und müssen
von der Applikation vor Anwendung des Pixel Shaders gesetzt werden.
Jedes Register kann vier Festkommawerte mit Wertebereich [–1,1] enthalten.
- • tn: Textur-Register. Es stehen min. 4 Textur-Register
(t0-t3) zur Verfügung. Jedes
Register besteht aus vier Festkommawerten (r, g, b, a bzw. u, v,
w, q oder x, y, z, w geschrieben als tn.rgba
bzw. tn.uvwq oder tn.xyzw) mit
einem minimalen Wertebereich von jeweils [–1,1]. Jedes Textur-Register
korrespondiert zu einer so genannten Texture-Stage. Jede Texture-Stage
umfasst die Beschreibung einer verwendeten Textur und der für die Verwendung
benötigten
Attribute. Ein Textur-Register
beinhaltet zunächst
Textur-Koordinaten, die vom System automatisch interpoliert werden.
Möchte
man den korrespondierenden Farbwert der Textur haben, so muss man
die entsprechende Textur „sampeln". Dies geschieht
unter Berücksichtigung
der Attribute der entsprechenden Texture-Stage.
- • vn: Farbregister. Es stehen min. 2 Farbregister
(v0-v1) zur Verfügung. Sie
werden automatisch mit interpolierten Werten im Bereich [0,1] gefüllt und
sind für
unsere Betrachtung nicht weiter von Interesse.
-
Für die Verarbeitung
der Instruktionen stehen zwei temporäre Register r0 und
r1 mit einem minimalen Wertebereich von
[–1,1]
zur Verfügung.
Als Ausgaberegister des Pixel Shader-Programms wird das temporäre Register
r0 verwendet. Die vier darin enthaltenen
Festkommawerte werden als RGBA-Farbwerte mit einem Wertebereich
von [0,1] interpretiert.
-
Das
gemäß der Erfindung
entwickelte Pixel Shader-Programm hat nachfolgende Gestalt. Dabei übernimmt
dieses Programm in der hier gewählten
Ausführung
neben der Übertragung
der Tiefenwerte zusätzlich auch
die Darstellung des Landschaftsbildes. Andere und auch einfachere
Ausführungen
dieses Programms sind möglich.
Insbesondere können
andere Register verwendet werden.
(1)
ps.1.3 | |
(2)
tex | t0 |
(3)
tex | t1 |
(4)
texm3x2pad | t2,
t0 |
(5)
texm3x2detph | t3,
t0 |
(6)
mov | r0,
t1 |
-
Der
Befehl (1) gibt die Version des Pixel Shader-Programms (hier 1.3)
an. Wie in der 2 zu sehen ist, muss dies immer
der erste Befehl eines Pixel Shader-Programms sein. Die nächsten beiden
Befehle dienen dazu, die Texturen zu „sampeln". Jede Textur, die in einem Pixel Shader-Programm
verwendet wird, wird durch ein Textur-Register tn repräsentiert.
Der Index n ist dabei zugleich die Nummer der Texture-Stage, die zu diesem
Register korrespondiert.
-
Zunächst enthält das Textur-Register
die Textur-Koordinaten im Textur-System in tn.uvwq.
Das Tripel (u,v,w) beschreibt dabei die Koordinate in einer dreidimensionalen
Volumentextur. Eine normale zweidimensionale Textur verwendet als
Koordina ten nur (u,v). Durch das Sampeln der Textur wird die Farbinformation
und der Alphawert zu der entsprechenden Textur-Koordinate erzeugt
und in tn.rgba gespeichert. Hierbei werden
die Textur-Koordinaten überschrieben,
da tn.uvwq und tn.rgba
den gleichen Speicherbereich verwenden.
-
Mit
dem Befehl (2) wird somit die Textur der Texture-Stage 0 in das
Register t0 gesampelt und mit Befehl (3)
die Textur der Texture-Stage 1 in das Register t1.
In den beiden Registern stehen anschließend die Farbinformationen
der beiden Texturen für
diesen Punkt. Wie in der 2 zu sehen ist, bedingt die
Abarbeitungsreihenfolge von Pixel Shader-Programmen, dass alle zu
sampelnden Texturen vor der ersten arithmetischen Operation gesampelt
werden müssen.
-
Wesentlich
für die
Erfindung ist, dass eine der bei diesem Pixel Shader-Programm verwendeten
Texturen Informationen (dies müssen
nicht notwendigerweise Farbinformationen sein; Es existieren auch
andere Texturformate, die für
diese Aufgabe geeignet sind wie z.B. HILO-Texturen) enthält, die
als Tiefentextur (in Register t0) genutzt
wird. Eine andere enthält
Informationen, die als Bildinformation (in Register t1)
genutzt wird.
-
Mit
den Befehlen (4) und (5) wird der neue Tiefenwert für den aktuellen
Punkt auf Basis der Tiefentextur berechnet. Der Befehl (5) kann
nur in Kombination mit Befehl (4) verwendet werden und hat folgende
Wirkung:
- • texm3x2pad
tm, tn
Es wird
das Skalarprodukt von tm und tn gebildet
und in einem internen Register z gespeichert. Für die beiden Indizes m und
n muss die Bedingung m > n
erfüllt
sein.
- • texm3x2depth
tm+1, tn
Es
wird das Skalarprodukt von tm+1, und tn gebildet und in einem internen Register
w gespeichert. Anschließend
wird der neue Tiefenwert für
den aktuell berechne ten Punkt auf z/w gesetzt, falls w ≠ 0. Andernfalls wird
der neue Tiefenwert auf 1 gesetzt.
-
Es
findet also folgende Operation statt:
z = t2.uvw·t0.rgb = t2.u·t0.r + t2.v·t0.g + t2.w·t0.b (1) w = t3.uvw·t0.rgb = t3.u·t0.r + t3.v·t0.g + t3.w·t0.b (2)
-
Um
jedem Punkt im dargestellten Bild einen bestimmten Tiefenwert zuzuordnen,
muss also der Quotient z/w den gewünschten Tiefenwert ergeben.
Um einen möglichst
einfachen Zusammenhang zwischen dem Quotienten z/w und den Werten
der Tiefentextur z/w zu erhalten, und zu erreichen, dass z/w nicht
von den Werten der Textur-Register t2 und
t3 abhängt,
werden die Werte der Textur-Register t0,
t2 und t3 folgendermaßen gewählt:
- • t0.rgba: r und g ergeben den Quotienten; b
= 0; a ist beliebig
- • t2.uvwq: u = x; v = 0; w = 0; q ist beliebig
- • t3.uvwq: u = 0; v = x; w = 0; q ist beliebig
-
Dies
führt bei
obiger Berechnung zu folgendem:
z = t2.uvw·t0.rgb = x·t0.r
+ 0·t0.g + 0·0
= x·t0.r (4) w = t3.uvw·t0.rgb = 0·t0.r
+ x·t0.g + 0·0
= x·t0.g (5)
-
Der
Wert vom gewählten
x muss im Bereich (0,1) liegen, da 0 zu keinem zulässigen Resultat
führt und durch
die Abbildungsvorschrift von Texturkoordinaten eine 1 auf 0 abgebildet
wird.
-
Der
Wert der Tiefeninformation eines Pixels kann somit mittels einer
geeigneten Tiefentextur auf Pro-Pixel-Basis generiert werden.
-
Mit
dem letzten Befehl (6) des Pixel Shader-Programmes wird der Farbwert
des darzustellenden Bildes für
den aktuellen Punkt in das Ausgaberegister des Pixel Shader-Programmes übertragen.
Alternativ könnte
man die Erzeugung der Tiefeninformationen und das Darstellen des
eigentlichen Bildes in zwei getrennten Schritten vollziehen, jedoch
müssten
dann vom Grafikprozessor gleichartige Polygone mehrfach verarbeitet
werden. Dies kann sich auf die Gesamtperformance negativ auswirken.
-
Nach
Durchführung
des erläuterten
Pixel-Shader-Programms ist die Übertragung
der Tiefeninformation für
die einzelnen Pixel abgeschlossen. Daran schließen sich die weiteren Verarbeitungsschritte
der Standard-Rendering-Pipeline (unter DirectX insbesondere Rasterization)
an.
-
Beim
Einsatz einer Grafikkarte mit einem Grafikprozessor von ATI (z.B.
Radeon 9700 Pro), werden Pixel Shader der Version 1.3 nicht unterstützt. ATI
hat von der Version 1.2 die Version 1.4 abgeleitet, die es ermöglicht,
ein zu dem oben beschriebenen Programm datenkompatibles Pixel Shader-Programm
zu schreiben.
-
Unter
dieser Version des Pixel-Shaders wird anstatt des Quotienten zweier
Skalarprodukte direkt der Quotient
erzeugt, so dass der Inhalt
der Texturregister i
2, i
3 ohne
Bedeutung ist.