Search code examples
openglglslshader

Setting neighbor fragment color via GLSL


I need to setup a GLSL fragment shader to change the color of a fragment other than the one currently being processed. Since that may not seem desirable, I'll provide a very brief context.

The project utilizes a render pass whereby a given model is drawn into an FBO with unique colors that correspond to UV coordinates in the texture map. These colors are then sampled and converted to image coordinates so that the texture map for the model can be updated based on what's visible to the camera. Essentially:

Render model to FBO
For each FBO pixel
   1. sample secondary texture based on FBO pixel position
   2. convert color at current pixel to image coordinate for the model's texture map
   3. update model's texture with sampled secondary texture at calculated coordinate
End loop

The problem is that the current implementation is very CPU bound, so I'm reading the pixels out of the FBO and then manipulating them. Ideally, since I already have the color of the fragment to work with in the fragment shader, I want to just tack on the last few steps to the process and keep everything on the GPU.

The specific issue I'm having is that I don't quite know how (or if it's even possible) to have a fragment shader set the color of a fragment that it is not processing. If I can't work something up by using an extra large FBO and just offsetting the fragment that I want to set the color on, can I work something up that writes directly into a texture?

Any help/advice?


Solution

  • As far as I understand, you need a scatter operation (uniform FBO pixel space -> random mesh UV texture destination) to be performed in OpenGL. There is a way to do this, not as simple as you may expect, and not even as fast, but I can't find a better one:

    • Run a draw call of type GL_POINTS and size equal to the width*height of your source FBO.
    • Select model texture as a destination FBO color layer, with no depth layer attached
    • In a vertex shader, compute the original screen coordinate by using gl_VertexID.
    • Sample from the source FBO texture to get color and target position (assuming your original FBO surface was a texture). Assign a proper gl_Position and pass the target color to the fragment shader.
    • In a fragment shader, just copy the color to the output.

    This will make GPU to go through each of your original FBO pixels and scatter the computed colors over the destination texture.