How do I use an OpenGL shader to modify an existing texture / frame buffer in place without using a second texture or frame buffer? Is this even possible?
-
1nope you need a separate buffer to hold the old while you are writing the new, you just cannot get around that.ratchet freak– ratchet freak2015-01-12 16:02:02 +00:00Commented Jan 12, 2015 at 16:02
-
So it's not possible to use the same texture as a sampler and frame buffer?jjxtra– jjxtra2015-01-12 16:05:34 +00:00Commented Jan 12, 2015 at 16:05
-
Think about how it would work behind the scenes, when a fragment shader samples a pixel already written by a previous invocation, OpenGL prevents programmers making that mistakeratchet freak– ratchet freak2015-01-12 16:10:31 +00:00Commented Jan 12, 2015 at 16:10
-
So let's say I want to blur just a small part of a texture. I have to run it through a shader to a second texture and then copy that texture back to the first texture / frame buffer?jjxtra– jjxtra2015-01-12 16:14:09 +00:00Commented Jan 12, 2015 at 16:14
-
You can use image load/store or texture barriers to do this, but that is so complicated (you have to implement synchronization among all of the parallel shader invocations yourself) it is almost out of the question. The extra work will not get you anything worthwhile the majority of the time.Andon M. Coleman– Andon M. Coleman2015-01-12 16:39:25 +00:00Commented Jan 12, 2015 at 16:39
2 Answers
At first: It is technically possible and safe to read and write in the same pass using this extension - however i wouldn't recommend this, especially for learners, since the extension is tightly limited and might not be supported on every hardware.
That being said:
So it's not possible to use the same texture as a sampler and frame buffer?
You can use the same texture as a framebuffer texture attachment and render to it and as a texture sampler to look up values in the shader, but not in the same pass. That means, if you have two textures you could read from A and write to B and afterwards switch textures and read from B and write to A. But never A->A or B->B (without the extension mentioned).
As a technical detail, a texture currently being used as a target can also be bound to a sampler shader variable at the same time, but you must not use it.
So let's say I want to blur just a small part of a texture. I have to run it through a shader to a second texture and then copy that texture back to the first texture / frame buffer?
Second texture yes. But for efficiency reasons do not copy the texture data back. Just delete the source texture and use the target texture you have rendered to in the future. If you have to do this often, keep the source texture as a render target for later use to increase performance. If you have to do it every frame just swap the textures every frame. The overhead is minimal.