OpenGL VRML W3D            
  Home Tutorials Books Applications Tools Docs Models Textures  

 

              Bugs

GLSL Tutorial   

  GLSL Tutorial

Index
Introduction

The Graphics Pipeline
Pipeline Overview
Vertex Processor
Fragment Processor

OpenGL Setup for GLSL
Overview
Creating a Shader
Creating a Program
Source Code
Trouble Shooting: the InfoLog
Cleaning Up

Comm. OpenGL=> GLSL
Comm. Introduction
Uniform Variables
Attribute Variables

Shader Basics
Data Types and Variables
Statments and Functions
Varying Variables

Shader Examples
Shader Examples List

GLSL Hello World

Color Shader

Flatten Shader

Toon Shader
Toon Shader - Version I
Toon Shader - Version II
Toon Shader - Version III

Lighting
OpenGL Directional Light I
OpenGL Directional Light II
Directional Light per Pixel
Point Light Per Pixel
Spot Light Per Pixel

Simple Texture
Combine Texture + Fragment
Multitexturing

Notes
The gl_NormalMatrix
Normalization Issues


Google

OpenGLTutorials @ Lighthouse3d.com

Led Shader
View Frustum Culling
GLSL Tutorial
Maths Tutorial
Billboarding Tutorial
Picking Tutorial
Terrain Tutorial
Display Lists Tutorial
GLUT Tutorial



   
[Previous: Shader Examples List] [Next: Color Shader]

GLSL Tutorial


Hello World in GLSL


This is kind of a Hello World for GLSL. A minimal shader that performs the most basic tasks: transform the vertices and render the primitives in a single color. In here it this shaders, vertex and fragment, are presented.

 

Vertex Shader

As mentioned before, a vertex shader is responsible for transforming the vertices. In here it will be shown how to transform the vertices following the equations for the fixed functionality.

The fixed functionality states that a vertex is to be transformed by the modelview and projection matrices using the following equation:

	vTrans = projection * modelview * incomingVertex
In order to write such a statement in GLSL it is necessary to access the OpenGL state to retrieve both matrices. As mentioned before, part of the OpenGL state is accessible in GLSL, namely the above mentioned matrices. The matrices are provided through predefined uniform variables declared as:
	uniform mat4 gl_ModelViewMatrix;
	uniform mat4 gl_ProjectionMatrix;
One more thing is needed: to access the incoming vertex. These vertices are suplied, one by one, to the vertex shader through a predefined attribute variable:
	attribute vec4 gl_Vertex;
In order to output the transformed vertex, the shader must write to the also predefined variable gl_Position, declared as a vec4.

Given the above, it is now possible to write a vertex shader that will do nothing more than transform vertices. Note that all other functionality will be lost, meaning, for instance, that lighting computations will not be performed.

The vertex shader has to have a main function. The following code does the trick:


	void main()
	{	
			
		gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
	}

In the above code, the projection matrix is multiplied by the modelview matrix for every vertex, which is a clear waste of time since these matrices do not change per vertex. The matrices are uniform variables.

GLSL provides some derived matrices, namely the gl_ModelViewProjectionMatrix that is the result of multiplying the above matrices. So the vertex shader could be written as:


	void main()
	{	
			
		gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
	}

The end result is of course the same. Does this guarantee the same transformation as in the fixed functionality? Well in theory yes, but in practice the process of transforming the vertices may not follow the same order as in here. This is normally a highly optimized task in a graphic card, and a special function is provided to take advantage of that optimization. Another reason for this function is due to the limit in the precision of the float data type. When calculus is done in different orders, different results may be obtained due to this limited precision. Hence the GLSL provides a function that guarantees that not only the best performance is obtained but also that the result is always the same as when using the fixed functionality. This magical function is:

	vec4 ftransform(void);
This function returns the transformed incoming vertex, following the same steps as the fixed functionality does. The shader could then be rewritten as:
	void main()
	{	
			
		gl_Position = ftransform();
	}

 

Fragment Shader

The fragment shader also has a predefined variable to write the color of the fragment: gl_FragColor. As in the case of vertex shaders, fragment shaders must also have a main function. The following code is for a fragment shader that draws all fragments in a bluish color:


	void main()
	{
		gl_FragColor = vec4(0.4,0.4,0.8,1.0);
	}

The source code for this example can be obtained in here: ARB extensions syntax or OpenGL 2.0 syntax.

[Previous: Shader Examples List] [Next: Color Shader]

       


Site designed and maintained by António Ramires Fernandes
Your comments, suggestions and references to further material are welcome!

Lighthouse 3D privacy statement