Help end child hunger

Color Shader

 
Prev: Hello World in GLSL Next: Flatten Shader
 

GLSL has access to part of the OpenGL state. In this tutorial we’ll see how to access the color as set in an OpenGL application with glColor.

GLSL has an attribute variable where it keeps track of the current color. It also provides varying variables to get the color from the vertex shader to the fragment shader

	attribute vec4 gl_Color;

	varying vec4 gl_FrontColor; // writable on the vertex shader
	varying vec4 gl_BackColor; // writable on the vertex shader

	varying vec4 gl_Color; // readable on the fragment shader

The idea is as follows:

  1. The OpenGL applications sends a color using the glColor function
  2. The vertex shader receives the color value in the attribute gl_Color
  3. The vertex shader computes the front face and back face colors, and stores them in gl_FrontColor, and gl_BackColor respectively
  4. The fragment shader receives an interpolated color in the varying variable gl_Color, depending on the orientation of the current primitive, i.e. the interpolation is done using either the gl_FrontColor or the gl_BackColor values.
  5. The fragment shader sets gl_FragColor based on the value of gl_Color

This is an exception to the “rule” where a varying variable should be declared with the same name both in the vertex shader and the fragment shader. The concept in here is that we have two variables in the vertex shader, namely gl_FrontColor and gl_BackColor, and these are used to derive automatically the value of gl_Color depending in the orientation of the current face. Note that there is no conflict between the attribute gl_Color and the varying variable gl_Color, since the former is visible only in the vertex shader, and the latter in the fragment shader.

Enough talk, the code for the vertex shader, where only the front face color is computed is:

void main()
{
	gl_FrontColor = gl_Color;
	gl_Position = ftransform();
}

The fragment shader is also a very simple shader:

void main()
{
	gl_FragColor = gl_Color;
}

Source code based on GLUT and GLEW is available in here: ARB extensions syntax or OpenGL 2.0 syntax.

 

Prev: Hello World in GLSL Next: Flatten Shader
 

  4 Responses to “Color Shader”

  1. Hello!
    I’m kind of new to GLSL and I was wondering how are pixels/fragments traversed in the fragment shader?
    Is it possible to make a fragment shader that takes the current value of a variable, subtracts it’s color from it and then sets it to the gl_FragColor?
    Something like this:
    uniform sampler2d image;
    vec4 temp;
    void main()
    {
    if(uv.x == 0.0)
    {tmpcolor = vec3 (0,0)}
    if (tmpcolor.rbg == vec3 (0.0))
    {
    gl_FragColor = vec4 (1.0,1.0,1.0,1.0);
    }
    else
    {
    tmpcolor = tmpcolor + texture2D(image,vec2(uv.x,1.0-uv.y)).rgb;
    gl_FragColor = vec4 (1.0-tmpcolor,1.0);
    }
    }

  2. Would you give me a simple example of using gl_BackColor ?
    I understand the difference against gl_FrontColor conceptually,
    but I am curious what would be examples of using that.
    Thx.

    • 1) Set in vertex shader:
      gl_FrontColor = vec4(1,0,0,1); // red
      gl_BackColor = vec4(0,1,0,1); // green
      2) in the renderScene, draw a plane instead of teapot, and rotate it just by Y:
      glRotatef(a,0,1,0);
      glBegin(GL_QUADS);
      glVertex3f(1,1,0);
      glVertex3f(1,-1,0);
      glVertex3f(-1,-1,0);
      glVertex3f(-1,1,0);
      glEnd();
      3) DISABLE – or not enable, the Backface culling. That is, in the main method, comment the line: glEnable(GL_CULL_FACE);
      4) add after the commented line:
      glEnable(GL_VERTEX_PROGRAM_TWO_SIDE_ARB);

      That is 🙂 You’ll have a plane with 1 part red the other one green.

      • That’s good!
        But for being able to see both faces you should rotate around X and Y axis, for example, say
        glRotate(a, 1, 1, 0).

Leave a Reply to Sam Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: