seamless blur

Started by
6 comments, last by dblack 12 years, 10 months ago
hello, i am trying to implement a full screen effect, where the whole scene fades out blurry. it starts with a small blur and gets blurrier and blurrier.

now i know how to do a basic blur. just horizontally and vertically filter with a gaussian kernel. but what about larger kernel sizes? do you just increase the kernekl size? or do you just reblur an already existing blur?

thanks!
Advertisement
Repeated blurs will approximate a larger kernel size. The difference is just barely noticeable side-by-side. :o)
[TheUnbeliever]

Repeated blurs will approximate a larger kernel size. The difference is just barely noticeable side-by-side. :o)


thanks but isnt there a limit to kernel sizes?
i mean the fps will drop significantly with larger kernels, right?

[quote name='TheUnbeliever' timestamp='1307207157' post='4819472']
Repeated blurs will approximate a larger kernel size. The difference is just barely noticeable side-by-side. :o)


thanks but isnt there a limit to kernel sizes?
i mean the fps will drop significantly with larger kernels, right?
[/quote]

Since you want to do a transition between no blurred and blurred image, you should blur the image using a small kernel, show it, blur it again, show it, (...) and repeat until you think is good enough.
In my Gaussian Blur I use for Blooming I have a parameter called "Deviation". Most Gaussian- If you put this higher, the effect gets wider. It won't give the best quality for blooming (Gets Box-Shaped), but since you want to blur a whole image one should only barely see any difference.

Here's my code in case you didn't implement that parameter:

HRESULT PostFXBase::GetSampleOffsets_Bloom(DWORD dwD3DTexSize,
float afTexCoordOffset[15],
float* avColorWeight,
float fDeviation, float fMultiplier )
{
int i=0;
float tu = 1.0f / (float)dwD3DTexSize;

// Fill the center texel
float weight = 1.0f * GaussianDistribution( 0, 0, fDeviation );
avColorWeight[7] = weight;

afTexCoordOffset[7] = 0.0f;

// Fill the right side
for( i=1; i < 8; i++ )
{
weight = fMultiplier * GaussianDistribution( (float)i, 0, fDeviation );
afTexCoordOffset[7-i] = i * tu;

avColorWeight[7-i] = weight;
}

// Copy to the left side
for( i=8; i < 15; i++ )
{
avColorWeight = avColorWeight[14-i];
afTexCoordOffset = -afTexCoordOffset[14-i];
}

return S_OK;
}

float PostFXBase::GaussianDistribution( float x, float y, float rho )
{
float g = 1.0f / sqrtf( 2.0f * D3DX_PI * rho * rho );
g *= expf( -(x*x + y*y)/(2*rho*rho) );

return g;
}

Multiple passes is generally a cheap and effective way to simulate large blur kernels. Using a wider filter kernel will indeed degrade performance due to the extra texture samples required, and you may need a very wide kernel to match the level of "bluriness" provided by 2 passes. In that case, you will typically get much better performance out of 2 passes with a smaller kernel.
Also note, that you can easily down sample the source image in each blur pass by enabling bilinear filtering and sampling from in between four texels. That way, each blur pass operates on a quarter of the number of texels of the previous pass, and you can stack as many passes as you want without ever needing more than 33% more time than the first pass.

hello, i am trying to implement a full screen effect, where the whole scene fades out blurry. it starts with a small blur and gets blurrier and blurrier.

now i know how to do a basic blur. just horizontally and vertically filter with a gaussian kernel. but what about larger kernel sizes? do you just increase the kernekl size? or do you just reblur an already existing blur?

thanks!


You could also take a look at summed area tables and "iterative gaussian blurs"(ie the gaussian blur is re-organised so that it loops across pixels in a line and maintains a running sum, google for something like "recursive gaussian filters" or look in the nvidia SDK for an example, not sure which one).

David

This topic is closed to new replies.

Advertisement