In fact, two-sided blurring is not much different from Gaussian blurring, you just need to multiply the sample value by a Gaussian coefficient multiplied by the result of the "proximity" function between the actual values of the center pixel and the selected pixel.
So in pseud GLSL
vec3 centreColour = texture2D(image,texCoord); vec3 result = centreColour; float normalization = 1; for (int i = 0; i < NUM_SAMPLES; ++1) { vec3 sample = texture2D(image, texCoord + offsets[i]); float gaussianCoeff = computeGaussianCoeff(offsets[i]); //depends on your implementation, this is quick float closeness = 1.0f - distance(sample,centreColour) / length(vec3(1,1,1)); float sampleWeight = closeness * gaussian; result += sample * sampleWeight; noralization += sampleWeight; } vec3 bilateral = result / normalization;
You should probably have a better way to determine the meaning of proximity, for example, in a perceptually uniform space such as LUV.
For optimization, you can apply all the methods that work to blur gaussian, except those that ignore the fact that you need to know the pixel value. For example, with a pure Gaussian language, you can select your Texcoords wisely and integrate 4 pixels into one selection. This will not work.
Great things that work:
* Separate your filter. Instead of 5x5 samples (25), make 5 horizontally, save to intermediate buffer and make 5 vertically. It will not look exactly the same, but it will remove the noise anyway.
* Run the filter at a lower resolution and compose it with orignal to get more information.
source share