1
\$\begingroup\$

I am following a tutorial for 3D game development in Java, using LWJGL. I have completed all chapters up to chapter 14 - Terrain, inclusive. The tutorial is in Java, but I'm using Scala. My full code is here.

After completing chapter 14, I'm trying to render a few cubes, but the lighting comes out unexpected.

Having diffuse, texture and specular lighting, I expect the cube to be lit on the areas pointing to the light and be (relatively) dark on the sides that are facing away from the light.

Instead, the cube gets lit in a very weird way, with some lit areas and some dark areas, in a way that doesn't look like the lighting is working.

The cube is rendered at (0,0,0). Light position is different for each picture.

EDIT: I found that I was using the wrong cube mode. I fixed that and uploaded new pictures.

This is what the cube looks like from the bottom, camera at ~(0,-30,15), light at (100, 200, -100): enter image description here

This is how it looks from the front, camera at ~(0,5,10). Here with the light at (0,20,0): enter image description here

And here with the dragon, which has perfect lighting. Camera at ~(0,5,-30), light at (100, 200, -100): enter image description here

Here are my shaders and object file:

vertex-shader:

#version 400 core

in vec3 position;
in vec2 textureCoords;
in vec3 normal;

out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;


void main(void) {
    vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
    gl_Position = projectionMatrix * viewMatrix * worldPosition;
    pass_textureCoords = textureCoords;

    surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
    toLightVector = lightPosition - worldPosition.xyz;
    toCameraVector = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;
}

fragment-shader:

#version 400 core

in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;

out vec4 out_Colour;

uniform sampler2D textureSampler;
uniform vec3 lightColour;
uniform float shineDamper;
uniform float reflectivity;


void main(void) {
    vec3 unitNormal = normalize(surfaceNormal);
    vec3 unitLightVector = normalize(toLightVector);

    float nDot1 = dot(unitNormal, unitLightVector);
    float brightness = max(nDot1, 0.2);
    vec3 diffuse = brightness * lightColour;

    vec3 unitVectorToCamera = normalize(toCameraVector);
    vec3 lightDirection = -unitLightVector;
    vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);

    float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
    specularFactor = max(specularFactor, 0.0);
    float dampedFactor = pow(specularFactor, shineDamper);
    vec3  finalSpecular = dampedFactor * reflectivity * lightColour;

    out_Colour = vec4(diffuse, 1.0) * texture(textureSampler, pass_textureCoords) + vec4(finalSpecular,1.0);
    //out_Colour = vec4(diffuse, 1.0) * texture(textureSampler, pass_textureCoords) ;
}

cube2.obj:

# Blender v2.79 (sub 0) OBJ File: 'cube.blend'
# www.blender.org
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -0.000000 1.000000 0.000000
v 1.000000 0.897903 -0.901142
v 1.000000 -0.000853 -0.000852
v -0.000000 0.000000 1.000000
v -1.000000 0.000000 -0.000000
v 0.000000 -1.000000 -0.000000
v 0.000000 -0.000000 -1.000000
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.161046 0.161046
vt 0.838954 0.161046
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.838954 0.838954
vt 0.838954 0.838954
vt 0.161046 0.161046
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.838954 0.161046
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.161046 0.838954
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.161046 0.161046
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.838954 0.838954
vt 0.161046 0.161046
vt 0.838954 0.838954
vt 0.838954 0.838954
vt 0.161046 0.838954
vt 0.838954 0.838954
vt 0.161046 0.838954
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
s off
f 1/1/1 14/2/1 4/3/1
f 5/4/2 8/5/2 9/6/2
f 1/1/3 10/7/3 11/8/3
f 2/9/4 6/10/4 12/11/4
f 3/12/5 7/13/5 13/14/5
f 5/4/6 15/15/6 8/16/6
f 6/17/2 9/18/2 7/19/2
f 7/20/2 9/18/2 8/16/2
f 9/21/2 6/10/2 5/22/2
f 2/9/3 11/23/3 6/24/3
f 6/17/3 10/7/3 5/25/3
f 11/26/3 2/27/3 1/28/3
f 3/12/4 12/29/4 7/19/4
f 7/20/4 12/29/4 6/24/4
f 12/30/4 3/31/4 2/32/4
f 8/33/5 4/34/5 13/14/5
f 13/35/5 4/34/5 3/36/5
f 13/35/5 7/13/5 8/16/5
f 4/37/1 14/2/1 3/36/1
f 14/38/1 1/39/1 2/32/1
f 3/12/1 14/2/1 2/32/1
f 8/33/6 15/15/6 4/3/6
f 4/37/6 15/15/6 1/28/6
f 15/40/6 5/41/6 1/28/6
f 1/1/3 5/41/3 10/7/3
f 6/17/3 11/23/3 10/7/3
\$\endgroup\$
  • 1
    \$\begingroup\$ Try disabling specular for a short time, that usually causes problems with the wrong values \$\endgroup\$ – Bálint May 31 '18 at 7:38
  • \$\begingroup\$ When linking the tutorials, please be specific. The link you gave goes to the first lesson, which doesn't appear to have much in common with the code you posted. \$\endgroup\$ – Pikalek May 31 '18 at 13:58
  • \$\begingroup\$ @Bálint I don't understand... :/ \$\endgroup\$ – summerbulb May 31 '18 at 14:32
  • \$\begingroup\$ @summerbulb you have several vertex normals with -0.0 coords; what happens if you manually change them to 0.0? \$\endgroup\$ – Pikalek May 31 '18 at 18:56
  • \$\begingroup\$ @Pikalek Tried that. Nothing happens. \$\endgroup\$ – summerbulb May 31 '18 at 19:01
1
\$\begingroup\$

I don't see anything wrong with the vertex or fragment shader. But since the dragon is beeing lit properly and the cube isn't I was wondering could it be that you don't duplicate your vertices properly between the OBJ and and the data sent to your GPU.

For openGL one vertex can have only one normal, and one UV coordinate, but the OBJ can have as many normals linked to a vertex has possible. In this case I can see that the first vertex is both linked to VN 1 and VN 3. If you didn't make sure to create a new vertex so each one has one normal it will cause this kind of weird issue.

The reason the dragon renders just fine would be that one vertex has one normal which give it this smooth aspect. I cannot be sure since I don't have the wavefront loading code. But to be sure check the data you send to the GPU and make sure it is coherent.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.