The effect file code with the shaders in them.
Code:
//Glare vertex shader
float4x4 matWorldViewProj;
float fBlendFactor;
sampler SourceTex1;
sampler SourceTex2;
sampler SourceTex3;
sampler SourceTex4;
struct VS_OUTPUT
{
float4 Pos : POSITION;
float2 UV0 : TEXCOORD0;
float2 UV1 : TEXCOORD1;
float2 UV2 : TEXCOORD2;
float2 UV3 : TEXCOORD3;
};
VS_OUTPUT VSBlurMain(float4 Pos : POSITION,float2 Tex : TEXCOORD0)
{
VS_OUTPUT Out=(VS_OUTPUT)0;
float2 vecUp=(-0.04,0.00);
float2 vecDn=(0.04,0.00);
float2 vecLt=(-0.02,0.0);
float2 vecRt=(0.02,0.0);
Out.Pos=mul(matWorldViewProj,Pos);
Out.UV0=Tex.xy+vecUp;
Out.UV1=Tex.xy+vecDn;
Out.UV2=Tex.xy+vecLt;
Out.UV3=Tex.xy+vecRt;
return Out;
}
float4 PSBlurMain(VS_OUTPUT In) : COLOR
{
float4 Color0=tex2D(SourceTex1,In.UV0);
float4 Color1=tex2D(SourceTex1,In.UV1);
float4 Color2=tex2D(SourceTex1,In.UV2);
float4 Color3=tex2D(SourceTex1,In.UV3);
float4 vCol1=lerp(Color0,Color3,.50);
float4 vCol2=lerp(Color1,Color2,.50);
return saturate(lerp(vCol1,vCol2,.50));
}
VS_OUTPUT VSABMain(float4 Pos : POSITION,float2 Tex : TEXCOORD0,
float2 Tex2 : TEXCOORD1)
{
VS_OUTPUT Out=(VS_OUTPUT)0;
Out.Pos=mul(matWorldViewProj,Pos);
Out.UV0=Tex;
Out.UV1=Tex;
return Out;
}
float4 PSABMain(VS_OUTPUT In) : COLOR
{
float4 Color0=tex2D(SourceTex1,In.UV0);
float4 Color1=tex2D(SourceTex2,In.UV1);
return ((Color1*0.40f)+Color0)*1.55f;
}
technique Blur
{
pass P0
{
Lighting=false;
VertexShader=compile vs_3_0 VSBlurMain();
PixelShader=compile ps_3_0 PSBlurMain();
}
}
technique AddBlend
{
pass P0
{
Lighting=false;
VertexShader=compile vs_3_0 VSABMain();
PixelShader=compile ps_3_0 PSABMain();
}
}
The source code that utilizes this effect file:
Code:
...
HRESULT hr=0;
//Get primary back buffer surface
IDirect3DSurface9 *pSourceSurf=NULL;
hr=m_pDevice->GetRenderTarget(0,&pSourceSurf);
if (FAILED(hr))
{
::MessageBox(0,"Cannot get render surface","Cannot get render surface",0);
}
//Get surface of down sample texture (currently blank)
IDirect3DSurface9 *pTargSurf=NULL;
hr=m_pScene->GetSurfaceLevel(0,&pTargSurf);
//Copy texture from original scene render to 1/64 down sample texture
m_pDevice->EndScene();
//Copy rendered scene into m_pScene
hr=m_pDevice->StretchRect(pSourceSurf,NULL,
pTargSurf,NULL,D3DTEXF_LINEAR);
hr=m_pDownSample164->GetSurfaceLevel(0,&pTargSurf);
//Downsample rendered scene into m_pDownSample164
hr=m_pDevice->StretchRect(pSourceSurf,NULL,
pTargSurf,NULL,D3DTEXF_NONE);
if (FAILED(hr)) ::MessageBox(0,"","Stretch rect failed",0);
m_pDevice->BeginScene();
//Blur the texture by drawing a quad on Blur164 using the
//downsample164 texture
UINT iPass=0,cPasses=0;
//Set render target to down sample render target
IDirect3DSurface9 *pBlur164Surf=NULL;
m_pBlur164->GetSurfaceLevel(0,&pBlur164Surf);
//Set render target to blur surface
m_pDevice->SetRenderTarget(0,pBlur164Surf);
//Our down sampled texture to blur
m_pDevice->SetTexture(0,m_pDownSample164);
m_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(1,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(1,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(2,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(2,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(3,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
m_pDevice->SetSamplerState(3,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
//Blur it by drawing a quad on blur surface
//Use blur technique from effect file
m_pDevice->SetVertexDeclaration(VertexTLT1::pDecl);
m_pGlareEffect->SetTechnique("Blur");
m_pGlareEffect->Begin(&cPasses, 0);
for(iPass = 0; iPass < cPasses; iPass++)
{
m_pGlareEffect->BeginPass(iPass);
RenderScreenAlignedQuad(0,0,m_pGlareEffect);
m_pGlareEffect->EndPass();
}
m_pGlareEffect->End();
//Set back to primary buffer
m_pDevice->SetRenderTarget(0,pSourceSurf);
m_pDevice->SetVertexDeclaration(VertexTLT1::pDecl);
m_pGlareEffect->SetTechnique("AddBlend");
m_pGlareEffect->SetFloat("fBlendFactor",0.05f);
m_pDevice->SetTexture(0,m_pBlur164);
m_pDevice->SetTexture(1,m_pScene);
m_pGlareEffect->Begin(&cPasses, 0);
for(iPass = 0; iPass < cPasses; iPass++)
{
m_pGlareEffect->BeginPass(iPass);
RenderScreenAlignedQuad(0,0,m_pGlareEffect);
m_pGlareEffect->EndPass();
}
m_pGlareEffect->End();
m_pDevice->EndScene();
}
All surfaces are members of the application class and can be used for any shader effects. I couldn't find a better way to do it.