I have a fairly bog-standard Gaussian blur filter (seperable) I'm using to make a glow effect in my pipeline. At the moment I'm rendering it only to 256x256 texture and then doing a very simple additive combine with the scene to get the effect.
Due to the low resolution of the blur texture, I get quite a bit of "shimmering" of the blur when the camera moves around. Actually I noticed this in the Mass Effect 2 game, where they "glow" the specular highlights and shimmering is visible there.
Does anyone know of any technique for reducing or eliminating shimmering/aliasing that doesn't involve rendering the blur to a higher resolution texture (and so killing performance)? I'm already using GL_LINEAR in my samplers, which helps a bit, but not all that much.
Here's a little YouTube clip of the blur, although it's hard to see after YouTube have downsized and messed around with the clip, unfortunately.
Note that I read this article about real-time glow, and they briefly mention shimmering, but don't go into detail about solutions.
For completeness, I include my blur shader below.
#version 420
// Input uniforms.
uniform vec2 uniform_TexelSize;
uniform float uniform_BlurScale;
uniform float uniform_BlurStrength;
uniform int uniform_Orientation;
uniform int uniform_BlurAmount;
// Shared.
in vec2 attrib_Fragment_Texture;
// Samplers
uniform sampler2D Map_Diffuse;
// Result
out vec4 Out_Colour;
// Local Functions
float Gaussian (float x, float deviation)
{
return (1.0 / sqrt(2.0 * 3.141592 * deviation)) * exp(-((x * x) / (2.0 * deviation)));
}
// Main
void main(void)
{
float halfBlur = float(uniform_BlurAmount) * 0.5;
float deviation = halfBlur * 0.35;
deviation *= deviation;
float strength = 1.0 - uniform_BlurStrength;
vec4 colour = vec4(0.0), texColour = vec4(0.0);
// Horizontal or vertical?
if (uniform_Orientation == 0)
{
// Horizontal.
for (int i = 0; i < 10; ++i)
{
if (i >= uniform_BlurAmount)
break;
float offset = float(i) - halfBlur;
texColour = texture2D(Map_Diffuse, attrib_Fragment_Texture + vec2(offset * uniform_TexelSize.x * uniform_BlurScale, 0.0)) * Gaussian(offset * strength, deviation);
colour += texColour;
}
}
else
{
// Vertical.
for (int i = 0; i < 10; ++i)
{
if (i >= uniform_BlurAmount)
break;
float offset = float(i) - halfBlur;
texColour = texture2D(Map_Diffuse, attrib_Fragment_Texture + vec2(0.0, offset * uniform_TexelSize.y * uniform_BlurScale)) * Gaussian(offset * strength, deviation);
colour += texColour;
}
}
Out_Colour = colour;
}