Jump to content
  • Advertisement
Sign in to follow this  
Paul C Skertich

Making gaussian blur more blurry

This topic is 1157 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I don't feel like creating a render target and rendering a quad to that render target with the horizontal and vertical gaussian blur shader.

 

There has to be a way to create two pass or three pass or even more within the shader, right?

 

All I want to do is create render target then create the quad with horizontal and verticle blur and be done with the desired blur strength I desire.

 

[horizontalGaussianBlur.hlsl]

 // Create the weights that each neighbor pixel will contribute to the blur.
    float weight0 = 1.0f;
    float weight1 = 0.9f;
    float weight2 = 0.55f;
    float weight3 = 0.18f;
    float weight4 = 0.1f;
	
	float normalization = (weight0  + 2.0f * (weight1 + weight2 + weight3 + weight4));
	weight0 /= normalization;
	weight1 /= normalization;
	weight2 /= normalization;
	weight3 /= normalization;
	weight4 /= normalization;
	
	float3 tc = float3(0,0,0);
 	
 	
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * -4.0f,0.0f)).rgb * weight4;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * -3.0f,0.0f)).rgb * weight3;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * -2.0f,0.0f)).rgb * weight2;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * -1.0f,0.0f)).rgb * weight1;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * -0.0f,0.0f)).rgb * weight0;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * 1.0f,0.0f)).rgb * weight1;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * 2.0f,0.0f)).rgb * weight2;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * 3.0f,0.0f)).rgb * weight3;
	tc += ObjTexture.Sample(ss[2], input.texCoord +  float2( 1.0f / screenSize.x * 4.0f,0.0f)).rgb * weight4;
	
	return float4(tc, 1.0f);

How would I apply a second pass or third pass or N amount of pass I choose? I'm not using the effect framework.

 

Share this post


Link to post
Share on other sites
Advertisement

How would I apply a second pass or third pass or N amount of pass I choose?

You issue N draw calls, ping ponging between two render targets... Like you don't want to do.

Or, implement the blur as a compute shader instead of a pixel shader. Use UAVs so you can read/write the same target simultaneously. Loop N times, and perform the necessary synchronization between parts of the algorithm that read from the UAV and that write to it.

Share this post


Link to post
Share on other sites

Originally I was performing

 

Render scene normally down sized to render target A

Horizontal blur Quad from render target A

Render Vertical blur Quad from render Target A to Render Target B

Render Horizontal Blur Quad to from Render Target B to Render Target C

render Verticle Blur Quad from render target C to render target D

up size render target D to final output quad

Render screen quad to screen.

 

I do have a gaussian blur shader which can be performed in just render target A and render target B then finally output it. However, the compute shader would be most ideal approach then I have to make sure the group threads are in sync.

 

The vertical gaussian and horizontal gaussian blur shaders were in seperate shader files.

 

I tried to visually what the gaussian blur was doing -

what I gather is this:

 

it samples a texel a given point moving it over depending on the offset and weight. If I'm wrong then correct me of course. It's just my visualization of what is going on in the gaussian blur.

Share this post


Link to post
Share on other sites

If your goal is just to make it "blurrier" you really don't need multiple passes (well not more than 2) but you can space more the samples you fetch.

Supposing you want a gaussian blur with 7 taps:

 

This is not actual code, is just to give an idea. 


const float weights[7] = {0.006, 0.061, 0.242, 0.382, 0.242, 0.061, 0.006}; // This would be equivalent to a gauss blur with std dev 1 
const int offsets[7] = {-3, -2, -1, 0, 1, 2, 3};


float2 width = direction*gaussWidth*pixelSize;   // Direction is (0,1) or (1,0) based on vertical or horizontal
for(int i=0; i<7; i++){
    OutColor += TextureSample(sceneColor, sceneColorSampler, UV + offsets[i]*width)*weights[i];
}

 

Increasing gaussWidth will increase the amount of blur. 

 

This will introduce visible artefacts if you chose a very high width, but works well for reasonable blurs. 

Edited by cifa

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!