Help end child hunger

Flatten Shader

Prev: Color Shader Next: Toon Shading

Shader programming sets us free to explore strange new effects. This is a small example just to show that with shader programming vertices can be manipulated in strange ways.

First we’re going to flatten a 3D model, by setting its z coordinate to zero prior to applying the modelview transformation. The source code for the vertex shader is:

void main(void)
	vec4 v = vec4(gl_Vertex);
	v.z = 0.0;

	gl_Position = gl_ModelViewProjectionMatrix * v;

First notice that we had to copy the gl_Vertex variable to a local variable. The gl_Vertex is an attribute variable provided by GLSL, and hence it is a read only variable as far as the vertex shader is concerned. Hence to change the values of the incoming vertex coordinates we had to copy it first to the local variable v.

The fragment shader only sets a color, so it’s basically the same as the one presented in the Hello World section.

This shader sets the z coordinate of each vertex that is processed to zero. When applied to the teapot, the result is something like the following pictures taken around the flattened teapot:



OK, let’s play some more, now we’re going to apply a sine function to the z coordinate, as a function of the x coordinate, so the teapot appears wavy.

void main(void)
	vec4 v = vec4(gl_Vertex);
	v.z = sin(5.0*v.x )*0.25;

	gl_Position = gl_ModelViewProjectionMatrix * v;

And finally to end this simple example we’re going to add some vertex animation. In order to do this we need a variable to keep track of time, or a frame counter. A vertex shader can’t keep track of values between vertices, let alone between frames. Therefore we need to define this variable in the OpenGL application, and pass it to the shader as a uniform variable. Let’s assume that there is a frame counter in the OpenGL application named “time”, and that in the shader there is an uniform attribute with the same name.

The code for the vertex shader becomes something like:

uniform float time;

void main(void)

	vec4 v = vec4(gl_Vertex);
	v.z = sin(5.0*v.x + time*0.01)*0.25;
	gl_Position = gl_ModelViewProjectionMatrix * v;


As mentioned in the Uniform Variables section, in the OpenGL application two steps are required:

  • setup: getting the location of the uniform variable
  • render: update the uniform variable

The setup phase is only:

	loc = glGetUniformLocationARB(p,"time");

Where p is the handler to the program, and “time” is the name of the uniform variable as defined in the vertex shader. The variable loc is of type GLint and should be defined in a place where it is also accessible to the render function.

The render function could be something like:

void renderScene(void) {

	glUniform1fARB(loc, time);


where the variable time is initialized to some value in the initialization, and is incremented in each frame.

The source code for this last example, together with the shaders can be obtained

in here: ARB extensions syntax or OpenGL 2.0 syntax.

Note: you’ll need to have glew to run this. A Shader Designer project is also available in here. A mpeg showing the effect can be downloaded here. This video was produced using a feature on Shader Designer that creates an AVI movie.


Prev: Color Shader Next: Toon Shading

  2 Responses to “Flatten Shader”

  1. when I build the program it flattens the Y-axis
    I played around a bit I acctually found out that the flattend axis has something to do with the teapot meaning when you take an ordinary model and flatten the z axis, the Z-axis is flattend but by doing the same thing to the teapot you flatten the Y-axis… is there a certain reason for this?

    • It depends on your teapot. It is possible that the vertical axis is the Z-axis and not the Y axis, in which case it would seem like the flattening is not occurring in the Z axis.

Leave a Reply

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

%d bloggers like this: