Sign in to follow this  
Igor Kokarev

[DX9] Blur with variable radius

Recommended Posts

Please advice blur with variable radius with good quality for entire screen.

 

I've read advice to use separated gaussian blur x, y axis. However all examples were for certain fixed radius. How to implement variable radius?

 

Also it's important to avoid moire artefacts for animated objects inside blurred scene. We tried downsampling + spline and it gave moire defects.

 

 

Share this post


Link to post
Share on other sites

How dynamic are the variable radius ? Is it on a per pixel level or per game session (depending only on the visual settings ? ).

Here are some tips:

1. If you really have a dynamic setup, try to save different gaussian distributions in a texture and sample the texture.

2. If the setup change not very often, try to generate the shader coder just before uploading it. This way you avoid recalculation of the gaussian distribution and you have a fix range, which avoids dynamic for-loops (better performance on older hardware).

 

Edit:

3. You can use pre-processor directive to choose between a fix set of precoded configurations.

Edited by Ashaman73

Share this post


Link to post
Share on other sites

As above, can you give some more information on what you're doing?

 

I did a DOF blur effect with a variable width Gaussian blur per pixel for this scene, by first implementing a regular two-pass Gaussian blur shader, and then simply scaling my texture coordinate offsets per pixel. I think that shader is using 5 samples per pixel in each direction.

Share this post


Link to post
Share on other sites

Thanks for your responses!

 

I need to apply a dynamic blur to photography for multimedia application in realtime. Blur radius will change in every frame smoothly. Radius will be between 0 and around 150.

 

Hodgman,

I see very nice blur on your screenshot. My congratulations! Regrettably I need variable blur adjustable by user (templates).

Edited by SirIgor

Share this post


Link to post
Share on other sites

Using traditional techniques, you would either want to recompile hundreds of different blur shaders for those different radii, as they'll all need different numbers of samples and different weights, or you'd have to use a loop in the shader to dynamically choose the number of weights.
 
Those traditional blur techniques are not very efficient at such large radii though.
A better technique would be to look into Summed Area Tables (SAT), e.g. http://www.nvidia.com/docs/IO/8227/GDC2003_SummedAreaTables.pdf
Or look in to using compute shaders to implement the typical gaussian blur.

Edited by Hodgman

Share this post


Link to post
Share on other sites

Update: The problem is solved. Thanks.

 

We're trying to implement 2-pass Gaussian blur on HSL2.0. Here is a code of shader for horizontal blur. Pixelwidth is a radius. This shader doesn't work, the result looks as without the shader, please can you help?

sampler s0: register(s0);

float1 pixelwidth: register(c0);

float PixelKernel[13] =
{
-6,
-5,
-4,
-3,
-2,
-1,
0,
1,
2,
3,
4,
5,
6,
};

static const float BlurWeights[13] =
{
0.002216,
0.008764,
0.026995,
0.064759,
0.120985,
0.176033,
0.199471,
0.176033,
0.120985,
0.064759,
0.026995,
0.008764,
0.002216,
};

float1 Clip(float1 arg): float1
{
if (arg<0) arg=0;
if (arg>1) arg=1;
return arg;
}

float4 main_ps(float2 tex: TEXCOORD0):COLOR
{
float4 cl=(0,0,0,0);
float2 coord=tex;
for (int i=0; i<13; i++){
coord.x=Clip(tex.x+PixelKernel[i]*pixelwidth);
cl+=tex2D(s0, coord)*BlurWeights[i];
}
return cl;
}
Edited by SirIgor

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