Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Kapitel 9.4 Blooming (Postprocess-Effekt). Postprocess-Effekte 2D-Effekte Werden auf das gerenderte Bild im Framebuffer angewendet Beispiele: Bewegungsunschärfe.

Ähnliche Präsentationen


Präsentation zum Thema: "Kapitel 9.4 Blooming (Postprocess-Effekt). Postprocess-Effekte 2D-Effekte Werden auf das gerenderte Bild im Framebuffer angewendet Beispiele: Bewegungsunschärfe."—  Präsentation transkript:

1 Kapitel 9.4 Blooming (Postprocess-Effekt)

2 Postprocess-Effekte 2D-Effekte Werden auf das gerenderte Bild im Framebuffer angewendet Beispiele: Bewegungsunschärfe Unterwassersicht Farbkorrektur/-bearbeitung/-invertierung Kantenhervorhebung Schimmer-/Schleierbildung Blooming

3 Blooming Effekt zur Schleierbildung Helle Pixel sollen benachbarte Pixel überstrahlen bzw. scharfe Konturen sollen ausfransen Schritte: Gerendertes Eingangsbild in Textur kopieren Diese Textur weichzeichnen neue Textur Farbwerte der beiden Texturen addieren

4 Weichzeichnen Das Weichzeichnen erfolgt durch folgenden Algorithmus: F arbwert Punkt = (Farbwert Punkt x Gewichtung Punkt ) + (Farbwerte benachbartePunkte x Gewichtung benachbartePunkte ) Bsp: w 0 = 0,4; w 1 = 0,2 PixelgewichtungEingangsbildAusgangsbild 0,80,60,2 0,60,40 0,200 110 100 000 0w1w1 0 w1w1 w0w0 w1w1 0w1w1 0

5 Eine Gewichtung, die für gute Ergebnisse sorgt, ist die Gewichtung nach der Gauß-Glocke mit folgender Verteilung: Damit wir überhaupt Koordinaten für die jeweiligen Pixel haben kopieren wir das gerenderte Bild vor dem Weichzeichnen in eine Textur, und ziehen diese auf eine Fläche, die den Ausmaßen des Bildschirms entspicht. UV(0,0) linke, obere Ecke UV(1,1) rechte, untere Ecke

6 Die Effektdatei Bevor das Bild weichgezeichnet wird, verkleinern wir es, um Rechenaufwand zu sparen Wir gehen also nach folgendem Schema vor: Jeder Schritt stellt einen Pass in der Effektdatei dar: pass Downsize pass Bloom pass AddTextures Schritt 1 Eingangstextur verkleinern Schritt 2 Verkleinerte Textur weichzeichnen Schritt 3 Eingangstextur Mit weichge- zeichneter Textur addieren Eingangstextur

