I compute Gaussian blur in two passes (horizontally and vertically). Shaders look like this:
Horizontal blur - fragment shader:
#version 420
layout (location = 0) out vec4 outColor;
in vec2 texCoord;
float PixOffset[5] = float[](0.0,1.0,2.0,3.0,4.0);
float Weight[5] = float[]( 0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162 );
float scale = 4.0;
uniform sampler2D texture0;
uniform vec2 screenSize;
void main(void)
{
float dx = 1.0 / screenSize.x;
vec4 sum = texture(texture0, texCoord) * Weight[0];
for( int i = 1; i < 5; i++ )
{
sum += texture(texture0, texCoord + vec2(PixOffset[i], 0.0) * scale * dx ) * Weight[i];
sum += texture(texture0, texCoord - vec2(PixOffset[i], 0.0) * scale * dx ) * Weight[i];
}
outColor = sum;
}
I use deferred rendering and the following screens shows a diffuse material texture after blurring. I simplified a render loop for the sake of clarity(only one render target - a diffuse material).
A render loop - first case:
- bind fbo1
- gbuffer stage
unbind fbo1
bind fbo2
- read a diffuse texture, render to a temporary texture (full screen quad)
- read a temporary texture, horizontal blur, render to a temporary texture (full screen quad)
- read a temporary texture, vertical blur, render to a temporary texture (full screen quad)
unbind fbo2
read a temporary texture, render to the default framebuffer (full screen quad)
The final image has artifacts(flickering pixels). Some of them are placed between two triangles which create the full screen quad.Screen1
A render loop - second case:
- bind fbo1
- gbuffer stage
unbind fbo1
bind fbo2
- read a diffuse texture, render to a temporary texture (full screen quad)
- read a temporary texture, horizontal blur, render to a temporary texture (full screen quad)
unbind fbo2
read a temporary texture, vertical blur, render to the default framebuffer (full screen quad)
Some artifacts may appear between triangles: Screen2
A render loop - third case:
- bind fbo1
- gbuffer stage
unbind fbo1
bind fbo2
- read a diffuse texture, horizontal blur, render to a temporary texture (full screen quad)
unbind fbo2
read a temporary texture, vertical blur, render to the default framebuffer (full screen quad)
The final image doesn't contain artifacts.Screen3
How to fix that ? The above code is simplified but normally the first case(render loop order) is most useful, for example: I want to blur a glow texture and use it when shading.