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.

To apply post effects, it is often needed to read the preliminary image, perform computations on its pixels and store the result in the same texture again. For example, think of a tone mapping or desaturation effect. The input and output should be the same texture, but this isn't allowed by OpenGL.

Therefore, what is a good workaround?

One idea I came up with but which isn't very satisfying is to have two image textures and automatically use them alternating. Also keeping track of which is the newer one to finally display it on the screen.

share|improve this question
    
For many effects (those involving convolution) this would be an undesirable trait. The system I am currently working with uses a texture pool to limit GPU allocations, with the option to ensure uniqueness if necessary. The idea of a double buffered post processing target is the implementation I have seen, though I cannot say if there are suitable alternatives. –  Evan Jun 16 '13 at 16:12
    
I don't want every effect to use it. For example a pass that blurs out an image for later use in another effect shouldn't write to its input! But in some cases it would be very useful. You texture pool idea sounds interesting. Could you elaborate on it, please? –  danijar Jun 16 '13 at 16:15
    
The texture pool allocates textures on the GPU of the desired size and format, and stores it as a non-unique texture. Whenever a texture is requested from the texture-pool again, unless it is specified that it be unique (textures are sorted by size, format, and index) it will simply give you a pointer to the existing texture of that size. This works fine in most situations, but it doesn't get around the necessity for separate source and target textures when post processing. The deferred rendering pipeline I currently use simply performs a copy pass before the post process. –  Evan Jun 16 '13 at 16:24
    
Thanks. You mentioned another workaround, that is, sampling for a copy of the texture and rendering to the original. Do you know whether it is worth to avoid this copying for performance reasons? –  danijar Jun 16 '13 at 17:06
    
Well there is no doubting the fact that a copy is more of a performance hit than not copying. Ultimately it is equal to rendering a single quad the size of your screen. A minor performance hit. Probably not worth the time it would take to discover a work around, but you could always profile it for fun. –  Evan Jun 16 '13 at 18:19
add comment

1 Answer 1

up vote 1 down vote accepted

One idea I came up with but which isn't very satisfying is to have two image textures and automatically use them alternating. Also keeping track of which is the newer one to finally display it on the screen.

This is actually the way it's commonly done, and the technique even has a name: "ping-ponging".

There's some discussion on the technique here (look for the section headed "ping-pong texturing").

As for the "why", if you think about it, it makes sense. Many post-processing effects don't actually have a direct one-to-one mapping between source and destination texels (or "fragments" if you prefer; I'll just continue to use "texels" here as it may be clearer to aid understanding). Common examples would be blur and distortion effects, where the source texel position may not be same as the destination position. What this could mean is that your input could have been a texel that was previously already processed, and so is not valid.

This is leaving aside any hardware considerations, but it is worth noting that hardware can make certain assumptions ahead of time if it is guaranteed that you're not going to read from and write to the same image, and that those assumptions can lead to better performance.

If you're running an effect where you know that you're always going to have this one-to-one mapping (e.g. maybe simulating a gamma curve using FBOs) then you've got image load/store in OpenGL and that provides an option that would meet this requirement, although I'd encourage you to do a comparative benchmark before committing, as it may be the case that you'll still get better performance from doing it the traditional way.

share|improve this answer
    
Thanks a lot. Ping-pong texturing makes it a bit harder to toggle a single effect, but I'll develop automatic mechanisms for that. By the way, do you know how big the overhead of copying the texture for sampling would be? –  danijar Jun 16 '13 at 17:11
    
Make it a separate question otherwise this one could run and run in comments. ;) –  Jimmy Shelter Jun 16 '13 at 18:41
add comment

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.