Screenshots of bug:
http://dl.dropbox.com/u/2637453/bloom/topview.jpg
http://dl.dropbox.com/u/2637453/bloom/rotated.jpg
My shader code:
float2 PixelCoordsDownFilter[16] ={ { 1.5, -1.5 }, { 1.5, -0.5 }, { 1.5, 0.5 }, { 1.5, 1.5 }, { 0.5, -1.5 }, { 0.5, -0.5 }, { 0.5, 0.5 }, { 0.5, 1.5 }, {-0.5, -1.5 }, {-0.5, -0.5 }, {-0.5, 0.5 }, {-0.5, 1.5 }, {-1.5, -1.5 }, {-1.5, -0.5 }, {-1.5, 0.5 }, {-1.5, 1.5 },};float2 TexelCoordsDownFilter[16]<string ConvertPixelsToTexels = "PixelCoordsDownFilter";>;texture textureBloom;sampler2D textureBloomSampler = sampler_state{ Texture = <textureBloom>; AddressU = Clamp; AddressV = Clamp; MINFILTER = Point; MIPFILTER = Linear; MAGFILTER = Linear;};texture textureScene;sampler2D textureSceneSampler = sampler_state{ Texture = <textureScene>; AddressU = Clamp; AddressV = Clamp; MINFILTER = Point; MIPFILTER = Linear; MAGFILTER = Linear;};float4 DownFilter(in float2 Tex : TEXCOORD0) : COLOR0{ float4 Color = 0; for (int i = 0; i < 16; i++){ Color += tex2D(textureBloomSampler, Tex + TexelCoordsDownFilter.xy); } return Color / 16;}float Luminance = 0.08f;static const float fMiddleGray = 0.18f;static const float fWhiteCutoff = 0.8f;float4 BrightPassFilter(in float2 Tex : TEXCOORD0) : COLOR0{ float3 ColorOut = tex2D(textureBloomSampler, Tex);; ColorOut *= fMiddleGray / (Luminance + 0.001f); ColorOut *= ( 1.0f + (ColorOut / (fWhiteCutoff * fWhiteCutoff))); ColorOut -= 5.0f; ColorOut = max(ColorOut, 0.0f); ColorOut /= (10.0f + ColorOut); return float4(ColorOut, 1.0f);}static const int g_cKernelSize = 13;float2 PixelKernel[g_cKernelSize] ={ { -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 TexelKernel[g_cKernelSize]<string ConvertPixelsToTexels = "PixelKernel";>;static const float BlurWeights[g_cKernelSize] = { 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,};float BloomScale = 1.5f;float4 BlurHFilter(float2 Tex : TEXCOORD0) : COLOR0{ float4 Color = 0; for (int i = 0; i < g_cKernelSize; i++){ Color += tex2D(textureBloomSampler, Tex + TexelKernel.xy) * BlurWeights; } return Color * BloomScale;}float4 BlurVFilter(float2 Tex : TEXCOORD0) : COLOR0{ float4 Color = 0; for (int i = 0; i < g_cKernelSize; i++){ Color += tex2D(textureBloomSampler, Tex + TexelKernel.yx) * BlurWeights; } return Color * BloomScale;}float4 UpFilter(float2 Tex : TEXCOORD0) : COLOR0{ return tex2D(textureBloomSampler, Tex);}float4 CombineFilter(float2 Tex : TEXCOORD0) : COLOR0{ float3 ColorOrig = tex2D(textureSceneSampler, Tex); ColorOrig += tex2D(textureBloomSampler, Tex); return float4(ColorOrig, 1.0f);}technique Bloom{ pass p0{ VertexShader = null; ZEnable = false; PixelShader = compile ps_2_0 DownFilter(); } pass p1{ VertexShader = null; ZEnable = false; PixelShader = compile ps_2_0 BrightPassFilter(); } pass p2{ VertexShader = null; ZEnable = false; PixelShader = compile ps_2_0 BlurHFilter(); } pass p3{ VertexShader = null; ZEnable = false; PixelShader = compile ps_2_0 BlurVFilter(); } pass p4{ VertexShader = null; ZEnable = false; PixelShader = compile ps_2_0 UpFilter(); } pass p5{ VertexShader = null; ZEnable = false; PixelShader = compile ps_2_0 CombineFilter(); }}
Code to use the shader:
void RenderBloom(){ shader->SetTechnique("Bloom"); const D3DSURFACE_DESC* desc = DXUTGetD3D9BackBufferSurfaceDesc(); float Height = (float)desc->Height; float Width = (float)desc->Width; float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width - 0.5f, -0.5f, 0, 0, 1, 0, -0.5f, Height - 0.5f, 0, 0, 0, 1, Width - 0.5f, Height - 0.5f, 0, 0, 1, 1, }; uint passes; device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); { // down filter 4x device->SetRenderTarget(0, surfacePass2); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, textureScene); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 0.25f - 0.5f, -0.5f, 0, 0, 1, 0, -0.5f, Height * 0.25f - 0.5f, 0, 0, 0, 1, Width * 0.25f - 0.5f, Height * 0.25f - 0.5f, 0, 0, 1, 1, }; shader->Begin(&passes, 0); shader->BeginPass(0); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // down filter 4x device->SetRenderTarget(0, surfacePass1); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass2); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 0.25f - 0.5f, -0.5f, 0, 0, 1, 0, -0.5f, Height * 0.25f - 0.5f, 0, 0, 0, 1, Width * 0.25f - 0.5f, Height * 0.25f - 0.5f, 0, 0, 1, 1, }; shader->Begin(&passes, 0); shader->BeginPass(0); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // brightpass device->SetRenderTarget(0, surfacePass2); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass1); shader->Begin(&passes, 0); shader->BeginPass(1); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // blur horizontal device->SetRenderTarget(0, surfacePass1); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass2); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 0.0625f - 0.5f, -0.5f, 0, 0, 0.0625f, 0, -0.5f, Height * 0.0625f - 0.5f, 0, 0, 0, 0.0625f, Width * 0.0625f - 0.5f, Height * 0.0625f - 0.5f, 0, 0, 0.0625f, 0.0625f, }; shader->Begin(&passes, 0); shader->BeginPass(2); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // blur vertical device->SetRenderTarget(0, surfacePass2); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass1); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 0.0625f - 0.5f, -0.5f, 0, 0, 0.0625f, 0, -0.5f, Height * 0.0625f - 0.5f, 0, 0, 0, 0.0625f, Width * 0.0625f - 0.5f, Height * 0.0625f - 0.5f, 0, 0, 0.0625f, 0.0625f, }; shader->Begin(&passes, 0); shader->BeginPass(3); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // blur horizontal device->SetRenderTarget(0, surfacePass1); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass2); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 0.0625f - 0.5f, -0.5f, 0, 0, 0.0625f, 0, -0.5f, Height * 0.0625f - 0.5f, 0, 0, 0, 0.0625f, Width * 0.0625f - 0.5f, Height * 0.0625f - 0.5f, 0, 0, 0.0625f, 0.0625f, }; shader->Begin(&passes, 0); shader->BeginPass(2); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // blur vertical device->SetRenderTarget(0, surfacePass2); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass1); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 0.0625f - 0.5f, -0.5f, 0, 0, 0.0625f, 0, -0.5f, Height * 0.0625f - 0.5f, 0, 0, 0, 0.0625f, Width * 0.0625f - 0.5f, Height * 0.0625f - 0.5f, 0, 0, 0.0625f, 0.0625f, }; shader->Begin(&passes, 0); shader->BeginPass(3); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // up filter 16x device->SetRenderTarget(0, surfacePass1); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass2); float verts[] = { -0.5f, -0.5f, 0, 0, 0, 0, Width * 16 - 0.5f, -0.5f, 0, 0, 1, 0, -0.5f, Height * 16 - 0.5f, 0, 0, 0, 1, Width * 16 - 0.5f, Height * 16 - 0.5f, 0, 0, 1, 1, }; shader->Begin(&passes, 0); shader->BeginPass(4); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); } { // combine device->SetRenderTarget(0, surfaceBackbuffer); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); shader->SetTexture(shaderTextureBloom, texturePass1); shader->SetTexture(shaderTextureScene, textureScene); shader->Begin(&passes, 0); shader->BeginPass(5); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(float) * 6); shader->EndPass(); shader->End(); }}
If anymore information needed - let me know.
Thank you in advance.