Fitzeputz
Fitzeputz

Reputation: 21

What am I doing wrong in this Phong Shader?

I've been trying for some time now to debug this simple Phong-Shader and just came up short. The diffuse part is fine but the specular is not. It doesn't move with the camera.

Here's from one side:

Here's from one side

And here from the other:

And here from the other

As far as I can see, I did convert the Position to Viewspace, but, apparently, I made another mistake of some kind.

Vertex Shader:

#version 330
#extension GL_ARB_explicit_attrib_location : enable


layout(location=0) in vec3 aPosition;
layout(location=1) in vec3 aNormal;

out vec3 vPosition;
out vec3 vNormal;

uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;

void main(void) 
{
    vPosition = vec3(uModel * vec4(aPosition,1.0f));
    vNormal =   vec3(uModel * vec4(aNormal,  0.0f));
    gl_Position = uProjection * uView * uModel * vec4(aPosition, 1.0);
}

And my Fragment Shader

#version 330

out     vec4 FragColor;

in      vec3 vPosition;
in      vec3 vNormal;

uniform mat4 uView;
uniform vec3 uColor;
uniform vec3 uLightpositions[10];
uniform vec3 uLightcolors[10];
uniform float uPhongSpecular;


void main(void)
{
    FragColor = vec4(0.4*uColor, 1.0);//Ambient Value
    for(int i = 0; i < 5; i++){
        vec3 lVec = normalize(uLightpositions[i] - vPosition);
        vec3 nVec = normalize(vNormal);
        
        float diffuse = max(dot(lVec,nVec), 0);
        FragColor += 0.5* vec4(uLightcolors[i] * diffuse,0.0f);
        
        vec3 rVec = normalize(reflect(lVec,nVec));
        vec3 vVec = -normalize(vec3(uView * vec4(vPosition,1.0)));
        
        float specular = 0;
        if(dot(rVec,vVec) < 0.0)
        {
            specular = pow(max(dot(-rVec,vVec),0),uPhongSpecular);
        }
        FragColor += 0.2*vec4(uLightcolors[i] * specular,0.0f);
    }
}

Upvotes: 0

Views: 88

Answers (2)

Alison
Alison

Reputation: 1

One thing wrong in addition to Rabbid76's answer is if(dot(rVec,vVec) < 0.0) is testing if the angle between the two is greater than 90 degrees. In other words, you are testing if the specular reflection is visible behind the model. You have to flip that from less-than to greater-than >.

Upvotes: 0

Rabbid76
Rabbid76

Reputation: 210878

The problem is dot(-rVec, vVec). vVec is a vector in view space, however, rVec is a vector in world space. Convert rVec from world space to view space:

vec3 rVec = normalize(reflect(lVec, nVec));

vec3 rVec = normalize(mat3(uView) * reflect(lVec, nVec));

Upvotes: 1

Related Questions