1
\$\begingroup\$

I have noticed that fragments rendered by the glClearColor() method do not pass through shaders. However, I'd like to modify these fragments using my fragment shader. Is there any way of forcing them through?

To clarify, I'd like to fill the background with a solid colour in such a way that causes each pixel to be treated as a fragment (and passed through the fragment shader).

One way of doing this is creating and loading an image into memory that is as large as the background. However, this seems like a horrible waste of memory.

I have tried making a VAO with a source size of one pixel and destination size of the screen dimensions but this gets treated as a single fragment.

\$\endgroup\$
2
\$\begingroup\$
One way of doing this is creating and loading an image
into memory that is as large as the background. However, 
this seems like a horrible waste of memory.

To affect the whole screen with a fragment shader you don't need a full-screen texture, just a full-screen polygon (one quad or two triangles). The four vertices would have attributes on them. At the least, you need XY coordinate (so the vertex shader knows where to put the four corners). The fragment shader could also use the XY coordinate to influence the fragment shader. (Otherwise, the fragment shader would only be able to draw a solid color, having no way to treat each fragment uniquely.)

The geometry would have XY attributes spanning (-1,-1) to (+1,+1). The vertex shader will be trivial, something like:

#version 410
in vec2 xy;
out vec2 xyVarying;
void main(void)
{
    float z = 0.0; // middle
    gl_Position = vec4(xy.x, xy.y, z, 1.0);
    xyVarying = xy;
}

And then the fragment shader can do whatever you like with the varying XY coordinate. For example:

#version 410

in vec2 xyVarying;

out vec4 fragColor;
void main (void)
{
    // map (-1,-1)(+1,+1) to red-green ramps.
    fragColor = vec4(xyVarying.x / 2.0 + 0.5,
                     xyVarying.y / 2.0 + 0.5,
                     0.0 ,1.0);
}

Hope that helps!

\$\endgroup\$
1
\$\begingroup\$

If you are just filling with a solid color then you could pass that color to the fragment shader as a uniform, and process it from there. Use a full screen quad for the fragment shader to render onto.

Another way is to this to render the background to an FBO and do the full screen quad trick but apply the FBO texture to it. This would be very memory inefficient though as you have to pass that texture to the GPU.

\$\endgroup\$
0
\$\begingroup\$

I suggest you make a skybox: A skybox is a large cube which you render around your camera which will give you the ability to pass each pixel through a fragment shader. And you can render anything onto the skybox: a color, an image, a gradient, etc.

Just be sure to call glClear(GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT);

A good tutorial on this topic is this one: http://antongerdelan.net/opengl/cubemaps.html

edit: Also make sure your skybox is bigger than your renderdistance (objects out of the box wont get rendered) but smaller than your clipping distance (box wont get rendered).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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