DirectX – Graphics
Fortgeschrittene Techniken
Lichtberechnung - Basics
Vertexbasiertes Licht
• DirectX – Standardmethode
• Farbe eines Polygons ergibt sich aus dem Licht, dem
seine Vertices ausgesetzt sind
• hohe Performance der Berechnung
• Problem:
– bei zu großen Polygonen kann es passieren, dass die Vertices
nicht mehr vom Licht erreicht werden
dies gilt allerdings nur für Lichtquellen mit begrenzter Reichweite
Lichtberechnung - Basics
Pixelbasiertes Licht
• pixelbasierte Verfahren errechnen für jedes Pixel eines
Polygons dessen Normalenvektor
• dieser dient dann als Grundlage für die Lichtberechnung
realistische Lichtberechnung
allerdings sehr arbeitsintensive Berechnungen
Lichtberechnung - Basics
Lichtarten
• Ambientes Licht
– dient der gleichmäßigen Ausleuchtung einer Szene =>
Grundbeleuchtung
– Lichtfarbe wird festgelegt und Licht eingeschaltet
//Einschalten
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
//Lichtfarbe
g_pd3dDevice->SetRenderState(D3DRS_AMBIENT,
D3DCOLOR_XRGB(150, 150, 150);
Lichtberechnung – Basics
Direkte Lichtquellen
• Directional Light
– paralleles Licht mit unendlicher Reichweite
• Point Light
– breitet sich von einer Punktlichtquelle in alle Richtungen mit begrenzter
Reichweite aus
• Spot Light
– bsw. Lichtkegel einer Taschenlampe
Lichtberechnung - Basics
Lichteigenschaften werden in der D3DLIGHT9 – Struktur
gespeichert:
Lichtberechnung - Basics
Farbanteile des Lichtes werden in der D3DCOLORVALUE
- Struktur gespeichert
Werte > 1 erzeugen ein sehr helles Licht
Werte < 0 entziehen der Szene den jeweiligen Farbanteil
Lichtberechnung
Lichtreflektion an einer Oberfläche
• Helligkeit abhängig vom
Einfallswinkel
• je größer der Winkel, desto
geringer die Helligkeit
• wahrgenommene Intensität
unabhängig von der Position
des Betrachters, da Licht in
viele verschiedene
Richtungen reflektiert wird
(Oberflächenbeschaffenheit)
Lichtberechnung
weitere Reflektionsarten
• spiegelnde Reflektion
– abhängig von der Materialoberfläche (Spiegel vs. Stein)
– wahrgenommene Intensität abhängig von der relativen Position
des Betrachters zur Lichtquelle
• ambiente Reflektion
– Licht ohne spezielle Richtung
– wird ständig „hin und her“ reflektiert
– Reflektion unabhängig von der Orientierung der Oberfläche =>
Licht kommt aus allen Richtungen
– bsw. Helligkeit trotz Wolken
Lichtberechnung
• abhängig von der Temperatur eines Körpers kann dieser
auch selbst Licht aussenden (bsw. Weißglut)
Materialeigenschaften wie diese werden in der
D3DMATERIAL9 – Struktur gespeichert
Shading - Verfahren
Flat – Shading
• Lichtberechnung aufgrund des Oberflächennormalenvektors
• wegen vertexbasierter Berechnung, muss Normalenvektor
den Vertices zugewiesen werden
gesamtes Polygon wird einheitlich schattiert
kantige Farbverläufe zwischen Polygonen
dafür sehr schnelles Verfahren
Shading - Verfahren
Gouraud – Shading
•
DirectX – Standardverfahren
1. Berechnung der Lichtintensität der Vertices
2. Interpolation der Farbverlaufs aufgrund dieser Werte
die Beleuchtung des Polygons ist dann einheitlich,
wenn sowohl Beleuchtung als auch Normalenvektoren
aller Vertices gleich sind
Shading - Verfahren
Vertexstrukturen
• D3DFVF_NORMAL =>
Vertexbeleuchtung durch
DirectX
• D3DFVF_TEX2 => 2 Sätze
von Texturkoordinaten
werden verwendet
Multitexturing
• Erscheinungsbild eines Polygons resultiert aus der
Kombination von Licht – und Texelfarbe (Farbe jedes
Texturpixels)
• DirectX bietet viele verschiedene Kombinationsverfahren
• Beispiel Farbbestimmung bei einer Textur (0. Stufe)
// 1. Farbargument ist Texelfarbe
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,
D3DTA_TEXTURE)
// 2. Argument ist diffuse Streulichtfarbe
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,
D3DTA_DIFFUSE)
// Multiplikative Verknüpfung
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,
D3DTOP_MODULATE)
Multitexturing
DirectX – Farboperationen
Konstante
Vorgehen
Effekt
D3DTOP_MODULATE
Arg1 * Arg2
D3DTOP_MODULATE2X
(Arg1 * Arg2) * 2
Aufhellung
D3DTOP_MODULATE4X
(Arg1 * Arg2) * 4
Aufhellung
D3DTOP_ADDSIGNED
Arg1 + Arg2 - 0,5 Angenehmer Hell
– Dunkel Kontrast
D3DTOP_ADDSIGNED2X
(Arg1 + Arg2 –
0,5) * 2
kräftiger Hell –
Dunkel Kontrast
Multitexturing
• verwendet man mehrere Texturstufen (= mehrere
Texturen) wird die Farbe der nächst kleineren Texturstufe
zum 2. Farbargument
bsw. Ergebnis der Farboperation der 0. Stufe wird zum
Farbargument der 1. Stufe usw.
• DirectX erlaubt die Verwendung von bis zu 8
Texturstufen
Multitexturing
Detailmapping
• dient einer Vergrößerung des Polygondetailreichtums
• Strukturtextur wird bsw. als 1. Texturstufe auf das Polygon
gemappt
// 2. Satz Texturkoordinaten verwenden
g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,
1);
// 1. Argument ist Texelfarbe der Detailtextur
g_pd3dDevice->SetTextureStageState (1, D3DTSS_COLORARG1,
D3DTA_TEXTURE);
// 2. Argument ist Ergebnis der Farboperation der 0. Texturstufe
g_pd3dDevice->SetTextureStageState (1, D3DTSS_COLORARG2,
D3DTA_CURRENT);
// als Farboperation wird D3DTOP_ADDSIGNED verwendet
g_pd3dDevice->SetTextureStageState (1, D3DTSS_COLOROP,
D3DTA_ADDSIGNED);
Multitexturing
Glowmapping
•
dient der Simulierung einer zusätzlichen Beleuchtung
einer Polygonfläche
•
2 Möglichkeiten
1.
2.
Berücksichtigung der Streulichtfarbe der eingeschalteten
Lichtquellen
zur Beleuchtung wird ausschließlich die Lightmap – Textur
verwendet
Def.: Lightmap – Textur ist ein
Bitmap,
welches bsw. einen Lichtkegel
darstellt:
Multitexturing
Darkmapping
• dient der Abdunklung einer Textur
• wird durch die Farboperation D3DTOP_MODULATE
erreicht
Zurücksetzen der Farboperationen nach dem Rendern:
• Standard 0. Texturstufe:
g_pd3dDeviceSetTextureStageState(0, D3DTSS_COLOROP,
D3DTOP_MODULATE)
• Standard aller weiteren Stufen
g_pd3dDeviceSetTextureStageState(Nr , D3DTSS_COLOROP,
D3DTOP_DISABLE)
Multitexturing
Konstanten und ihre Bedeutung:
Konstante
Effekt
D3DTOP_ADD
Addition beider Farbargumente
D3DTA_CURRENT
Ergebnis der vorherigen Farboperation
D3DTA_TEXTURE
Texelfarbe der aktuellen Texturstufe
D3DTOP_SELECTARG1
als Farbargument der Operation wird nur die
aktuelle Texelfarbe verwendet
D3DTA_COLORARG1
1. Farbargument
D3DTSS_TEXCOORDIND x. Texturkoordinatensatz wird verwendet
EX, x
Konstanten für Farboperationen vs. Konstanten zur Farbargumentfestlegung
Texturfilterung
Techniken
• bilineare Filterung
• anisotrope Filterung
• bilineare Texturfilterung mit einfachem Mipmap – Wechsel
• trilineare Texturfilterung (bilineare Filterung zwischen
verschiedenen Mipmaps „sanftes Überblenden“)
• anisotrope Filterung
Filterungsverfahren dienen der Qualitätsverbesserung bei
der Skalierung der 3D – Objekte und damit der Texturen
Filterverfahren sind bei der Skalierung darum notwendig,
weil Texelfarben bei Vergrößerung / Verkleinerung
interpoliert werden müssen
Texturfilterung
• die bilineare Filterung interpoliert einen neuen Texelwert
aus den Farbwerten in x – und y – Richtung um das
betreffende Basistexel
speziell bei perspektivischen Darstellungen erbringt
dieses Verfahren allerdings schlechte Ergebnisse
die trilineare Filterung interpoliert aus 2 bilinear
gefilterten Farbwerten einen Endwert => die 2
Basisfarbwerte stammen von den Texelfarben zweier
benachbarter Mipmap – Stufen
beim Übergang einer Mipmap zur nächsten wird die
Texelfarbe aus beiden Mipmaps interpoliert
Texturfilterung
• anisotrope (uneinheitliche) Filterung
– während die trilineare Filterung alle Texel gleichmäßig abtastet,
berücksichtigt die anisotrope Filterung den Winkel, mit dem man
auf eine Textur blickt
– dadurch erhöht sich die Bildqualität
– allerdings ist die Berechnung relativ zeitaufwendig
Texturfilterung
Filtertechniken / wichtige Konstanten:
Konstante
Effekt
D3DSAMP_MINFILTER
Filtertyp, der bei der Verkleinerung einer
Textur eingesetzt wird
D3DSAMP_MAGFILTER
Filtertyp, der bei der Vergrößerung einer
Textur eingesetzt wird
D3DTEXF_LINEAR
bilineare Texturfilterung
D3DTEXF_ANISOTROPIC
anisotropische Filterung
D3DSAMP_MAXANISOTR
OPY, AnzSufen
Festlegung der Maximalstufe der
anisotropen Filterung =>
hardwareabhängig
Texturfilterung
Filtertechniken / wichtige Konstanten:
Konstante
Effekt
D3DSAMP_MIPFILTER
Mipmap – Filteroptionen festlegen
D33DTEXF_NONE
bilineare Filtern ohne Mipmap – Wechsel
D3DTEXF_POINT
bilineares Filtern mit einfachem Mipmap –
Wechsel
D3DTEXF_LINEAR
trilineare Texturfilterung => bilineare
Filterung zwischen Mipmaps
Beispiel:
g_pd3dDevice->SetsamplerState(NrTexturStufe, D3DSAMP_MIPFILTER,
D3DTEXF_LINEAR);
Erzeugung von 3D - Objekten
• einfache 3D – Objekte lassen sich von einer
mathematischen Grundform ableiten bsw. Kugel
• dadurch lässt sich die Konstruktion solcher Objekte
algorithmisch formulieren
man muss eine mathematische Formulierung finden, die
den Aufbau eines komplexen Objektes aus einzelnen
Polygonen erreicht
zur Speicherung der Vertex – Koordinaten verwendet
man eine indizierte Dreiecksliste
Erzeugung von 3D - Objekten
Indizierte Dreieckslisten
• neben einem Vertexbuffer benötigt man einen
Indexbuffer, in dem die Positionen der Vertices in einer
festgelegten Reihenfolge vorliegen
• erzeugt man ein Polygon, werden dessen Vertex –
Koordinaten in den Indexbuffer geschrieben
• Vorteil: einzelne Vertices können mehrfach verwendet
werden
haben 2 Polygone eine gemeinsame Kante, haben sie
auch 2 gemeinsame Vertices
statt 6 Vertices, müssen nur 4 berechnet werden
Erzeugung von 3D - Objekten
Verwenden einer indizierten Dreiecksliste
• Indexdaten werden meist zunächst in temporärem
Indexarray gespeichert und dann in den Indexbuffer
kopiert
• Indexbuffer wird durch CreateIndexBuffer(…) erzeugt
g_pd3dDevice->CreateIndexBuffer(AnzIndices*sizeof(WORD),
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
D3DPOOL_MANAGED, &PlanetIB, NULL );
Erzeugung von 3 - Objekten
Erzeugung eines Indexbuffers
• bei der Erstellung eines 3D –
Objekts definiert man die Position
der einzelnen Polygone als 2D –
Projektion des Objekts in eine
Ebene (bsw. Kugel => Weltkarte)
dadurch bleibt die relative
Anordnung der Polygone
zueinander gleich
• in dieser Ebene verwendet man
üblicherweise Quads
• die Eckpunktindices der
Basisdreiecke werden im
Uhrzeigersinn in das Indexarray
geschrieben
Erzeugung von 3D - Objekten
Erzeugung eines Indexbuffers
• das Problem liegt darin, eine mathematische
Formulierung zu finden, die die gesuchte geometrische
Grundform beschreibt
• Beispiel Kugel:
x = radius * sin(Vertikalwinkel) * sin(Horizontalwinkel);
y = -radius * cos(Vertikalwinkel);
z = radius * sin(Vertikalwinkel) * cos(Horizontalwinkel);
Erzeugung von 3D - Objekten
Erzeugung einer Kugel
• mit den vorherigen Gleichungen kann man nun eine Schleife
bauen, die den Kugelindexbuffer initialisiert:
for( zeilenNr = 0; zeilenNr < AnzVerticesSpalte; zeilenNr++)
{
for( spaltenNr = 0; spaltenNr < AnzVerticesZeile; spaltenNr++)
{
pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].position =
D3DXVECTOR3(Radius*sinf(zeilenNr*RingTeilwinkel)*sinf(spalte
nNr*SegmentTeilwinkel), -Radius*cosf(zeilenNr*RingTeilwinkel),
Radius*sinf(zeilenNr*RingTeilwinkel)*cosf(spaltenNr*SegmentTeil
winkel));
}
}
Erzeugung von 3D - Objekten
Rendern einer indizierten Dreiecksliste
1. Übergabe von Index – und Vertexbuffer an DirectX
g_pd3dDevice->SetStreamSource(0, PlanetModell->PlanetVB, 0,
sizeof(SPACEOBJEKT3DVERTEX));
g_pd3dDevice->SetIndices(PlanetModell->PlanetIB);
2.
Zeichnen der indizierten Dreiecksliste
g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,
0, PlanetModell->AnzVertices,
0, PlanetModell->AnzTriangles)
zeichnet alle Dreiecke vom Anfang bis zum Ende des
Indexbuffers
es können auch nur bestimmte Dreiecke des
Indexbuffers gezeichnet werden
Alpha - Blending
• dient der Darstellung von Transparenzeffekten
• um Darstellungsfehler zu vermeiden, müssen alle
transparenten Objekte in Back – to – Front Order
gerendert werden => zuerst die am weitesten entfernten
Objekte
• Objekte ohne Transparenzeigenschaften müssen
entweder vorher oder auch Back – to – Front gerendert
werden
2. Möglichkeit deutlich rechenintensiver, dafür keine
Darstellungsfehler
Alpha - Blending
• zunächst Sortierung der Objekte notwendig
• Verwendung von qsort() => basiert auf Quick – Sort –
Algorithmus
• qsort() ruft Callback – Methode ObjektSortCB() auf
diese Funktion legt fest, wie die Objekte sortiert werden
sollen
Alpha - Blending
• Alpha Blending erzeugt Mischfarben aus den
Texelfarben des transparenten Objekts und den Farben
der Hintergrundpixel
da die Farben der Hintergrundpixel vorhanden sein
müssen, müssen weit entfernte Pixel zuerst gerendert
werden
Def.:
• Texelfarbe des transparenten Objekts: Quellfarbe
(source color)
• Farbe der Hintergrundpixel: Zielfarbe (destination color)
Alpha - Blending
Konstante
Bedeutung
D3DBLEND_SRCALPHA
Alphakomponente => Grad der
Transparenz 0.0f = 100% Transparenz,
1.0f = 0% Transparenz
D3DBLEND_INVSRCALPHA 1 - Alphakomponente
• bei 100% Transparenz gilt: Mischfarbe = Hintergrundfarbe
• bei 0% Transparenz gilt: Mischfarbe = Texelfarbe
• allgemein gilt: Mischfarbe = Texelfarbe * Alpha +
Hintergrundfarbe * (1 – Alpha)
• den Grad der Transparenz legt man bei den Materialeigenschaften
fest bsw. mtrl.Diffuse.a = 0.6f => 40% Transparenz
Alpha - Blending
verschiedene Mischoperationen für Alpha – Blending:
Konstante
Bedeutung
D3DTSS_ALPHAOP
Festlegen der Operationsmethode
D3DTOP_MODULATE
ARG1 * ARG2
D3DRS_DESTBLEND, 2
Mischfarbe = Texelfarbe + Hintergrundfarbe =>
keine Verwendung der Alphakomponenten
Standardeinstellungen:
• 0. Texturstufe: D3DTOP_SELECTARG1 => nur
Alphawerte der Texel werden berücksichtigt
• weitere Stufen: D3DTOP_DISABLE
Fragen?