Was sind Texturen

Werbung
Texturen – Inhalt
Inhaltsverzeichnis
1. Einleitung ......................................................................... 2
1.1 Vorwort ........................................................................ 2
1.2 Was sind Texturen ......................................................... 2
2. Texturverarbeitung in der Hardware ................................ 3
2.1 Point Sampling .............................................................. 3
2.2 Bilineares Filtern ............................................................ 4
2.3 MIP-Mapping ................................................................. 4
2.4 Trilineares Filtern ........................................................... 4
2.5 Multi-Texturing .............................................................. 5
2.6 Texturkompression ........................................................ 6
3. Texturen in Java 3D ......................................................... 7
3.1 Einleitendes Beispiel....................................................... 7
3.2 Texturoptionen ............................................................. 10
3.3 Texturattribute ............................................................. 12
3.4 Automatsiche Texturkoordinatenberechnung .................... 14
3.5 MIP-Maps .................................................................... 16
4. Programmbeispiele ........................................................ 17
5. Literaturverzeichnis ....................................................... 19
1
Texturen – Einleitung
1. Einleitung
1.1 Vorwort
Diese Ausarbeitung entstand im Rahmen der LVA Seminar Java 3D bei
Herrn Prof. Dr. Heinzel an der FH Fulda im WS 2002/2003.
Voraussetzung für das Verständnis ist grundlegende Kenntnisse in der
Grafikprogrammierung und der objektorientierten Programmierung. Des
weiteren empfehle ich die Dokumentation der Java 3D API als Referenz
zum Querlesen, da es den Rahmen dieser Ausarbeitung sprengen
würde, alle Details zu den vorgestellten Objekten, Methoden und
Attributen mit aufzunehmen.
Auch das Grundprinzip der Szenegraphen in Java 3D erleichtert das
Verständnis dieser Ausarbeitung.
1.2 Was sind Texturen?
Eine
Textur
ist
eine
zweidimensionale
Grafik,
die
durch
ein
Bitmapformat oder durch eine Schraffur, ein Raster oder ein Muster
definiert ist. Die Textur kann Oberflächenmerkmale verschiedenster Art
eines
Körpers
spezifizieren,
Materialeigenschaften.
Diese
vom
bloßen
Texturen
Aussehen
lassen
sich
bis
auf
hin
zu
definierte
Flächen(z. B. Polygone) in einem zwei- oder dreidimensionalen Raum
„legen“. Diesen Vorgang nennt man Textur-Mapping, wobei hier
zwischen diversen, mehr oder weniger komplexen Mapping-Verfahren
unterschieden wird.
Der Zweck des „Texturing“ liegt in einer realistischen Darstellung von
Objekten in zwei- oder dreidimensionalen Szenen, die dennoch relativ
effizient von der Hardware verarbeitet werden können.
2
Texturen in der Hardware
2. Texturverarbeitung in der Hardware
Da die Entwicklung bei 3D Grafikchips zügig voranschreitet und jeder
Hersteller seine eigenen, zusätzlichen 3D-Funktionen in die Chips
implementiert, werden im folgenden Abschnitt nur einige grundlegende
Funktionen hinsichtlich Texturierung beschrieben. Des Weiteren wird
auch nicht auf Spezialfunktionen von Grafikkarten für den High-EndBereich eingegangen. Auch lassen sich die meisten Funktionen in
Software-Texturing-Verfahren verwirklichen.
Der Anteil eines Grafikchips bei der Texturverarbeitung lässt sich
zunächst einfach deuten: Er liest die Texturen aus dem Grafik-, Hauptoder
Festplattenspeicher
und
legt
sie
auf
die
als
Polygonnetz
angelieferten Objekte. Dann folgt noch ein Tiefenvergleich bei mehreren
sich überschneidenden Objekten, um nur die Pixel auf dem Bildschirm
auszugeben, die tatsächlich sichtbar in der 3D-Welt erscheinen.
Ganz so einfach funktioniert das jedoch nicht, wenn man bedenkt, dass
sich ein 3D-Objekt vom Betrachter entfernen bzw. nähern oder drehen
kann.
2.1 Point Sampling
Das Point Sampling ist eine sehr einfache Methode der Texturierung.
Hierbei wird ein Bezug zwischen der Textur und dem Polygon
hergestellt. Der Farbwert des Texels (Textur-Element), dessen Position
der des Pixels des Polygons am Nächsten liegt, wird verwendet.
Ein Problem entsteht bei einer Differenz der Anzahl Texel und Pixel. Aus
großer Nähe überdeckt ein Texel gleich mehrere Pixel, dies führt zu
einer sehr groben Darstellung der Textur. Aus großer Distanz bleibt für
ein Texel kein ganzes Pixel mehr übrig, man muss ein Texel auswählen.
Dies führt unter Umständen zu einem Farbchaos, bei dem der
Betrachter keine sinnvolle Oberflächendarstellung mehr deuten kann.
3
Texturen in der Hardware
Pixel
Texel
mappin
mappin
g
g
Textur
Polygon
Textur
Abb. 1
2.2 Bilineares Filtern
Beim bilinearen Filtern oder auch bilinearen Textur-Mapping werden vier
Texel interpoliert auf ein Pixel abgebildet. Dadurch verwischen sowohl
grob dargestellte Texturen bei großer Nähe, als auch bunt flimmernde
Texturen bei großer Distanz zu einem gewissen Grad.
2.3 MIP-Mapping
Für
MIP-Mapping
stellt
man
jede
Textur
in
verschiedenen
Auflösungsstufen zur Verfügung. So kommt je nach Distanz zwischen
Betrachter und Objekt eine höher oder niedriger aufgelöste Version der
Textur zur Anwendung.
2.4 Trilineares Filtern
Das trilineare Filtern von Texturen ist eine Erweiterung des MIPMapping, das eine qualitativ hochwertige Darstellung von Texturen
ermöglicht. Falls sich ein Pixel zu nicht zu einer Auflösungsstufe
zuordnen lässt, wird zwischen zwei MIP-Maps gemittelt. Dazu werden
für ein Pixel die zwei MIP-Map-Werte durch bilineares Filtern ermittelt
und zwischen den daraus resultierenden Farbwerten wird durch eine
weitere Interpolation die Pixelfarbe bestimmt.
4
Texturen in der Hardware
2.5 Multi-Texturing
Die Möglichkeit, auf ein Polygon mehr als eine Textur zu legen, nennt
man Multi-Texturing. Eine Anwendung von Multi-Texturing ist zum
Beispiel
die
ursprüngliche
Simulation
Textur,
Hell/Dunkel-Muster
beliebiger
beispielsweise
(Lighting-Map)
Lichtverteilungen.
eine
gelegt.
Mauer,
Das
Auf
wird
Ergebnis
eine
nun
ein
ist
ein
statischer Lichteffekt, der jedoch durch Variation der Lighting-Map
dynamisch gestaltet werden kann.
Abb. 2
Weitere
Anwendungsgebiete
von Multi-Texturing sind das Bump-
Mapping (Simulation von Prägestrukturen) und das Enviroment-Mapping
(Simulation von Reflexionen auf glatten und metallischen Oberflächen).
Auch die Kombination beider Verfahren ist möglich.
5
Texturen in der Hardware
2.6 Texturkompression
Um den Speicherplatz und die Datenbandbreite möglichst gering zu
halten,
sind
in
Texturkompression,
den
oder
heutigen
besser
Grafikchips
gesagt
Verfahren
zur
Texturdekompression,
implementiert. Dadurch können mehr oder höher aufgelöste Texturen
verwendet werden. Die Texturen müssen allerdings der Software
komprimiert beiliegen. Sie werden komprimiert in den Grafikspeicher
transferiert und erst bei dem Zugriff ohne Geschwindigkeitsverlust
dekomprimiert.
6
Texturen in Java 3D
3. Texturen in Java 3D
Im folgenden Abschnitt möchte ich die Möglichkeiten der Verwendung
von Texturen in Java 3D zeigen. Zu Beginn wird die Entwicklung eines
einfachen Beispiels an Hand eines Rezeptes dargestellt, um die
prinzipielle Vorgehensweise der Texturierung zu veranschaulichen. Im
Anschluss daran gehe ich auf die Details der Java Texture API ein.
3.1 Einleitendes Beispiel
Um eine Textur überhaupt in Java 3D verwenden zu können, muss sie
in einem lesbaren Dateiformat und Auflösung vorliegen. Unterstützte
Dateiformate sind zum Beispiel JPEG und GIF, weitere Formate sind der
Sun-Website zu entnehmen. Die Auflösung in Pixel muss in der Breite
sowie der Höhe einer Zweierpotenz entsprechen, also 2n x 2m Pixel. Dies
liegt in dem binären Zahlenraum der Rechnersysteme begründet und
ermöglicht effizientes Rendering.
Ist die Textur in richtigem Format und richtiger Auflösung vorhanden,
wird sie mittels TexturLoader aus der Datei geladen. Dazu wird
zunächst ein TexturLoader-Objekt benötigt, dem bei der Instanzierung
der Dateinamen der Textur und ein Observer-Objekt übergeben wird.
TextureLoader loader = new TextureLoader(“brick.jpg”,
this);
ImageComponent2D image = loader.getImage();
Das Observer-Objekt überwacht den Ladevorgang der Grafik. Hierfür
wird das Applet (this) verwendet, in dem das Objekt dargestellt wird.
Ein ImageComponent2D-Objekt dient als Behälter für die Grafik.
7
Texturen in Java 3D
Im nächsten Schritt übergibt man das ImageComponent2D-Objekt an
ein Textur-Objekt. Bei der Instanzzierung des Texture2D-Objekts
werden vier Parameter übergeben.
Texture2D texture = new Texture2D(Texture.BASE_LEVEL,
Texture.RGBA, image.getWidth(), image.getHeight());
Der erste Parameter gibt MIP-Map-Modus an. Es gibt 2 Konstanten,
BASE_LEVEL
für
Standardtexturierung
mit
einer
Textur
in
fixer
Auflösung und MULTI_LEVEL_MIPMAP für die Verwendung von einer
Textur in mehreren Auflösungen (siehe Abschnitt MIP-Mapping).
Der zweite Parameter bestimmt die Genauigkeit des Farbwertes jedes
Texels und wie das Pixel, das den Texelwert bekommt, dargestellt wird.
Es werden sechs verschiedene Modi unterschieden (siehe TexturOptionen).
Der dritte und vierte Parameter bestimmt Breite und Höhe der Textur.
Appearance appear = new Appearance();
appear.setTexture(texture);
Mit der Instanzzierung eines Appearance-Objekts und der Übergabe des
Texture-Objekt an das Appearance-Objekt wird die Darstellung in der
Szene möglich.
Zum Schluss müssen die Texturkoordinaten gesetzt werden. Dazu muss
man wissen, dass die logischen Texturkoordinaten die Höhe und Breite
1.0 besitzen. Diese werden den Vertex-Koordinaten des Polygons
zugeordnet.
Die folgende Abbildung verdeutlicht diese Zuordnung, das eigentliche
Mapping.
8
Texturen in Java 3D
tc(1.0, 0.0)
tc(1.0, 1.0)
tc(0.0, 0.0)
tc(0.0, 1.0)
Abb. 3
Das
Code-Fragment
für
die
Zuweisung
der
Koordinaten
sieht
folgendermaßen aus.
/* Array für Geometriepunkte anlegen, um die Eckpunkte
* des Rechtecks
* festzulegen und Index der Eckpunkte erzeugen
*/
Point3f p = new Point3f(-1.0f, 1.0f, 0.0f);
plane.setCoordinate(0, p);
p.set(-1.0f, -1.0f, 0.0f);
plane.setCoordinate(1, p);
p.set(1.0f, -1.0f, 0.0f);
plane.setCoordinate(2, p);
p.set(1.0f, 1.0f, 0.0f);
plane.setCoordinate(3, p);
/* Mapping: Array für Texturkoordinaten anlegen und auf
* Rechteck legen
*/
Point2f q = new Point2f( 0.0f, 1.0f);
plane.setTextureCoordinate(0, q);
q.set(0.0f, 0.0f);
plane.setTextureCoordinate(1, q);
q.set(1.0f, 0.0f);
plane.setTextureCoordinate(2, q);
9
Texturen in Java 3D
Der Szenengraph für dieses Beispiel würde folgendermaßen aussehen:
BG
Simple
Universe
S
Appearance
Texture
Abb. 4
Nach diesem grundlegenden Beispiel sollen nun weitere Funktionen der
Java Texture API erläutert werden.
Der vollständige Quellcode dieses Beispiels „TexturTest“ liegt auf der
beiliegenden CD vor.
3.2 Texturoptionen
Die Option Boundary-Mode stellt eine sehr wichtige Funktion bei der
Texturierung von großen, homogenen Flächen dar. Sie bestimmt, wie
eine Textur auf ein Polygon gelegt wird, wenn die Textur nur eine
kleinen Teil des Polygons abdeckt. Es gibt zwei Modi, die mit folgenden
Konstanten initiiert werden:
-
WRAP -> Die Textur wird wie zum Beispiel Fliesen ohne Fugen
aneinander gelegt, bis das Polygon vollständig bedeckt ist
-
CLAMP -> Das Polygon wird jenseits der Textur mit den Farben
der Randpixel der Textur gefärbt
10
Texturen in Java 3D
Die Konstanten müssen für x- und y-Richtung, bzw. z-Richtung gesetzt
werden. Die geschieht mit den Methoden
-
void setBoundaryModeS (int boundaryModeS)
-
void setBoundaryModeT (int boundaryModeT)
-
void setBoundaryModeR (int boundaryModeR).
Mit der Option Boundary-Color kann der Programmierer Einfluss die
Farbe jenseits der Textur nehmen, wenn der Boundary-Mode auf CLAMP
gesetzt ist und die Textur kleiner als das Polygon ausfällt.
Die
Methoden lauten:
-
void setBoundaryColor (Color4f boundaryColor)
void setBoundaryColor (float r, float g, float b,
float a)
Die Filterung legt die Art und Weise fest, wie die Texel auf die Pixel des
Polygons abgebildet werden. Da in den seltensten Fällen eine direkte
Abbildung eines Texels auf ein Pixel möglich ist (siehe Abb. 1), kann der
Programmierer zwischen verschiedenen Abbildungsverfahren wählen.
Java 3D unterscheidet zum einen den Fall, dass das abzubildende Texel
größer als das Pixel ist (Magnification Filter) und zum anderen, dass das
abzubildende Texel kleiner als das Pixel ist (Mignification Filter). Die
Filter werden mit den Methoden
-
void setMagFilter (int magFilter)
void setMinFilter (int minFilter)
gesetzt.
11
Texturen in Java 3D
Die Konstanten lauten
-
BASE_LEVEL_POINT -> Die Farbe des nächstliegenden Texels wird
verwendet (vgl. Kapitel 2.1 Point Sampling)
-
BASE_LEVEL_LINEAR -> Der Farbwert der vier nächstliegenden Texel
wird interpoliert und als Pixelfarbe gesetzt (vgl. Kapitel 2.2 Bilienar
Filtern)
-
MULTI_LEVEL_POINT
-> Der Farbwert des nächstliegenden
Texels in der nächstliegenden MIP-Map wird verwendet.
-
MULTI_LEVEL_LINEAR -> Nur bei MIP-Mapping; der Farbwert der vier
nächstliegenden Texel wird von den zwei nächstgelegenen MIP-Maps
ermittelt. Anschließend erhält der Pixelwert den zwischen den MIP-MapTexeln interpolierten Wert (vgl. Kapitel 2.4 Trilineares Filtern)
Das Format bestimmt die Genauigkeit des Farbwertes jedes Texels. Eine
Aufstellung der Konstanten, die bei der Instanzzierung des TexturObjekts angegeben werden, zeigt die folgende Tabelle:
3.3 Texturattribute
Texturattribute haben den Vorteil, dass sie Änderungen an der Optik
von Texturen durchführen, diese Attribute jedoch in einem separaten
Objekt (TextureAttribute) definiert werden. Der Programmierer kann
somit
eine
Textur
laden,
aber
unterschiedlich
Darstellen
durch
verändern der TextureAttributes.
12
Texturen in Java 3D
Abb. 5
Der Konstruktor, um alle Attribute eines TexturAttribute-Objekts zu
setzen benötigt vier Parameter.
-
TextureAttributes (int textureMode, Transform3D
transform, Color4f textureBlendColor, int
perspCorrectionMode)
Mit dem Attribut textureMode beeinflusst der Programmierer die Farbdarstellung
des
texturierten
Objekts.
Die
Standardeinstellung
ist
REPLACE, d. h. die Pixelfarbe = Texelfarbe. Die Tabelle zeigt alle
möglichen Modi:
Die Methode void setTextureMode (int textureMode) ändert die
Konstante textureMode.
Das Attribut textureBlendColor wirkt sich nur dann auf die Darstellung
aus,
wenn
der
Texture-Mode
setTextureBlendColor
(Color4f
BLEND
gesetzt
textureBlendColor)
ist.
Mit
manipuliert
void
der
Anwender die Texturdarstellung.
13
Texturen in Java 3D
Wenn eine Textur auf ein Polygon gemappt wird, das schräg zum
Betrachter erscheint, führt Java 3D eine Korrektur der Perspektive vor.
Dies
wird
standardmäßig
aufwendig,
aber
mit
guter
Qualität
durchgeführt (Konstante NICEST). Wünscht man schnelleres Rendering
zu lasten der Qualität, setzt man das Attribut mit der Methode void
setPerspectiveCorrectionMode (int mode) auf FASTEST.
Das letzte Attribut beeinflusst die Textur an sich. Mit der Methode void
setTextureTransform (Transform3D transform) kann der Programmierer zur Laufzeit die Textur verschieben, rotieren und skalieren, in
dem er ein Transform3D-Objekt mit den gewünschten Transformationen
an das TextureAttribute übergibt.
3.4 Automatische Texturkoordinatenberechnung
Gerade bei sehr komplexen Szenen mit mehreren Polygonen muss der
Programmierer viel Aufwand betreiben, um die Texturkoordinaten auf
die Polygonkoordinaten zu transferieren (vlg. 3.1 Einleitendes Beispiel).
Um
diese
„Schreibarbeit“
zu
verringern,
wurde
die
Klasse
TexCoordGeneration in der Java 3D API implementiert.
Die Instanzzierung der TexCoordGeneration Klasse kann parameterlos
(Standardwerte
werden
verwendet)
oder
mit
Angabe
von
Generierungsformat und Texturformat erfolgen.
-
TexCoordGeneration ()
-
TexCoordGeneration (int genMode, int format)
14
Texturen in Java 3D
Die Anbindung an den Szenengraph wird in Abbildung 6 dargestellt.
Abb. 6
Der Parameter format bestimmt, ob die Textur eine 2D- oder 3D-Textur
ist (Standardwert ist 2D-Textur).
Interessanter ist der Parameter genMode, der die folgenden drei
Variationen kennt:
-
OBJECT_LINEAR -> Die Textur, die auf das Polygon gelegt
wird,
bewegt
sich
mit
dem
Objekt
(statische
Texturkoordinaten)
-
EYE_LINEAR -> Das Objekt, auf dem die Textur liegt, wird
unter der Textur gedreht (variable Texturkoordinaten)
-
SPHERE_MAP -> Die Texturkoordinaten werden dynamisch aus
der
Oberflächennormalen
und
der
Betrachtungsrichtung
berechnet (dynamische Texturkoordinaten)
Für
eine
ausführliche
Beschreibung
der
Methoden
und
Attribute
verweise ich auf das Sun Programmierreferenz zur Java 3D API.
15
Texturen in Java 3D
3.5 MIP-Maps
Java 3D unterstützt das bereits in Kapitel 2.3 erwähnte Multiple-LevelTexturing (MIP-Mapping). Dahinter steckt ein Verfahren, das eine
Textur von beispielsweise 128 x 128 Pixel Auflösung in der Größe so
lange geviertelt wird (Länge und Breite werden halbiert), bis die Textur
in der Auflösung 1 x 1 Pixel vorliegt. Alle zwischendurch erzeugten
Texturen werden gespeichert, so dass Texturen in den Größen 128 x
128, 64 x 64, ..., 1 x 1 vorliegen. Je nach der Distanz des Betrachters
zum texturierten Objekt in der Szene wird ein höher oder niedriger
aufgelöste Textur verwendet.
Die unterschiedlichen Auflösungsstufen der Textur können in einer
kleinen Schleife erstellt werden.
while (imageWidth > 1 || imageHeight > 1){
imageLevel++;
if (imageWidth > 1) imageWidth /= 2;
if (imageHeight > 1) imageHeight /= 2;
image = loader.getScaledImage(imageWidth,
imageHeight);
texture.setImage(imageLevel, image);
}
Zu beachten ist hierbei, dass bei der Instanzzierung des TextureObjekts der erste Parameter den MIP-Map-Modus initialisiert.
Texture2D texture = new
Texture2D(Texture.MULTI_LEVEL_MIPMAP,
Texture.RGB, imageWidth, imageHeight);
Weiterhin
sind
die
Texturoptionen
(vgl.
Kapitel
3.2)
hinsichtlich
Filtereinstellungen für den Minification-Filter auf MULTI_LEVEL_POINT
oder MULTI_LEVEL_LINEAR anzupassen.
16
Beispiele
4. Beispiele
Ein gutes Beispiel für die Wirkung der verschiedenen Optionen und
Attribute auf eine Textur ist eine Art Tutorial von Henry A. Sowizral und
David R. Nadeau.
In dieser Sammlung von Klassen befindet sich die Datei ExTexture.java,
die einen 3D-Würfel in einer Szene darstellt. Über diverse Menüpunkte
lassen sich Attribute und Optionen interaktiv verändern. Mit der Maus
kann der Benutzer den Würfel in der Szene drehen, zoomen, usw..
Diese Sammlung von Klassen befindet sich unter der Internetadresse
http://www.sdsc.edu/~nadeau/Courve/Siggraph99
Aufmerksam wurde ich auf dieses Beispiel durch meinen Mitstudent
Stefan Dubois.
17
Beispiele
Jicasso – Visuelle Java 3D Programmierung
Das Tool Jicasso von Colin Mummery ermöglicht die visuelle Erstellung
von 3D Objekten in einer Szene. Der Benutzer kann diverse graphische
Primitive einer Szene hinzufügen und anschließen Licht, Textur,
Hintergrund usw. modifizieren.
Einschränkungen macht das Tool bezüglich des generierten Quelltextes.
Die (hier getestete) Shareware-Variante erzeugt lediglich BinärcodeDateien, so dass ich über die Qualität des erzeugten Quellcodes keine
Aussage machen kann.
Das Tool liegt in einer Betaversion der CD bei, im Internet findet man es
unter der Adresse http://www.cellspark.com/jicasso.html
18
Literarturverzeichnis
5. Literaturverzeichnis:
-
M. Bertuch – Polygonfabriken – Artikel aus C’T 8/2000, S.202f,
Heise-Verlag
-
F. Angulanza, M. Mayr, C. Osterrieder – Texturen in Java 3D –
Vortrag vom 02.07.2002, Quelle:
http://www.cosy.sbg.ac.at/graphics_I/ps_pdf_ppt/angulanza_e
t_al.pdf
-
S. P. Häuser – Definition und Darstellung von Texturen –
Studienarbeit vom 23.07.1997, Quelle:
http://www.ncstrl.informatik.uni-stuttgart.de/Dienst/UI/2.0/De
scribe/medoc.ustuttgart_fi/STUD-1628
-
Java 3D Tutorial v 1.5 von SUN, Quelle:
http://developer.java.sun.com/developer/onlinetraining
19
Herunterladen