Saturday, December 12, 2009

gpu post-processing

I wanted to explain an overview of the post-processing effects using GPU shader programs since I've been working on this for awhile now. Basically, the rendering for post processing is broken into two steps

- we render-to-texture using normal rendering routines
- then use a pixel shader to texture a square with the render-target texture

The code I used the DirectX SDK sample ($SDK\Samples\C++\Direct3D\PostProcess)
Here is a simple model of the rendering

// render-to-texture
graphics->SetRenderTarget( offscreenTexture );
graphics->RenderScene( );

// square is the size of the screen, from back buffer description
VERTEX quad [4] = /* use the BackBufferDescription( ); */

// set shader parameters
shader->SetTechnique( "RenderPostProcess" );
shader->SetTexture( “offscreen_texture", offscreenTexture );

// square is textured by the pixel shader effect
graphics->SetRenderTarget( screen );
graphics->DrawPrimitive( quad );


I based this code off of the DirectX SDK sample ($SDK\Samples\C++\Direct3D\PostProcess, definitely look at that this if you are trying this). The square is calculated to fit the screen (using DXUTGetD3D9BackBufferSurfaceDesc). Then we texture the "fullscreen square" using our RTT texture, and we can use pixel shader effects during this rendering.

Here, the simplest "toon shader" ever

// render target from effect->settexture
texture offscreen_texture;
sampler2D s = sampler_state {
Texture = <>;
};

// "toon shader"
float4 PostProcessPixel(float2 uv : TEXCOORD0) : COLOR
{
float4 c = tex2D(s, uv_coord);
c.rgba -= (Color.rgba % 0.3f );
return c;
}

technique RenderPostProcess {
pass p0 {
VertexShader = null;
PixelShader = compile ps_2_0 PostProcessPixel ();
ZEnable = false;
}
}


Thanks to gamedev for helping me with this miracle



Updated:

Source code - http://zxcvbn.googlecode.com/svn/trunk/skelly/
Wiki page - http://code.google.com/p/zxcvbn/wiki/skelly
Demo - http://zxcvbn.googlecode.com/files/Skelly.exe

No comments:

Post a Comment