7 technique Blooming { pass Downsize { VertexShader= compile vs_2_0 VS_Passthru(); PixelShader= compile ps_2_0 PS_Textured(); } pass Bloom { VertexShader= compile vs_2_0 VS_Passthru(); PixelShader= compile ps_2_0 PS_Bloom(); } pass AddTextures { VertexShader= compile vs_2_0 VS_Passthru(); PixelShader= compile ps_2_0 PS_Add(); } void VS_Passthru( float4 Pos : POSITION, float2 tex : TEXCOORD0, out float4 oPos : POSITION, out float2 texcoord : TEXCOORD0 ) { oPos= Pos; texcoord= tex; } Der Vertexshader leitet die Vertices einfach weiter:

8 Der Pixelshader PS_Textured //Texturvariable definieren TextureTexInput0; //Textursampler sampler Sampler0 = sampler_state { texture = ; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; //Pixelshader void PS_Textured( float2 texcoord : TEXCOORD0, out float4 Color : COLOR ) { Color = tex2D( Sampler0, texcoord ); } Der Pixelshader selbst sorgt nicht dafür, dass die Textur verkleinert wird. Dazu müssen wir in der C++-Klasse ein verkleinertes surface als Rendertarget für diesen Pass verwenden.

9 Vorbereitungen für den Pixelshader PS_Bloom float2 HorizontalPixel[13] = { { -6, 0 }, { -5, 0 }, { -4, 0 }, { -3, 0 }, { -2, 0 }, { -1, 0 }, { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, { 6, 0 }, }; float2 VerticalPixel[13] = { { 0, -6 }, { 0, -5 }, { 0, -4 }, { 0, -3 }, { 0, -2 }, { 0, -1 }, { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, }; Zunächst müssen wir 2 Arrays anlegen, damit wir jeweils 12 benachbarte Pixel in der horizontalen und vertikalen Ebene verrechnen können:

10 Zusätzlich müssen wir die Gewichtungen für die benachbarten Pixel in einem Array festhalten: static const float BlurWeights[13] = { 0.002216, 0.008764, 0.026995, 0.064759, 0.120985, 0.176033, 0.199471, 0.176033, 0.120985, 0.064759, 0.026995, 0.008764, 0.002216, }; Da unsere verkleinerte Textur 256 x 256 Pixel groß sein soll, müssen wir noch folgendes definieren: #define REDUCED_WIDTH 256 #define REDUCED_HEIGHT 256

11 Der Pixelshader PS_Bloom void PS_Bloom( float2 texcoord : TEXCOORD0, out float4 Color : COLOR ) { float2 uvoffset; Color = float4( 0.0f, 0.0f, 0.0f, 1.0f ); for( int i=0; i < 13; i++ ) { uvoffset = VerticalPixel[i].xy/float2( 1.0f, REDUCED_HEIGHT ) //Bestimmen des offsets (Abstands)zum Nachbarpixel Color+= tex2D( Sampler0, texcoord + uvoffset ) * BlurWeights[i]; //Gewichtung eines Nachbarpixels mit diesem multiplizieren und //zu Color addieren uvoffset = HorizontalPixel[i].xy/float2( REDUCED_WIDTH, 1.0f); Color+= tex2D( Sampler0, texcoord + uvoffset ) * BlurWeights[i]; //die beiden Schritte für die horizontale Ebene wiederholen } Color=Color*BloomFactor; //neuen Farbwert mit konstantem Faktor addieren } Parameter wird vorher definiert: float BloomFactor = 1.2f;

12 Der Pixelshader PS_Add //Texturvariable definieren TextureTexInput1; //Textursampler sampler Sampler1 = sampler_state { texture = ; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; //Pixelshader void PS_Add( float2 texcoord : TEXCOORD0, out float4 Color : COLOR ) { Color = tex2D( Sampler0, texcoord ) + tex2D( sampler1, texcoord ); }

13 Die Blooming-Klasse class CBloomEffect { protected: ID3DXEffect* m_Effect;//Effektinstanz LPDIRECT3DTEXTURE9 m_texCopyOrgRT;//Kopie des aktuellen Rendetargets // Originalbild LPDIRECT3DTEXTURE9 m_texReduced;//verkleinerte Textur LPDIRECT3DTEXTURE9 m_texBloomed;//verkl. Textur nach Weichzeichnen LPDIRECT3DVERTEXBUFFER9 m_VB;//Vertexbuffer urspr. Rendertarget // für die Fläche die den Bildschirm einnehmen soll LPDIRECT3DVERTEXBUFFER9 m_VBreduced;//Vertexbuffer verkl. Rendertarget // Fläche für verringerte Eingangstexturen public: CBloomEffect(); BOOL Create( LPDIRECT3DDEVICE9 Device ); void PostProcess( LPDIRECT3DDEVICE9 Device ); void SetBloomFactor( float factor ); void Destroy(); };

14 Die Create -Funktion BOOL CBloomEffect::Create( LPDIRECT3DDEVICE9 Device ) { ID3DXBuffer*ErrorBuffer = NULL; LPDIRECT3DSURFACE9BackBuffer = NULL; D3DSURFACE_DESCBackBufferDesc; void*VertexData; //Erzeugen der Effektinstanz aus der FX-Datei if( FAILED( D3DXCreateEffectFromFile( Device, "Effects/bloom.fx", NULL, NULL, 0, NULL, &m_Effect, &ErrorBuffer ) ) ) { char *Errors = (char*) ErrorBuffer->GetBufferPointer(); fprintf( stderr, "%s", Errors ); return false; } //Wir holen uns Informationen über das aktuelle Rendertarget über den surface-Descriptor Device->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &BackBuffer ); BackBuffer->GetDesc( &BackBufferDesc );//Surface-Descriptor enthält Info über Auflösung etc. SAFE_RELEASE(BackBuffer); //Textur erzeugen mit Hilfe der Auflösung und des Formats des Backbuffers if( FAILED( Device->CreateTexture(BackBufferDesc.Width, //Breite BackBufferDesc.Height,//Höhe 1, //MipmapsD3DUSAGE_RENDERTARGET, //UsageBackBufferDesc.Format,//Format D3DPOOL_DEFAULT, //Pool&m_texCopyOrgRT, //ZielNULL ) ) )//Reserv. return false;

15 //Erzeugen der verkleinerten Texturen if( FAILED( Device->CreateTexture(REDUCED_WIDTH, REDUCED_HEIGHT, 1, D3DUSAGE_RENDERTARGET, BackBufferDesc.Format, D3DPOOL_DEFAULT, &m_texReduced, NULL ) ) ) return false; if( FAILED( Device->CreateTexture(REDUCED_WIDTH, REDUCED_HEIGHT, 1, D3DUSAGE_RENDERTARGET, BackBufferDesc.Format, D3DPOOL_DEFAULT, &m_texBloomed, NULL ) ) ) return false; Breite und Höhe der verkleinerten Texturen müssen wir vorher definieren: #define REDUCED_WIDTH 256 #define REDUCED_HEIGHT 256

16 Um die Vertexbuffer zu erstellen wird zunächst in der Header-Datei folgende Struktur beschrieben: struct SBloomVertex { D3DXVECTOR4 pos; FLOATu; FLOATv; }; Wir werden pro Vertexbuffer 6 Vertices definieren: Vertices[0]Vertices[1] Vertices[4] Vertices[2] Vertices[3]Vertices[5]

17 { //Vertices in Struktur anlegen SBloomVertex Vertices[6] = { { D3DXVECTOR4( -0.5f, -0.5f, 0.0f, 1.0f), 0.0f, 0.0f }, { D3DXVECTOR4( BackBufferDesc.Width-0.5f, -0.5f, 0.0f, 1.0f), 1.0f, 0.0f }, { D3DXVECTOR4( -0.5f, BackBufferDesc.Height-0.5f, 0.0f, 1.0f), 0.0f, 1.0f }, { D3DXVECTOR4( BackBufferDesc.Width-0.5f, -0.5f, 0.0f, 1.0f), 1.0f, 0.0f }, { D3DXVECTOR4( BackBufferDesc.Width-0.5f, BackBufferDesc.Height- 0.5f, 0.0f, 1.0f), 1.0f, 1.0f }, }; //mit Hilfe der Struktur Vertexbuffer m_VB erstellen if( FAILED( Device->CreateVertexBuffer( sizeof(SBloomVertex)*6, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,D3DPOOL_DEFAULT, &m_VB, NULL ) ) ) return false; if( FAILED( m_VB->Lock( 0, 0, &VertexData, D3DLOCK_DISCARD ) ) ) return false; memcpy( VertexData, Vertices, sizeof(SBloomVertex)*6 ); m_VB->Unlock(); }

18 { //zweiten Vertexbuffer anlegen SBloomVertex Vertices[6] = { { D3DXVECTOR4( -0.5f, -0.5f, 0.0f, 1.0f), 0.0f, 0.0f }, { D3DXVECTOR4( REDUCED_WIDTH-0.5f, -0.5f, 0.0f, 1.0f), 1.0f, 0.0f }, { D3DXVECTOR4( -0.5f, REDUCED_HEIGHT-0.5f, 0.0f, 1.0f), 0.0f, 1.0f }, { D3DXVECTOR4( REDUCED_WIDTH-0.5f, -0.5f, 0.0f, 1.0f), 1.0f, 0.0f }, { D3DXVECTOR4( REDUCED_WIDTH-0.5f, REDUCED_HEIGHT-0.5f, 0.0f, 1.0f), 1.0f, 1.0f }, }; if( FAILED( Device->CreateVertexBuffer( sizeof(SBloomVertex)*6, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_VBreduced, NULL ) ) ) return false; if( FAILED( m_VBreduced->Lock( 0, 0, &VertexData, D3DLOCK_DISCARD ) ) ) return false; memcpy( VertexData, Vertices, sizeof(SBloomVertex)*6 ); m_VBreduced->Unlock(); } return true; }

19 Die PostProcess -Funktion void CBloomEffect::PostProcess( LPDIRECT3DDEVICE9 Device ) { UINTpasses= 0; LPDIRECT3DSURFACE9OrgRenderTarget= NULL; LPDIRECT3DSURFACE9Surface= NULL; // Backup des originalen Rendertargets Device->GetRenderTarget( 0, &OrgRenderTarget ); // Wir kopieren das Target in eine Textur, damit wir es als // Eingang für einen Shader verwenden können m_texCopyOrgRT->GetSurfaceLevel( 0, &Surface ); Device->StretchRect( OrgRenderTarget, NULL, Surface, NULL, D3DTEXF_NONE ); Surface->Release(); //Wir deaktivieren das Schreiben und Lesen des Z-Buffers Device->SetRenderState( D3DRS_ZENABLE, false ); Device->SetRenderState( D3DRS_ZWRITEENABLE, false ); Device->SetFVF( SBLOOMVERTEX_FVF );

20

21

22

23 Weitere Funktionen...


Herunterladen ppt "Kapitel 9.4 Blooming (Postprocess-Effekt). Postprocess-Effekte 2D-Effekte Werden auf das gerenderte Bild im Framebuffer angewendet Beispiele: Bewegungsunschärfe."

Ähnliche Präsentationen


Google-Anzeigen