380 likes | 557 Views
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 :
E N D
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 • Berechnung der Lichtintensität der Vertices • 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
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 • 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: 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:
Texturfilterung Filtertechniken / wichtige Konstanten: 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 • Übergabe von Index – und Vertexbuffer an DirectX • g_pd3dDevice->SetStreamSource(0, PlanetModell->PlanetVB, 0, sizeof(SPACEOBJEKT3DVERTEX)); g_pd3dDevice->SetIndices(PlanetModell->PlanetIB); • 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 • 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: Standardeinstellungen: • 0. Texturstufe: D3DTOP_SELECTARG1 => nur Alphawerte der Texel werden berücksichtigt • weitere Stufen: D3DTOP_DISABLE