View Full Version : Phong shading and transformations

09-28-2012, 01:42 PM
Hello, I am starting to code with OpenGL 3.3+ and currently I am trying to implement a single per-pixel phong light to shine on my model. Sadly, it doesn't work as I want. The lighting works, but if I move the camera, lighting also changes directions and distance..

(when far away, the light is bright, almost nonchanging and lights the opposite direction, the black cube representing the light is in front)

The shaders I use(found in the anton's opengl4 wiki):


#version 330
layout (location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 vertexUV;
layout (location = 2) in vec3 vertexNormal;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;

// Output data ; will be interpolated for each fragment.
out vec2 UV;
out vec4 vpeye;
out vec4 vneye;

void main() {

vpeye = modelViewMatrix * vec4(vertexPosition, 1.0);
vneye = vec4(normalMatrix * vertexNormal, 0);
UV = vertexUV;
gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);


#version 330

in vec4 vpeye; // fragment position in eye coords
in vec4 vneye; // surface normal in eye coords
in vec2 UV; // Texture coordinates

uniform vec4 lightPosition; // light position in eye coords
uniform vec4 Ka; // ambient coefficient
uniform vec4 Kd; // diffuse coefficient
uniform vec4 Ks; // specular coefficient
uniform float Ns; // specular exponent
uniform vec4 Ld; // diffuse light colour

// Values that stay constant for the whole mesh.
uniform sampler2D myTextureSampler;

layout (location = 0) out vec4 fragmentColour;

void main() {
vec4 n_eye = normalize(vneye); // normalise just to be on the safe side
vec4 s_eye = normalize(lightPosition - vpeye); // get direction from surface fragment to light
vec4 v_eye = normalize(-vpeye); // get direction from surface fragment to camera
vec4 h_eye = normalize(v_eye + s_eye); // Blinn's half-way vector
//vec4 r_eye = reflect(-s_eye, vneye); // Phong's full reflection (could use instead of h)

vec4 Ia = vec4(0.1,0.1,0.1,1) * Ka; // ambient light has a hard-coded colour here, but we could load an La value
vec4 Id = Ld * Kd * max(dot(s_eye, n_eye), 0.0); // max() is a safety catch to make sure we never get negative colours
vec4 Is = vec4(1,1,1,1) * Ks * pow(max(dot(h_eye, v_eye), 0), Ns); // my ambient light colour is hard coded white, but could load Ls

fragmentColour = texture( myTextureSampler, UV ).rgba *(Ia + Id + Is);

I didn't change the original code, I've just added texturing. Somehow I think it's related to my modelView or normal matrix(after a long time searching for solutions on google..), I set them like this:

glm::mat4 normat=glm::inverse(glm::transpose(Model*cam->getView()));

glm::mat4 ModelView=cam->getView()*Model;

Hope you can assist me with this problem. Learning opengl3+ and having almost no shader experience is a bit exhausting..