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:
- [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 :-))
And now for the question:
- [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…
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