21
Kapitel 9.3 Dot3-Bumpmapping (Normalmapping)

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

Embed Size (px)

Citation preview

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

Kapitel 9.3

Dot3-Bumpmapping (Normalmapping)

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

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

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

Heightmaps Graustufen-Texturen, in denen

Tiefenwerte codiert sind, welche dann zur Berechnung der Schattierung herangezogen werden

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

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

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

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

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

Die EffektdateiBenö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

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

Textursampler

sampler SamplerDiffuse = sampler_state { texture = <TexDiffuse>; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR;};

sampler SamplerNormal = sampler_state { texture = <TexNormal>; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR;};

Sampler für die Diffusemap

Sampler für die Normalmap

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

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

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

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)

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

Pixelshaderfloat4 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

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

Die Dot3-Bumpmapping-Klasseclass CBumpEffect{protected:

ID3DXEffect* m_Effect;SBumpParameter m_Parameter;

public:static BOOL SetupMesh( ID3DXMesh** mesh, LPDIRECT3DDEVICE9 device );BOOL Create( LPDIRECT3DDEVICE9 Device );void Destroy();void Setup( SBumpParameter& Para );DWORD Begin( LPDIRECT3DDEVICE9 Device );void BeginPass(DWORD pass);void EndPass();void End();

};

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

SBumpParameter-Struktur

struct SBumpParameter{

//Welche Werte wurden geändert?DWORD Changed;

//LichtD3DXVECTOR4 LightColor;D3DXVECTOR4 LightAmbient;D3DXVECTOR3 LightDir;

//MaterialD3DXVECTOR4MtrlDiffColor;D3DXVECTOR4MtrlSpecColor;FLOAT MtrlSpecPower;LPDIRECT3DTEXTURE9 TexDiffuse;LPDIRECT3DTEXTURE9 TexNormal;

};

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.

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

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;

}

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

Die Funktion SetupMesh

BOOL CBumpEffect::SetupMesh( ID3DXMesh** mesh, LPDIRECT3DDEVICE9 device ){

D3DVERTEXELEMENT9decl[MAX_FVF_DECL_SIZE]; //VertexdeklarationD3DVERTEXELEMENT9endDecl = D3DDECL_END(); //setzt „Endeintrag“ im ArrayDWORD FVF = (*mesh)->GetFVF();ID3DXMesh* clone = NULL;BumpVertex* vertex = NULL;DWORD numVertices = (*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)

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

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)

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

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_FORCE_VS_SOFTWARE_NOOPT*/,

NULL, &m_Effect, &ErrorBuffer ) ) ){

char *Errors = (char*) ErrorBuffer->GetBufferPointer();fprintf( stderr, "%s", Errors );return false;

}

return true;}

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

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;}

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

Begin:

DWORD CBumpEffect::Begin( LPDIRECT3DDEVICE9 Device ){

UINT passes = 0;

// Matrizen setzenD3DXMATRIX 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;}

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

BeginPass:

void CBumpEffect::BeginPass(DWORD pass){

// Parameter setzenif( 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 );}

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

EndPass:void CBumpEffect::EndPass(){

m_Effect->EndPass();m_Parameter.Changed = 0;

}

End:void CBumpEffect::End(){

m_Effect->End();}

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