[DX9] Blur with variable radius

Started by
6 comments, last by Igor Kokarev 11 years ago

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.

Advertisement

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.

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.

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).

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.

Thanks, I'll try Summed Area Tables.

We afraid that Summed Area Tables on PS 2.0 will not work fast enough.

Computable shaders is a good idea, but it require DX11 or Cuda.

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*pixelwidth);
cl+=tex2D(s0, coord)*BlurWeights;
}
return cl;
}

This topic is closed to new replies.

Advertisement