dr4cula

08-13-2013, 09:04 AM

Hello,

I recently started looking into using GLSL and now I've run into a bit of a problem while trying to implement per-vertex lighting. I've tried working out the maths on pen and paper, have compared my code to numerous sources online yet I can't find out where I've gone wrong. Ambient and diffuse lighting are working fine (if I set either to 0, the shading changes). However, specular lighting is behaving oddly: I can't say it's not working at all... I think it's better if I post full shader codes first and then explain what I've found.

vertex shader:

#version 400

layout (location = 0) in vec3 vertexPosition_;

layout (location = 2) in vec3 vertexNormal_;

out vec3 lightIntensity_;

uniform MainMatrices {

mat4 projectionMatrix_;

mat4 modelviewMatrix_;

mat3 normalMatrix_;

};

uniform LightProperties {

// position of the light source in eye coordinates

vec4 lightPosition_;

// ambient light intensity

vec3 La_;

// diffuse light intensity

vec3 Ld_;

// specular light intensity

vec3 Ls_;

};

uniform MaterialProperties {

// ambient reflectivity

vec3 Ka_;

// diffuse reflectivity

vec3 Kd_;

// specular reflectivity

vec3 Ks_;

// shininess factor (usually [1,200])

float shininess_;

};

vec3 calculatePhongShading(in vec4 coordEye, in vec3 normal) {

// find the light's position w.r.t. the vertex position

vec3 relPos = normalize(vec3(lightPosition_ - coordEye));

// find the reflected vector

vec3 ref = reflect(-relPos, normal);

// find the "reverse" vertex direction vector (origin for eye coordinates at camera's position)

// "reverse" needed due to the direction of the reflected vector being opposite to the eye coordinate w.r.t. normal

vec3 vertDir = normalize(-coordEye.xyz);

// find the ambient component

vec3 ambient = La_ * Ka_;

// find the dot product in advance between relPos and normal

// saves having to recalculate it in order to check if specular component exists

float relPosDotNormal = max(dot(relPos, normal), 0.0);

// find the diffuse component

vec3 diffuse = Ld_ * Kd_ * relPosDotNormal;

// define the specular component

vec3 specular = vec3(0.0);

// see if there's any point in finding specular component

if(relPosDotNormal > 0.0) {

specular = Ls_ * Ks_ * pow(max(dot(ref, vertDir), 0.0), shininess_);

}

// final shading = ambient + diffuse + specular

return (ambient + diffuse + specular);

}

void main() {

// find the the vertex coordinate and the normal in eye-space coordinates

vec4 coordEye = (modelviewMatrix_ * vec4(vertexPosition_, 1.0));

vec3 normal = normalize(normalMatrix_ * vertexNormal_);

lightIntensity_ = calculatePhongShading(coordEye, normal);

// find the final vertex position

gl_Position = projectionMatrix_ * modelviewMatrix_ * vec4(vertexPosition_, 1.0);

}

fragment shader:

#version 400

in vec3 lightIntensity_;

layout (location = 0) out vec4 fragColor_;

void main() {

fragColor_ = vec4(lightIntensity_, 1.0);

}

That code produces the following result: http://i39.tinypic.com/snotgi.png

I've figured out that the application does get to specular calculation line by altering the following line:

// see if there's any point in finding specular component

if(relPosDotNormal > 0.0) {

specular = Ls_ * Ks_ * pow(max(dot(ref, vertDir), 1.0), shininess_);

}

This produces the following: http://i39.tinypic.com/2pt8h2x.png

I can deduce from this that my code identifies where it should apply specular highlighting but it's not actually capable of doing it. Ls_ and Ks_ are vec3(1.0, 1.0, 1.0) and shininess_ = 100.

I've been going through the same code over and over again and I can't find where I'm going wrong. Any help appreciated.

Thanks in advance!

I recently started looking into using GLSL and now I've run into a bit of a problem while trying to implement per-vertex lighting. I've tried working out the maths on pen and paper, have compared my code to numerous sources online yet I can't find out where I've gone wrong. Ambient and diffuse lighting are working fine (if I set either to 0, the shading changes). However, specular lighting is behaving oddly: I can't say it's not working at all... I think it's better if I post full shader codes first and then explain what I've found.

vertex shader:

#version 400

layout (location = 0) in vec3 vertexPosition_;

layout (location = 2) in vec3 vertexNormal_;

out vec3 lightIntensity_;

uniform MainMatrices {

mat4 projectionMatrix_;

mat4 modelviewMatrix_;

mat3 normalMatrix_;

};

uniform LightProperties {

// position of the light source in eye coordinates

vec4 lightPosition_;

// ambient light intensity

vec3 La_;

// diffuse light intensity

vec3 Ld_;

// specular light intensity

vec3 Ls_;

};

uniform MaterialProperties {

// ambient reflectivity

vec3 Ka_;

// diffuse reflectivity

vec3 Kd_;

// specular reflectivity

vec3 Ks_;

// shininess factor (usually [1,200])

float shininess_;

};

vec3 calculatePhongShading(in vec4 coordEye, in vec3 normal) {

// find the light's position w.r.t. the vertex position

vec3 relPos = normalize(vec3(lightPosition_ - coordEye));

// find the reflected vector

vec3 ref = reflect(-relPos, normal);

// find the "reverse" vertex direction vector (origin for eye coordinates at camera's position)

// "reverse" needed due to the direction of the reflected vector being opposite to the eye coordinate w.r.t. normal

vec3 vertDir = normalize(-coordEye.xyz);

// find the ambient component

vec3 ambient = La_ * Ka_;

// find the dot product in advance between relPos and normal

// saves having to recalculate it in order to check if specular component exists

float relPosDotNormal = max(dot(relPos, normal), 0.0);

// find the diffuse component

vec3 diffuse = Ld_ * Kd_ * relPosDotNormal;

// define the specular component

vec3 specular = vec3(0.0);

// see if there's any point in finding specular component

if(relPosDotNormal > 0.0) {

specular = Ls_ * Ks_ * pow(max(dot(ref, vertDir), 0.0), shininess_);

}

// final shading = ambient + diffuse + specular

return (ambient + diffuse + specular);

}

void main() {

// find the the vertex coordinate and the normal in eye-space coordinates

vec4 coordEye = (modelviewMatrix_ * vec4(vertexPosition_, 1.0));

vec3 normal = normalize(normalMatrix_ * vertexNormal_);

lightIntensity_ = calculatePhongShading(coordEye, normal);

// find the final vertex position

gl_Position = projectionMatrix_ * modelviewMatrix_ * vec4(vertexPosition_, 1.0);

}

fragment shader:

#version 400

in vec3 lightIntensity_;

layout (location = 0) out vec4 fragColor_;

void main() {

fragColor_ = vec4(lightIntensity_, 1.0);

}

That code produces the following result: http://i39.tinypic.com/snotgi.png

I've figured out that the application does get to specular calculation line by altering the following line:

// see if there's any point in finding specular component

if(relPosDotNormal > 0.0) {

specular = Ls_ * Ks_ * pow(max(dot(ref, vertDir), 1.0), shininess_);

}

This produces the following: http://i39.tinypic.com/2pt8h2x.png

I can deduce from this that my code identifies where it should apply specular highlighting but it's not actually capable of doing it. Ls_ and Ks_ are vec3(1.0, 1.0, 1.0) and shininess_ = 100.

I've been going through the same code over and over again and I can't find where I'm going wrong. Any help appreciated.

Thanks in advance!