Sign in to follow this  

Please help me!

Recommended Posts

I have made my own bloom effect from scratch.

Start with making a draw surface packet like I made for Direct3D 11:

struct DrawSurfaceItem {
// Flags
bool IsScreen;

// Dimensions
int CurrentWidth;
int CurrentHeight;

// Color buffer
ID3D11RenderTargetView* ColorInput; // Input
ID3D11Texture2D* ColorBuffer; // Buffer
ID3D11ShaderResourceView* ColorOutput; // Output

// Depth buffer
ID3D11Texture2D* DepthBuffer; // Buffer
ID3D11DepthStencilView* DepthInputAndOutput; // Input and output

void SetSizeOfDrawSurface(DrawSurfaceItem* Surface, int NewWidth, int NewHeight) {
if (NewWidth < 1 || NewHeight < 1) {
MessageBox(NULL, L"DrawSurfaceItem::SetSizeOfDrawSurface was called with non positive dimensions. Width and height may not be less than 1.", L"Error!", NULL);
} else if (Surface->CurrentWidth != NewWidth || Surface->CurrentHeight != NewHeight) {
// Release any old data to avoid memory leaks

// Store dimensions
Surface->CurrentWidth = NewWidth;
Surface->CurrentHeight = NewHeight;

// Color buffer
D3D11_TEXTURE2D_DESC TextureDescription = {
NewWidth,//UINT Width;
NewHeight,//UINT Height;
1,//UINT MipLevels;
1,//UINT ArraySize;
1, 0,//DXGI_SAMPLE_DESC SampleDesc;
0,//UINT CPUAccessFlags;
0//UINT MiscFlags;
DXUTGetD3D11Device()->CreateTexture2D( &TextureDescription, NULL, &Surface->ColorBuffer );

// Depth buffer
D3D11_TEXTURE2D_DESC DepthTextureDescription = TextureDescription;
DepthTextureDescription.Format = DXGI_FORMAT_R32_TYPELESS;
DepthTextureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
DXUTGetD3D11Device()->CreateTexture2D( &DepthTextureDescription, NULL, &Surface->DepthBuffer );

// Depth I/O
D3D11_DEPTH_STENCIL_VIEW_DESC DepthIODescription = {
DXUTGetD3D11Device()->CreateDepthStencilView( Surface->DepthBuffer, &DepthIODescription, &Surface->DepthInputAndOutput );

// Color output
D3D11_SHADER_RESOURCE_VIEW_DESC TextureOutputDescription = { TextureDescription.Format, D3D11_SRV_DIMENSION_TEXTURE2D, 0, 0 };
TextureOutputDescription.Texture2D.MipLevels = 1;
DXUTGetD3D11Device()->CreateShaderResourceView( Surface->ColorBuffer, &TextureOutputDescription, &Surface->ColorOutput );

// Color input
D3D11_RENDER_TARGET_VIEW_DESC TextureInputDescription;
TextureInputDescription.Format = TextureDescription.Format;
TextureInputDescription.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
TextureInputDescription.Texture2D.MipSlice = 0;
DXUTGetD3D11Device()->CreateRenderTargetView(Surface->ColorBuffer, &TextureInputDescription, &Surface->ColorInput );

void InitEmptyDrawSurface(DrawSurfaceItem* Surface) {
Surface->IsScreen = false;
Surface->CurrentWidth = -1;
Surface->CurrentHeight = -1;
Surface->ColorInput = NULL;
Surface->ColorBuffer = NULL;
Surface->ColorOutput = NULL;
Surface->DepthBuffer = NULL;
Surface->DepthInputAndOutput = NULL;

void GetScreenDrawSurface(DrawSurfaceItem* Surface) {
Surface->IsScreen = true;
Surface->CurrentWidth = g_Width;
Surface->CurrentHeight = g_Height;
Surface->ColorInput = DXUTGetD3D11RenderTargetView();
Surface->ColorBuffer = NULL;
Surface->ColorOutput = NULL;
Surface->DepthBuffer = NULL;
Surface->DepthInputAndOutput = DXUTGetD3D11DepthStencilView();

void ReleaseDrawSurface(DrawSurfaceItem* Surface) {
SAFE_RELEASE( Surface->ColorInput );
SAFE_RELEASE( Surface->ColorBuffer );
SAFE_RELEASE( Surface->ColorOutput );
SAFE_RELEASE( Surface->DepthBuffer );
SAFE_RELEASE( Surface->DepthInputAndOutput );

Make a set of pixel shaders that will sample pixels from a set of input textures with some basic effects.
Use them to draw a quad without 3D projection to an output texture.
Make calls for rendering from one thing to another.
Use a linear blur filter 4 times to get 8 directions. Since they are linked in serial instead of paralell, their distribution will look like a perfectly round diffused blur like the one in a human eye.

RenderScene( &SurfaceA ); // World -> SurfaceA
RenderEffect( &SurfaceA, NoSx3, &SurfaceB, Common_PixelShaderType_Effect_Blur_Linear, NoMirror, -4.0f, 4.0f, 1.0f, 0.0f ); // SurfaceA -> SurfaceB (Horizontal blur)
RenderEffect( &SurfaceB, NoSx3, &SurfaceC, Common_PixelShaderType_Effect_Blur_Linear, NoMirror, -4.0f, 4.0f, 0.0f, 1.0f ); // SurfaceB -> SurfaceC (Vertical blur)
RenderEffect( &SurfaceC, NoSx3, &SurfaceB, Common_PixelShaderType_Effect_Blur_Linear, NoMirror, -3.0f, 3.0f, 1.0f, 1.0f ); // SurfaceC -> SurfaceB (Diagonal blur)
RenderEffect( &SurfaceB, NoSx3, &SurfaceC, Common_PixelShaderType_Effect_Blur_Linear, NoMirror, -3.0f, 3.0f, -1.0f, 1.0f ); // SurfaceB -> SurfaceC (Diagonal blur)
RenderEffect( &SurfaceC, NoSx3, &SurfaceB, Common_PixelShaderType_Effect_RaiseToArg, NoMirror, 2.0f, 2.0f, 2.0f, 1.0f ); // SurfaceC -> SurfaceB (Gamma)
RenderEffect( &SurfaceA, &SurfaceB, NoSx2, &SurfaceScreen, Common_PixelShaderType_Effect_ADD_AB, NoMirror, 0.5f, 1.5f, NoFx2 ); // SurfaceA, SurfaceB -> Screen (Blending)

SurfaceA has the same resolution as the screen but SurfaceB and SurfaceC are downsampled to 480x360 or 480x270 depending on the ratio.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this