I'm trying to wrap my head around shaders in GLSL, and I've found some useful resources and tutorials, but I keep running into a wall for something that ought to be fundamental and trivial: how does my fragment shader retrieve the color of the current fragment?
You set the final color by saying gl_FragColor = whatever
, but apparently that's an output-only value. How do you get the original color of the input so you can perform calculations on it? That's got to be in a variable somewhere, but if anyone out there knows its name, they don't seem to have recorded it in any tutorial or documentation that I've run across so far, and it's driving me up the wall.
The new maximum fragment color output is GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, which is 1 on every piece of hardware that supports this feature. In short: if you want dual-source blending, you can only write to one buffer from the fragment shader.
A fragment shader is the same as pixel shader. One main difference is that a vertex shader can manipulate the attributes of vertices. which are the corner points of your polygons. The fragment shader on the other hand takes care of how the pixels between the vertices look.
From OpenGL Wiki. A Fragment is a collection of values produced by the Rasterizer. Each fragment represents a sample-sized segment of a rasterized Primitive.
gl_FragColor is the principal variable that your fragment shader is designed to change. If your code does not assign a value to it then it is left undefined for the rest of the pipeline. gl_FragData is an array of data that can be used by the rest of the pipeline.
The fragment shader receives gl_Color
and gl_SecondaryColor
as vertex attributes. It also gets four varying variables: gl_FrontColor
, gl_FrontSecondaryColor
, gl_BackColor
, and gl_BackSecondaryColor
that it can write values to. If you want to pass the original colors straight through, you'd do something like:
gl_FrontColor = gl_Color; gl_FrontSecondaryColor = gl_SecondaryColor; gl_BackColor = gl_Color; gl_BackSecondaryColor = gl_SecondaryColor;
Fixed functionality in the pipeline following the vertex shader will then clamp these to the range [0..1], and figure out whether the vertex is front-facing or back-facing. It will then interpolate the chosen (front or back) color like usual. The fragment shader will then receive the chosen, clamped, interpolated colors as gl_Color
and gl_SecondaryColor
.
For example, if you drew the standard "death triangle" like:
glBegin(GL_TRIANGLES); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 0.0f, -1.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, 0.0f, -1.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3d(0.0, -1.0, -1.0); glEnd();
Then a vertex shader like this:
void main(void) { gl_Position = ftransform(); gl_FrontColor = gl_Color; }
with a fragment shader like this:
void main() { gl_FragColor = gl_Color; }
will transmit the colors through, just like if you were using the fixed-functionality pipeline.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With