Hi, I’m trying to implement a shader that simulates a translucent window: everything behind it is blurried. I got some nice results, but I would like to implement a gaussian blur which size depends on the distance of the object.
Up to now I use if() statements to decide whether or not to add more blur, but I don’t like this way.
Have you a better algorithm (yet fast, if possible) to parametrize the gaussian blur intensity?
Thank you!
cignox1,
I have a code to create a 1-D Gaussian kernel with given sigma value (standard deviation).
///////////////////////////////////////////////////////////////////////////////
// generate 1D Gaussian kernel
// kernel size should be odd number (3, 5, 7, 9, ...)
///////////////////////////////////////////////////////////////////////////////
void makeGaussianKernel(float sigma, float *kernel, int kernelSize)
{
//const double PI = 3.14159265; // PI
int i, center;
float sum = 0; // used for normalization
double result = 0; // result of gaussian func
// compute kernel elements normal distribution equation(Gaussian)
// do only half(positive area) and mirror to negative side
// because Gaussian is even function, symmetric to Y-axis.
center = kernelSize / 2; // center value of n-array(0 ~ n-1)
if(sigma == 0)
{
for(i = 0; i <= center; ++i)
kernel[center+i] = kernel[center-i] = 0;
kernel[center] = 1.0;
}
else
{
for(i = 0; i <= center; ++i)
{
//result = exp(-(i*i)/(double)(2*sigma*sigma)) / (sqrt(2*PI)*sigma);
// NOTE: dividing (sqrt(2*PI)*sigma) is not needed because normalizing result later
result = exp(-(i*i)/(double)(2*sigma*sigma));
kernel[center+i] = kernel[center-i] = (float)result;
sum += (float)result;
if(i != 0) sum += (float)result;
}
// normalize kernel
// make sum of all elements in kernel to 1
for(i = 0; i <= center; ++i)
kernel[center+i] = kernel[center-i] /= sum;
}
// DEBUG //
#if 0
cout << "1-D Gaussian Kernel
";
cout << "===================
";
sum = 0;
for(i = 0; i < kernelSize; ++i)
{
cout << i << ": " << kernel[i] << endl;
sum += kernel[i];
}
cout << "Kernel Sum: " << sum << endl;
#endif
}
If sigma is increases, the image gets more blurry. And the kernel size would also grow. To determine the kernel size, I use the following formula:
Thank you both! Yes, currently I use up to 4x4 filters, and it can be really slow, but it would be used only for small windows, so it shouln’t be a problem
cignox1,
Should the kernel size be odd number, for example 5x5?
And, you may increase performace by using seperable convolution, because Gaussian kernel is separable. Multiplications can be down from M*N to M+N.
Please check the link for separable convolution. There is an example to compare 2D and seperable convolution performance with Gaussian filter, too: www.songho.ca/dsp/convoluton.html