Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the current color of a fragment?

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.

like image 353
Mason Wheeler Avatar asked Apr 29 '10 21:04

Mason Wheeler


People also ask

What is the output color of the fragment shader?

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.

What is fragment shading?

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.

What is a fragment in OpenGL?

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.

What is gl_FragColor?

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.


1 Answers

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.

like image 78
Jerry Coffin Avatar answered Oct 27 '22 06:10

Jerry Coffin