Kapitel 9.3 Dot3-Bumpmapping (Normalmapping). Bumpmaps Textur, deren Pixel unterschiedlich auf einfallendes Licht reagieren Betrachter hat den Eindruck,

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

Klassen - Verkettete Liste -
Präsentation PS: Klasse File von Janko Lange, Thomas Lung, Dennis Förster, Martin Hiller, Björn Schöbel.
Kapitel 9: Graphdurchlauf
Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure.
Kurt Rosenberg. C# für.NET oder.NET für C# is(C# == C++ && Java)? true : false ; reines C# Ausblick Überblick.
PKJ 2005/1 Stefan Dissmann Vorwoche - Klasse public class Studierende { private String name, vorname, studiengang; private int matNr, semester; private.
Progwerkstatt JAVA Klasse, Objekte, Konstruktoren, Methoden
Trigonometrische Funktionen
Environment Mapping.
Kapitel 9.4 Blooming (Postprocess-Effekt). Postprocess-Effekte 2D-Effekte Werden auf das gerenderte Bild im Framebuffer angewendet Beispiele: Bewegungsunschärfe.
Intelligente Dateisysteme Einführende Bemerkungen Manfred Thaller, Universität zu Köln Köln 17. Oktober 2013.
Elemente der 3D-Grafikprogrammierung
Geometrie in DirectX: Vektoroperationen Kapitel – Spieleprogrammierung mit DirectX und C++ Kaiser/Lensing.
Prof. Dr.-Ing. habil. B. Steinbach - Informatik / Softwaretechnologie und Programmierungstechnik - Institut für Informatik F Verteilte Software - Java.
Verteilte Software - Java - Prozedurale Programmierung 1
Objektrelationales Mapping mit JPA Entity Mapping Jonas Bandi Simon Martinelli.
Binäre Bäume Richard Göbel.
FH-Hof Texturen Richard Göbel. FH-Hof Anwendungen von Texturen Darstellung von 2D-Bildern Gestaltung von Oberflächen Simulation komplexer Geometrien...
FH-Hof Texturen Richard Göbel. FH-Hof Anwendungen von Texturen Darstellung von 2D-Bildern Gestaltung von Oberflächen Simulation komplexer Geometrien...
Bilder und Rasterdaten
Java: Grundlagen der Objektorientierung
Ein Beispiel in Java.
Konstruktoren.
Assoziationen (Beziehungen) 1 : n. Zu einem Auto gibt es mehrere Fahrer (2) und zu diesen 2 Fahrern gibt es genau dieses Auto.
Polymorphie (Vielgestaltigkeit)
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
Shaderprogrammierung T. Goeschel + F. Theilacker
Positionierung und Ausrichtung der Kamera. void balance::kamera_bewegen( float seit, float hoch, float vor) { D3DXVECTOR3 v, s, h, t; v = da_gucke_ich_hin.
Spieleprogrammierung mit DirectX und C++
V03 Laden und Speichern von Spielfeldern und der Spielfeldeditor.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Oliver Rahner – Hauptseminar Computer Graphics, SS 2007 computer graphics & visualization DirectX 10 API Neuerungen in Direct3D 10.
Java3d „Licht und Material“
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
DVG Einführung in Java1 Einführung in JAVA.
DVG Methoden 1 Methoden. 2 int dezi = Integer.parseInt(args[0]); boolean vz = (dezi>=0); dezi = Math.abs(dezi); String Bin = ""; do { } while.
DVG Verkettete Listen Verkettete Listen. DVG Verkettete Listen 2 Primitive Datentypen Vorteile: –werden direkt vom Prozessor unterstützt.
Special Effects Realistischeres Rendern einer Scene.
Light and Color in Nature
Balance V01 Der Windows-Rahmen S Vortrag von Lisa Rau.
FH-Hof Sortieren mit Binären Bäumen Richard Göbel.
(additives Farbmischen)
Die Ableitung im.
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Grafikformate Nicolas Ruh.
Universität zu Köln Institut für Historisch-Kulturwissenschaftliche Informationsverarbeitung Prof. Dr. Manfred Thaller AM 3 Übung: Softwaretechnologie.
OO implementieren Teil IV Objekte erzeugen. © René ProbstModul 226IV - 2 Von der Klasse zum Objekt Plan Bau Objekt Klasse Instanzierung Objekt Das Objekt.
Java Performance Tuning Performance Tuning is similar to playing a strategy game but happily you usually get paid for it.
3D- Spieleprogrammierung
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Von der Planung bis zum Hauptmenü Seminar: Softwaretechnologie II Dozent: Prof. Manfred Thaller Referent: Jan Bigalke.
How to make a Pixar Movie
Grundlagen der Programmierung
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Informatik 1 Letzte Übung.
Abteilung für Telekooperation Übung Softwareentwicklung 2 für Wirtschaftsinformatik Dr. Wieland Schwinger
Equals, Hashcode und CompareTo Micha Kessler
Bildbearbeitung Nicolas Ruh.
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 1 Algorithmen und Datenstrukturen Übungsmodul 5 Dr. W. Narzt u. Dr. A. Stritzinger.
Beleuchtungsmodelle, Schattierungsmodelle
CuP - Java Neunte Vorlesung Entspricht Kapitel 4.2 und 5 des Skriptums
C++ SFINAE inkl. std::enable_if
Erfahrungen mit Microsoft DirectX 8 W. Krug, April 2002.
Einführung Blue J. Inhaltsverzeichnis  Definition  Vokabeln.
Java Programme nur ein bisschen objektorientiert.
Tutorium Software-Engineering SS14 Florian Manghofer.
 Präsentation transkript:

Kapitel 9.3 Dot3-Bumpmapping (Normalmapping)

Bumpmaps Textur, deren Pixel unterschiedlich auf einfallendes Licht reagieren Betrachter hat den Eindruck, dass ein Objekt detailreicher sei Aber: die Geometrie des Objekts ändert sich nicht (z. B. an der Silhouette des Objekts zu erkennen) Es gibt zwei Arten von Bumpmaps: Heightmaps und Normalmaps

Heightmaps Graustufen-Texturen, in denen Tiefenwerte codiert sind, welche dann zur Berechnung der Schattierung herangezogen werden

Normalmaps In der Textur werden die Normalen gespeichert 3 Farbkanäle: RGB Jeder Kanal steht für eine Dimension der Normale Bsp: liegt eine Textur in der XY-Ebene, so repräsentiert der Rot-Anteil die X-Richtung der Grün-Anteil die Y-Richtung der Blau-Anteil die Z-Richtung der Normale

Tangentenraum Aber: Farb-Achsen-Zuordnung ist relativ Bei Bewegung des Objekts müssen sich die Normalen der Textur auch mit bewegen Für jedes Polygon des Objekts muss also ein eigenes Koordinatensystem erstellt werden Die Normale der Fläche des Polygons entspricht dann der logischen Z-Richtung der Normalmap (Blau-Anteil) So ein Koordinatensystem nennt man Tangentenraum und die Achsen bezeichnet man als: Tangente (rot), Binormale (grün), und Normale (blau) U V Textur Die Tangente ist parallel zur U-Achse der Textur und die Binormale ist parallel zur V-Achse

Die Effektdatei Benötigte Parameter // Matrizen float4x4 MatWVP : WorldViewProjection; float4x4 MatViewInv : ViewInverse; float4x4 MatWorld : World; //Direktionale Lichtquelle float3 LightDir : Direction; float4 LightColor : Diffuse; float4 LightAmbient : Ambient; //Materialien float4 MtrlDiffColor : Diffuse; float4 MtrlSpecColor: Specular; float MtrlSpecPower : SpecularPower; Texture TexDiffuse : Diffuse;//Diffusemap Texture TexNormal : Diffuse;//Normalmap

Textursampler sampler SamplerDiffuse = sampler_state { texture = ; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; sampler SamplerNormal = sampler_state { texture = ; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; Sampler für die Diffusemap Sampler für die Normalmap

Vertexshader Ein- und Ausgabestrukturen struct VertexInput { float3 Position: POSITION; float3 Normal: NORMAL; float2 Tex0: TEXCOORD0; float3 Tangent: TANGENT; float3 Binormal: BINORMAL; }; struct VertexOutput { float4 HPosition: POSITION; float2 TexCoord: TEXCOORD0; float3 HalfVector: TEXCOORD2; float3 Normal: TEXCOORD3; float3 Tangent: TEXCOORD4; float3 Binormal: TEXCOORD5; }; Eingangsstruktur für den Vertexshader Ausgabestruktur

Vertexshader VertexOutput VS_Main( VertexInput IN ) { VertexOutput OUT; float3 PosWorld; float3 CamPosWorld; float3 CamDirToPos; float3 HalfVector; CamPosWorld= MatViewInv[3].xyz; PosWorld= mul( float4(IN.Position.xyz, 1.0), MatWorld ); CamDirToPos= normalize( PosWorld - CamPosWorld ); HalfVector= -(LightDir+CamDirToPos); OUT.Normal= normalize( mul( IN.Normal, (float3x3) MatWorld ) ); OUT.Tangent= normalize( mul( IN.Tangent, (float3x3) MatWorld ) ); OUT.Binormal= normalize( mul( IN.Binormal, (float3x3) MatWorld ) ); OUT.HPosition = mul( float4(IN.Position.xyz, 1.0), MatWVP); OUT.TexCoord = IN.Tex0; OUT.HalfVector = HalfVector; return OUT; } Transformieren der Tangente, Normale und Binormale in das Weltkoordinatensystem (alle Achsen des Tangentenraums werden mit der Weltmatrix multipliziert)

Pixelshader float4 PS_Main( VertexOutput IN ) : COLOR { float3 Normal; float4 Diffuse; float4 Specular; float3 HalfVec; float3 Light; float Intensity; float3x3 MatTex; HalfVec = normalize(IN.HalfVector); //Normalisierung des Halbvektors MatTex = float3x3( IN.Tangent, -IN.Binormal, IN.Normal ); //Tangente, (negierte)Binormale und Normale in Matrix einsetzten Normal = 2.0f * tex2D(SamplerNormal, IN.TexCoord).rgb - 1.0f; //Normale der Normalmap anhand der Farbwerte bestimmen Normal = normalize( mul( MatTex, Normal ) ); //Normale wird mit Matrix multipliziert //Berechnung des Farbwerts: Intensity = saturate( dot(Normal, -LightDir) ); Diffuse = Intensity * MtrlDiffColor * LightColor * tex2D(SamplerDiffuse, IN.TexCoord); Specular = pow( max(0,dot( HalfVec, Normal)), MtrlSpecPower ) * MtrlSpecColor * LightColor; return (Diffuse + Specular + LightAmbient); } Ein Farbwert muss zwischen 0 und 1 liegen. Die Werte Normalen der Normalmap müssen auf den Bereich zwischen -1 und 1 skaliert werden. Bsp: voller Rot-Anteil -> 1 -> Normale erhält Wert 1 in Richtung der Tangente Kein rot -> 0 -> Normale erhält Wert -1 in Richtung der Tangente

Die Dot3-Bumpmapping-Klasse class CBumpEffect { protected: ID3DXEffect*m_Effect; SBumpParameterm_Parameter; public: static BOOL SetupMesh( ID3DXMesh** mesh, LPDIRECT3DDEVICE9 device ); BOOLCreate( LPDIRECT3DDEVICE9 Device ); voidDestroy(); voidSetup( SBumpParameter& Para ); DWORD Begin( LPDIRECT3DDEVICE9 Device ); voidBeginPass(DWORD pass); voidEndPass(); voidEnd(); };

SBumpParameter -Struktur struct SBumpParameter { //Welche Werte wurden geändert? DWORD Changed; //Licht D3DXVECTOR4LightColor; D3DXVECTOR4LightAmbient; D3DXVECTOR3 LightDir; //Material D3DXVECTOR4MtrlDiffColor; D3DXVECTOR4MtrlSpecColor; FLOATMtrlSpecPower; LPDIRECT3DTEXTURE9TexDiffuse; LPDIRECT3DTEXTURE9TexNormal; }; Alle Parameter, die wir an den Effekt übergeben wollen in einer Struktur festgehalten. Changed signalisiert welche Werte geändert wurden, damit nur diese Werte neu übergeben werden müssen.

Vertexdeklaration Dient, genau wie das Flexible Vertex-Format (FVF), zur Beschreibung der Vertices Array der Struktur D3DVERTEXELEMENT9 Jeder Array-Eintrag beschreibt ein Attribut des Vertex (z.B. Position, Normale, Tangente…) D3DVERTEXELEMENT9 -Struktur: Typedef struct _D3DVERTEXELEMENT9 { WORD Stream; WORD Offset; BYTE Type; BYTE Method; BYTE Usage;//semantische Bedeutung des Eintrags (z.B. Tangente) BYTE UsageIndex; }

Die Funktion SetupMesh BOOL CBumpEffect::SetupMesh( ID3DXMesh** mesh, LPDIRECT3DDEVICE9 device ) { D3DVERTEXELEMENT9decl[MAX_FVF_DECL_SIZE]; //Vertexdeklaration D3DVERTEXELEMENT9endDecl = D3DDECL_END(); //setzt Endeintrag im Array DWORDFVF= (*mesh)->GetFVF(); ID3DXMesh*clone= NULL; BumpVertex*vertex= NULL; DWORDnumVertices = (*mesh)->GetNumVertices(); if( FVF!=(D3DFVF_TEX1|D3DFVF_NORMAL|D3DFVF_XYZ|D3DFVF_TEXCOORDSIZE2(1)) ) return false; /*Prüfen, ob der Mesh die Position des V., die Normale des V. und ein Texturkoordinatenpaar gespeichert hat. Diese Werte brauchen wir zur Berechnung des Tangentenraums*/ (*mesh)->GetDeclaration( decl );//Aktuelle //Vertexdeklaration wird übergeben decl[3].Stream = 0; decl[3].Offset = 32; decl[3].Type = D3DDECLTYPE_FLOAT3; decl[3].Method = D3DDECLMETHOD_DEFAULT; decl[3].Usage = D3DDECLUSAGE_TANGENT; decl[3].UsageIndex = 0; Pro Vertex sind schon 3 Einträge im Array gespeichert: Eintrag 0: Position Eintrag 1: Normale Eintrag 2: Texturkoordinaten-Paar Hier wird die Tangente hinzugefügt (Eintrag 3)

decl[4].Stream = 0; decl[4].Offset = 44; decl[4].Type = D3DDECLTYPE_FLOAT3; decl[4].Method = D3DDECLMETHOD_DEFAULT; decl[4].Usage = D3DDECLUSAGE_BINORMAL; decl[4].UsageIndex = 0; decl[5] = endDecl; //Endeintrag der Vertexdeklaration (Eintrag 5) (*mesh)->CloneMesh((*mesh)->GetOptions(), decl, device, &clone )) //Mesh wird geklont und enthält nun die neuen Deklarationen SAFE_RELEASE( (*mesh) ); //alten Mesh löschen *mesh = clone; //Klon einsetzten D3DXComputeTangent( clone, 0, 0, 0, false, NULL)) //Berechnet Tangentenraum return true; } Binormale wird hinzugefügt (Eintrag 4)

Weitere Funktionen… Create: BOOL CBumpEffect::Create( LPDIRECT3DDEVICE9 Device ) { ID3DXBuffer* ErrorBuffer; if( FAILED( D3DXCreateEffectFromFile( Device, "Effects/BumpMapping_FXComposer.fx", NULL, NULL, 0/*D3DXSHADER_DEBUG|D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT|D3DXSHADER_F ORCE_VS_SOFTWARE_NOOPT*/, NULL, &m_Effect, &ErrorBuffer ) ) ) { char *Errors = (char*) ErrorBuffer->GetBufferPointer(); fprintf( stderr, "%s", Errors ); return false; } return true; }

Destroy: void CBumpEffect::Destroy() { SAFE_RELEASE( m_Effect ); } Setup: void CBumpEffect::Setup( SBumpParameter& Para ) { if( Para.Changed & LIGHTCOLOR ) m_Parameter.LightColor = Para.LightColor; if( Para.Changed & LIGHTAMBIENT ) m_Parameter.LightAmbient = Para.LightAmbient; if( Para.Changed & LIGHTDIR ) m_Parameter.LightDir = Para.LightDir; if( Para.Changed & MTRLDIFFCOLOR ) m_Parameter.MtrlDiffColor = Para.MtrlDiffColor; if( Para.Changed & MTRLSPECCOLOR ) m_Parameter.MtrlSpecColor = Para.MtrlSpecColor; if( Para.Changed & MTRLSPECPOWER ) m_Parameter.MtrlSpecPower = Para.MtrlSpecPower; if( Para.Changed & TEXDIFFUSE ) m_Parameter.TexDiffuse = Para.TexDiffuse; if( Para.Changed & TEXNORMAL ) m_Parameter.TexNormal = Para.TexNormal; m_Parameter.Changed |= Para.Changed; }

Begin: DWORD CBumpEffect::Begin( LPDIRECT3DDEVICE9 Device ) { UINT passes = 0; // Matrizen setzen D3DXMATRIX MatWorld, MatView, MatProj; D3DXMATRIX MatWVP, MatViewInv, MatWorldInv; Device->GetTransform( D3DTS_WORLD, &MatWorld ); Device->GetTransform( D3DTS_VIEW, &MatView ); Device->GetTransform( D3DTS_PROJECTION, &MatProj ); m_Effect->SetMatrix( "MatWorld", &MatWorld ); MatWVP= (MatWorld*MatView)*MatProj; m_Effect->SetMatrix( "MatWVP", &MatWVP ); D3DXMatrixInverse( &MatViewInv, NULL, &MatView ); m_Effect->SetMatrix( "MatViewInv", &MatViewInv ); m_Effect->SetTechnique( "BumpMapping" ); m_Effect->Begin( &passes, 0 ); return passes; }

BeginPass: void CBumpEffect::BeginPass(DWORD pass) { // Parameter setzen if( m_Parameter.Changed & LIGHTCOLOR ) m_Effect->SetValue( "LightColor", m_Parameter.LightColor, sizeof( D3DXVECTOR4 ) ) ; if( m_Parameter.Changed & LIGHTAMBIENT ) m_Effect->SetValue( "LightAmbient", m_Parameter.LightAmbient, sizeof( D3DXVECTOR4 ) ); if( m_Parameter.Changed & LIGHTDIR ) m_Effect->SetValue( "LightDir", m_Parameter.LightDir, sizeof( D3DXVECTOR3 ) ); if( m_Parameter.Changed & MTRLDIFFCOLOR ) m_Effect->SetValue( "MtrlDiffColor", m_Parameter.MtrlDiffColor, sizeof( D3DXVECTOR4 ) ); if( m_Parameter.Changed & MTRLSPECCOLOR ) m_Effect->SetValue( "MtrlSpecColor", m_Parameter.MtrlSpecColor, sizeof( D3DXVECTOR4 ) ); if( m_Parameter.Changed & MTRLSPECPOWER ) m_Effect->SetFloat( "MtrlSpecPower", m_Parameter.MtrlSpecPower ); if( m_Parameter.Changed & TEXDIFFUSE ) m_Effect->SetTexture( "TexDiffuse", m_Parameter.TexDiffuse ); if( m_Parameter.Changed & TEXNORMAL ) m_Effect->SetTexture( "TexNormal", m_Parameter.TexNormal ); m_Effect->BeginPass( pass ); }

EndPass: void CBumpEffect::EndPass() { m_Effect->EndPass(); m_Parameter.Changed = 0; } End: void CBumpEffect::End() { m_Effect->End(); }