4. GLSL Lighting
Ok, so we can create a shader program, and render a shape with a specified color. Lets move into lighting. In this tutorial, I am going to show you how to perform per vertex lighting, which is then easily modified to achieve per pixel lighting in the next tutorial.
Lets get moving 🙂
There are going to be quite a few additions to this code, but you might recognise most of it from the lighting tutorials.
I am creating a directional light, that points in the direction [0,1,1]. It has a diffuse color of white, and an ambient color of black.
I have placed the calls to setup my lighting inside of a new method, which is called during our display method, *after* we set the camera position. I have a tip on the OpenGL Tips page, that explains why we do this.
Another minor change, is that I am now using a glutSolidSphere, I have kept it to a low polygon count, only 10 stacks and 10 slices. This is to show how per vertex will differ to per pixel lighting later on.
But enough of that, lets move onto our shaders. You should already know how to setup lighting in a standard OpenGL application.
Vertex Shader Source:
For this tutorial, I am going show you how to perform per
First I am going to teach you about varying variables. These
Because we are using per vertex lighting, the GLSL shader will
Now first off we need to know the surface normal of the current
Now as for our normal, I am storing it in the variable vec3 vertex_normal.
vec3 vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
Next on, we are going to work with our light. I am storing this
vec3 vertex_light_position = gl_LightSource.position.xyz;
This gives us the position of glLight0, and to get the position of
Now that we have our vertex_normal and the position of our vertex_light_position.
diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0);
And from that, we have now calculated the intensity of the light
Fragment Shader Source:
Because we are using the varying float Diffuse in
varying float diffuse_value;
After that, because I am building on the last tutorial, we will multiply
gl_FragColor = gl_Color * diffuse_value;
Once you get this running, it should show a sphere that gets darker down the bottom, or if you add a camera, it will be dark behind as well. Which you can see in the image at the top of the page.
If you have any questions, please email me at firstname.lastname@example.org
Download shader.h Source Code for this Tutorial
Download shader.cpp Source Code for this Tutorial
Download main.cpp Source Code for this Tutorial
Download shader.vert Source Code for this Tutorial
Thank you very much for your nice tutorials, but why are most of them formatted with a centered text-alignment? This makes them really unreadable, especially the code sections!
Hey, great tutorials on your site 🙂
Just one suggestion, it would be great if you provided screenshots of what the final output will look like in some of these tutorials.
Keep up the good work
Oh i just noticed you mention images in the tutorial but they’re not showing 🙂
In a lot of the older tutorials (GLSL included) I originally had an image per tutorial but they have gone walkabout over the years through several site transitions.
If I ever get the chance to come back and put a lot of effort into the site, I would love to put updated images back.
The dot product shouldn’t be between the vertex normal and the vector from vertex coords and light pos?
Isn’t the light pos in the dot product doing the light relative to the origin position 0,0,0 ?
This didn’t work for me. I ended up having to mix some of your code with most of http://nehe.gamedev.net/data/articles/article.asp?article=21
Could you give an example of what you had to change? I haven’t had any other reported problems?