Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

share|improve this question
    
You know, you can upload pictures directly to this site... Otherwise they'll disappear one day (like your first screen). –  Dudeson Aug 24 at 15:29
    
I'm confused by your description of your render passes. Is fbo2 the temporary texture that you render to during the blur? Do you have multiple temporary textures, each with its own fbo? Or are you attempting to re-use the same temporary texture / fbo for multiple passes (which won't generally work, and could explain the artifacts)? –  Nathan Reed Oct 7 at 23:53

1 Answer 1

This is probably the issue: https://www.opengl.org/wiki/Framebuffer_Object#Feedback_Loops

Using a texture that is currently bound to an FBO that is current bound as the rendering target is undefined.

You must unbind the FBO before using the texture. You can leave the texture bound to the FBO so long as the FBO itself is unbound. You need to bind a 2nd FBO with a 2nd temporary texture to do the vertical blur step.

The GPU is, in parallel, starting to reading old texture data while its still rendering to the FBO and/or the FBO result is still in the GPU render cache and hasn't yet been flushed to texture memory and the texture render cache contains old data.

Unbinding the FBO tells the GPU to finish and commit all its cached data to texture memory and invalidate the old texture sampling cache before starting to render the next step and properly sample the new texture data.

Cheers,

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.