Sign in to follow this  

SSAO blur

This topic is 2345 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

Hello, I'm implementing SSAO and I'm having some troubles with the blur.
What I do is:
1) Render ssao to half-res buffer (I use full-res normals/depth buffer)
2) Blur ssao to full-res buffer, first horizontally then vertically

And this is my output:
[img]http://santisanchez28.files.wordpress.com/2011/07/halfres_blur.jpg[/img]

It looks like it's blurring more in the y axis. Besides it's still kind of noisy, although it has 32 samples for ssao and a big blur size.
Increasing the size of the blur even more doesn't make any difference.
Should I upsample the ssao buffer before blurring? Or do you think this is good enough?
I've read that some people use a downsampled normal/depth buffer when rendering ssao to a lower resolution. Would doing this help?

Here is the ssao buffer without the blur and in full-res:
[img]http://santisanchez28.files.wordpress.com/2011/07/fullres_noblur.jpg[/img]

Share this post


Link to post
Share on other sites
[quote name='Santisan' timestamp='1310255739' post='4833195']2) Blur ssao to full-res buffer, first horizontally then vertically[/quote]
Do you actually mean that you blur the SSAO horizontally to an intermediate buffer, and then vertically blur that buffer onto your final render target?

First get this blur method working:

Blur horizontally onto intermediate buffer.
Blur vertically onto original SSAO buffer.
Copy original SSAO buffer onto final render target (using bilinear mag filter).

If that works, then you can skip the copy to the original SSAO buffer and copy directly onto your final render target while vertically blurring.

If you are already doing that, then let's see your blur shader and tell us the parameters set on the shader.

Share this post


Link to post
Share on other sites
What I was doing in the first picture was:
1- SSAO onto half-res buffer
2- blur horizontally onto intermediate buffer (full-res)
3- blur vertically onto final render target

If I do the 2nd step to half-res, the 3rd step to the ssao buffer and then copy to the final render target using
bilinear mag filter I get this output:
[img]http://santisanchez28.files.wordpress.com/2011/07/halfres_blur2.jpg[/img]

This is the fragment shader. It is (or tries to be) a bilateral filter like the one explained [url="http://developer.amd.com/gpu_assets/ShopfMixedResolutionRendering.pdf"]here[/url].
Parameters are: kernelSize = 11, positionThreshold = 0.5, normalThreshold = 0.15

[code]
float4 main(vertex2fragment IN, uniform sampler2D NormalBuffer, uniform sampler2D AOBuffer,
uniform float2 InvViewportSize, // (1/viewport.width, 1/viewport.height)
uniform int KernelSize, uniform float PositionThreshold, uniform float NormalThreshold) : COLOR
{
float2 texCoord = (IN.ScreenPos.xy / IN.ScreenPos.w) * 0.5f + 0.5f;
float4 normalDepthVS = tex2D (NormalBuffer, texCoord);
float3 pixelNormalVS = normalDepthVS.rgb * 2.0f - 1.0f;
float pixelDepth = normalDepthVS.a;

float weightedAO = 0.0f;
float AO = 0.0f;
float weightSum = 0.0f;

for (int i = -KernelSize; i <= KernelSize; i++)
{
float2 sampleTexCoord = texCoord + float2 (i * InvViewportSize.x, 0.0f);
float4 sampleDepthNormalVS = tex2D (NormalBuffer, sampleTexCoord);
float3 sampleNormalVS = sampleDepthNormalVS.rgb * 2.0f - 1.0f;
float sampleDepth = sampleDepthNormalVS.a;

float deltaZ = sampleDepth - pixelDepth;
float dotN = dot (pixelNormalVS, sampleNormalVS);
float4 sampleAO = tex2D (AOBuffer, sampleTexCoord);

if (deltaZ < PositionThreshold && dotN > 1.0f - NormalThreshold)
{
float totalWeight = pow (dotN, 32.0f) / (EPSILON + deltaZ); //EPSILON=0.01f
weightedAO += sampleAO.a * totalWeight;
weightSum += totalWeight;
}
AO += sampleAO.a;
}

if (weightSum > 0.0f)
{
AO = weightedAO / weightSum;
}
else
{
AO /= 2.0f * KernelSize + 1.0f;
}
return float4 (AO);
}
[/code]

Share this post


Link to post
Share on other sites
Hidden
[quote name='Santisan' timestamp='1310338573' post='4833500']
What I was doing in the first picture was:
1- SSAO onto half-res buffer
2- blur horizontally onto intermediate buffer (full-res)
3- blur vertically onto final render target[/quote]

Isn't step 2 the problem then? (As you will get a different amount of horizontal blur when upscaling than when you vertically blur to the same scale.)

Did you try blurring as I suggested to see if that is in fact the problem?

I realize that the method that I suggested is not the most performant one, but it is easy to test, and the point is to see if this is the source of your blur issue.

Share this post


Link to post
You probably don't want to blur at full res. Blurring at full res requires a [i]huge[/i] sampling radius to look good which can be very expensive, especially if you do it in a pixel shader without shared memory. Even at quarter res a wide-radius bilateral blur won't be cheap.

Share this post


Link to post
Share on other sites
I think the idea of SSAO performed at low res is to do the blurring at the low res, and then bilateral upsample to full res. (Where bilateral upsampling is essentially bilinear upsampling with normal and depth values affecting edge weights).


Like MJP pointed out, you are trying to simultaneously blur and upsample to full res at the same time.


Am I right?

Share this post


Link to post
Share on other sites
Ok thanks both for the answers.

My ssao has a flickering pattern in the shadowed areas. I know it's a common problem, and when performing ssao at full res
or even at half res it's not that noticeable, but at quarter resolution it gets really annoying. Is there anything I can do to improve
this?

Share this post


Link to post
Share on other sites
[quote name='Santisan' timestamp='1310511909' post='4834560']My ssao has a flickering pattern in the shadowed areas. I know it's a common problem, and when performing ssao at full res
or even at half res it's not that noticeable, but at quarter resolution it gets really annoying. Is there anything I can do to improve
this?[/quote]


Here are a few AO methods:
[url="http://www.jshopf.com/blog/?p=226"]http://www.jshopf.com/blog/?p=226[/url]

The first one, [url="http://www.cs.utah.edu/~loos/publications/vo/vo.pdf"]volumetric obscurance[/url], chooses samples that create less noise in both statically and temporally.




Also, inspecting the shader code you posted above, I see that your "bilateral filter" behaves very little like the one in the paper you mentioned.

The bilateral filter in that paper takes 8 samples (4 fine + 4 coarse) of the color, normal and depth, and applies a weighting to each set of the color/normal/depth samples. This filter is done in one pass.

Your shader appears to be doing two passes and 11 samples per pass.


If you fix that shader, the perf gain might leave you with similar performance to your current 1/4 res implementation, where there is less temporal noise?

Share this post


Link to post
Share on other sites

This topic is 2345 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.

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