Diffuse lighting working per-vertex but not per-pixel

Hello!

I’m writing an app for Android which currently consists of nothing more than a rotating untextured rock. I’ve implemented a per-vertex diffuse ligthing shader, but when I try to convert it to a per-pixel/per-fragment shader something goes awry.

First of all, let’s start with my working per-vertex shader:

#version 300 es
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform vec3 lightPosition;
uniform vec4 vertexColor;

in vec4 vertexPosition;
in vec3 vertexNormal;

out vec4 finalColor;

void main()
{
    vec3 cameraSpaceVertex = vec3(mvMatrix * vec4(vertexPosition.xyz, 1.0));
    vec3 cameraSpaceNormal = vec3(mvMatrix * vec4(vertexNormal, 0.0));

    float distance = length(lightPosition - cameraSpaceVertex);
    vec3 lightVector = normalize(lightPosition - cameraSpaceVertex);

    float cosTheta = clamp(dot(cameraSpaceNormal, lightVector), 0.0, 1.0);

    float lightPower = 60.0;
    float ambientLighting = 0.1;

    finalColor = ambientLighting + vec4((lightPower * cosTheta / (distance * distance)) * vertexColor.rgb, 1.0);

    gl_Position = mvpMatrix * vec4(vertexPosition.xyz, 1.0);
}
#version 300 es
precision mediump float;

in vec4 finalColor;
out vec4 FragColor;

void main()
{
    FragColor = finalColor;
}

Next up is my per-pixel diffuse lighting shader:

#version 300 es
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;

in vec3 vertexPosition;
in vec4 vertexColor;
in vec3 vertexNormal;

out vec3 fragPosition;
out vec4 fragColor;
out vec3 fragNormal;

void main()
{
    fragPosition = vec3(mvMatrix * vec4(vertexPosition, 1.0));
    fragColor = vertexColor;
    fragNormal = vec3(mvMatrix * vec4(vertexNormal, 0.0));

    gl_Position = mvpMatrix * vec4(vertexPosition, 1.0);
}
#version 300 es
precision mediump float;

uniform vec3 lightPosition; // position of the light in camera space

in vec3 fragPosition;
in vec4 fragColor;
in vec3 fragNormal;

out vec4 finalColor;

void main()
{
    float distance = length(lightPosition - fragPosition);
    vec3 lightVector = normalize(lightPosition - fragPosition); // Calculate the light vector (pointing towards the light)

    float cosTheta = clamp(dot(fragNormal, lightVector), 0.0, 1.0); // Calculate the dot product between the normal and the light vector

    float lightPower = 60.0;
    float ambientLighting = 0.1;

    finalColor = ambientLighting + vec4((lightPower * cosTheta / (distance * distance)) * fragColor.rgb, 1.0);
    //finalColor = vec4(abs(lightVector.xyz), 1.0);
}

The per-vertex code is working as expected. Here’s an example: https://i.imgur.com/2elCcDm.png
However, when I try to implement the same diffuse lighting per-pixel instead, the diffuse lighting is gone. The rock is lit up by the ambient lighting, but the diffuse light is nowhere to be seen. Here’s an example: https://i.imgur.com/3vtzYVi.png

What am I doing wrong? I’m using the exact same attributes when calling both of my implementations. I’ve spent 12 hours trying to find a solution, but I can’t think of anything any longer.

EDIT:
I just figured out that I can pass the color (the same throughout the entire object) to the fragment shader as a uniform instead of as an “in” to the vertex shader. When it was passed from the vertex shader to the fragment shader it somehow got changed into black. I suppose this doesn’t really allow interpolation, but every vertex of the same model shares color in my app anyway.

Anyhow, I’d be grateful if someone could explain to me why I can’t pass the color to the vertex shader as an “in” instead of passing it directly to the fragment shader as an uniform.

Well, I see one thing right off the bat. You didn’t renormalize your per-fragment normal in the fragment shader.

My bad. I’ve been editing the code back and forth, forgot to put that back in there. Still made no difference though.

EDIT:
I’ll be damned! I managed to get it to work, see the OP for info.

[QUOTE=WizardOfUs;1280098]
Anyhow, I’d be grateful if someone could explain to me why I can’t pass the color to the vertex shader as an “in” instead of passing it directly to the fragment shader as an uniform.[/QUOTE]
Given that there doesn’t appear to be anything wrong with the GLSL code, I’d check for errors related to the vertexColor attribute in the client code.