How to do multipass with DirectX11 ?

Started by
2 comments, last by Stewie.G 6 years, 1 month ago

Hi,

I've been trying to implement a gaussian blur recently, it would seem the best way to achieve this is by running a bur on one axis, then another blur on the other axis.

I think I have successfully implemented the blur part per axis, but now I have to blend both calls with a proper BlendState, at least I think this is where my problem is.

Here are my passes:


RasterizerState DisableCulling
{
	CullMode = BACK;
};

BlendState AdditiveBlend
{
	BlendEnable[0] = TRUE;
	BlendEnable[1] = TRUE;
	SrcBlend[0] = SRC_COLOR;
	BlendOp[0] = ADD;
	BlendOp[1] = ADD;
	SrcBlend[1] = SRC_COLOR;
};

technique11 BlockTech
{
	pass P0
	{
		SetVertexShader(CompileShader(vs_5_0, VS()));
		SetGeometryShader(NULL);
		SetPixelShader(CompileShader(ps_5_0, PS_BlurV()));
		SetRasterizerState(DisableCulling);
		SetBlendState(AdditiveBlend, float4(0.0, 0.0, 0.0, 0.0), 0xffffffff);
	}

	pass P1
	{
		SetVertexShader(CompileShader(vs_5_0, VS()));
		SetGeometryShader(NULL);
		SetPixelShader(CompileShader(ps_5_0, PS_BlurH()));
		SetRasterizerState(DisableCulling);
	}
}

 


    D3DX11_TECHNIQUE_DESC techDesc;
	mBlockEffect->mTech->GetDesc( &techDesc );
	
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
        deviceContext->IASetVertexBuffers(0, 2, bufferPointers, stride, offset);
		deviceContext->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0);

		mBlockEffect->mTech->GetPassByIndex(p)->Apply(0, deviceContext);		
        deviceContext->DrawIndexedInstanced(36, mNumberOfActiveCubes, 0, 0, 0);
    }

No blur

n9dQut9.png

 

PS_BlurV

c00sz4O.png

PS_BlurH

y8LI5L8.png

P0 + P1

VUq76xO.png

As you can see, it does not work at all.

I think the issue is in my BlendState, but I am not sure.

I've seen many articles going with the render to texture approach, but I've also seen articles where both shaders were called in succession, and it worked just fine, I'd like to go with that second approach. Unfortunately, the code was in OpenGL where the syntax for running multiple passes is quite different (http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/). So I need some help doing the same in HLSL :-)

 

Thanks!

Advertisement

A separable blur isn't a "typical" multi-pass technique where you just draw multiple times with a particular blend state. Instead, the second pass needs to read the results of the first pass as a texture. This requires changing render targets and shader resource view bindings between your draw calls. The basic flow goes something like this (in pseudo-code):


// Draw the scene to the "main pass" render target 
SetRenderTarget(mainPassTarget.RTV);
DrawScene();

// Draw the vertical pass using the main pass target as its input
SetRenderTarget(blurTargetV.RTV);
SetShaderResourceView(mainPassTarget.SRV);
SetPixelShader(blurVerticalPS);
DrawQuad();

// Draw the horizontal pass using the vertical blur target as its input
SetRenderTarget(finalBlurTarget.RTV);
SetShaderResourceView(blurTargetV.SRV);
SetPixelShader(blurHorizontalPS);
DrawQuad();




 
On 2/18/2018 at 8:38 PM, MJP said:

A separable blur isn't a "typical" multi-pass technique where you just draw multiple times with a particular blend state. Instead, the second pass needs to read the results of the first pass as a texture. This requires changing render targets and shader resource view bindings between your draw calls. The basic flow goes something like this (in pseudo-code):
 



// Draw the scene to the "main pass" render target 
SetRenderTarget(mainPassTarget.RTV);
DrawScene();

// Draw the vertical pass using the main pass target as its input
SetRenderTarget(blurTargetV.RTV);
SetShaderResourceView(mainPassTarget.SRV);
SetPixelShader(blurVerticalPS);
DrawQuad();

// Draw the horizontal pass using the vertical blur target as its input
SetRenderTarget(finalBlurTarget.RTV);
SetShaderResourceView(blurTargetV.SRV);
SetPixelShader(blurHorizontalPS);
DrawQuad();

 

 

 


 

 

 

Thank you very much, I tried this approach, and it works just fine!

This topic is closed to new replies.

Advertisement