Hello,

i am totally new to 3D Graphics in general and OpenGL in particular and currently learning the Basics of GLSL. I want to implement a per Vertex Phong Shader with the classical ADS Lighting model.

Diffuse and Ambient works as expected but i have trouble with the Specular component.

This is my GLSL Code for the entire Shader - the part probably problematic is the Function “GetSpecularColor”:

```
//
// Vertex Shader
//
//
#version 130
uniform mat4 mModel;
uniform mat4 mView;
uniform mat4 mProjection;
uniform vec4 vEyePosition; // In Model space
uniform vec4 vDiffuseLightPosition; // In Model space
in vec4 vVertexPosition;
in vec3 vVertexNormal;
smooth out vec4 vVaryingColor;
/*
* Returns the Specular Color at the current Vertex
*/
vec4 GetSpecularColor()
{
// Transform the Vertex and corresponding Normal into Model space
vec4 vTransformedNormal = mModel * vec4( vVertexNormal, 1 );
vec4 vTransformedVertex = mModel * vVertexPosition;
// Get the directional vector to the light and to the camera
// originating from the vertex position
//
// vLightDirection is interesting. Why do i need to write it in this way?
// The direction would be vDiffuseLighePosition - vTransformedVertex, but
// if i do it in this way the result is weird....
vec4 vLightDirection = normalize( vTransformedVertex - vDiffuseLightPosition );
vec4 vCameraDirection = normalize( vEyePosition - vTransformedVertex );
// Calculate the reflection vector between the incoming light and the
// normal (incoming angle = outgoing angle)
vec4 vReflection = reflect( vLightDirection, vTransformedNormal );
// Calculate specular component
// Based on the dot product between the reflection vector and the camer
// direction
float spec = pow( max( 0.0, dot( vCameraDirection, vReflection )), 32 );
return vec4( spec, spec, spec, 1.0 );
}
/*
* Returns the Ambient Color at the current Vertex
*/
vec4 GetAmbientColor()
{
// Ambient material is 0.2/0/0
// Ambient light is 0.2/0.2/0.2
return vec4( 0.2, 0, 0, 1.0 ) * vec4( 0.2, 0.2, 0.2, 1.0 );
}
/*
* Returns the Diffuse Color at the current Vertex
*/
vec4 GetDiffuseColor()
{
// Transform the normal from Object to Model space
// we also normalize the vector just to be sure ...
vec4 vTransformedNormal = normalize( mModel * vec4( vVertexNormal, 1 ));
// Get direction of light in Model space
vec4 vLightDirection = normalize( vDiffuseLightPosition - vTransformedNormal );
// Calculate Diffuse intensity
float fDiffuseIntensity = max( 0.0, dot( vTransformedNormal, vLightDirection ));
// Calculate resulting Color
vec4 vDiffuseColor;
vDiffuseColor.xyz = vec3( 1.0, 0.0, 0.0 ) * fDiffuseIntensity;
vDiffuseColor.a = 1.0;
return vDiffuseColor;
}
void main(void)
{
vec4 ambientColor = GetAmbientColor();
vec4 diffuseColor = GetDiffuseColor();
vec4 specularColor = GetSpecularColor();
vVaryingColor = ambientColor + diffuseColor + specularColor;
gl_Position = mProjection * mView * mModel * vVertexPosition;
}
```

First of all please let me explain a few things i assumed in my code:

[ul][li]I like to keep the Model, View and Projection matrices alone[*]I also like to do the maths in model space[*]and lust but not least i like to supply “camera” and light position in model space (REALLY like to think in model space :-))[/ul][/li]

And now for the question:

[ul][li]Is my specular lighting correct? I don’t think so, because even if it looks kind of correct in the graphical output it’s not clear to my why.[*] Take a look at the Function “GetSpecularColor” and the declaration of vLightDirection - if i write it exactly the opposite way (which would yield the direction) the specular lighting is totally screwed…[/ul][/li]

If you want to try out for yourself, heres the entire code for the test project:

http://hotfile.com/dl/111334776/b34b17d/gltest011.tar.bz2.html

Here’s the graphical output of my test project:

Thank you,

Tom