3
\$\begingroup\$

I'm writing a simple 3D renderer and while the model loads fine, the colors are off. Quite a few fragments in the model show no color at all.

Here is the render: enter image description here

The locations of the blacked out fragments change everytime I move my camera. From another angle:

enter image description here

Vertex shader:

#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 uvCoords;

out vec2 texCoords;
out vec3 normCoords;
out vec3 fragmentPos;

uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 modelMatrix; // Just an identity matrix for now

void main()
{
    normCoords = normal;
    fragmentPos = pos;

    texCoords = uvCoords;    

     gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(pos, 1.0);
}

Fragment shader:

#version 330 core

out vec4 frag_color;

in vec2 texCoords;
in vec3 normCoords;
in vec3 fragmentPos;

struct Light
{
    vec3 lightPos;
    vec3 lightColor;
};

uniform Light light;
uniform vec3 modelColor;

bool checkInf(in vec3 vect)
{
    return (isinf(vect.x) || isinf(vect.y) || isinf(vect.z));
}

bool checkNan(in vec3 vect)
{
    return (isnan(vect.x) || isnan(vect.y) || isnan(vect.z));
}

void main()
{    
    float ambientValue = 0.05;
    vec3 ambientColor = ambientValue * light.lightColor;

    vec3 result;
    vec3 normalizedNormal = normalize(normCoords);
    vec3 lightDir = normalize(light.lightPos - fragmentPos);

    if(checkInf(normalizedNormal) || checkInf(lightDir) || checkNan(normalizedNormal) || checkNan(lightDir))
        result = vec3(0.5,0.5,0.5);

    else
    {
        float diffuseValue = max(dot(normalizedNormal, lightDir), 0.0);
        vec3 diffuseColor = diffuseValue * light.lightColor;

        result = (diffuseColor + ambientColor) * modelColor;
    }
    frag_color = vec4(result, 1.0);
}

After some playing around, I realized that the blacked out fragments were due to the diffuse lighting calculations. After some searching on the internet, I found this answer: answer that suggested it may be caused by normalized vector being Nan or infinity. To test that, I decided to check each normalized vector to see if it was Nan or infinity and if it was, set it to a grey color. But that didn't work.

Any help would be appreciated.

\$\endgroup\$
  • 1
    \$\begingroup\$ Looks to me like backfacing triangles, and if it's flickering when you move then I'd suspect that you're drawing each tri as both a front and a back, and you're getting z-fighting \$\endgroup\$ – A C Jun 29 at 2:36
  • 2
    \$\begingroup\$ This is definitely Z-Buffer problem, artifacts seem to resolve at a distance closer to the viewer, where precision is supposed to be higher. \$\endgroup\$ – Ocelot Jun 29 at 3:39
  • \$\begingroup\$ @Ocelot that was the problem! Thank you. I solved it by increasing the distance of the near plane from 0.0001 to 0.1. You should put it as an answer so I could mark this question solved. \$\endgroup\$ – Rish Jun 29 at 8:36
2
\$\begingroup\$

This is definitely Z-Buffer problem, artifacts seem to resolve at a distance closer to the viewer, where precision is supposed to be higher.

It is worth knowing, that exactly this problem has been covered on the OpenGL wiki:

As the zNear clipping plane is set increasingly closer to 0.0, the effective precision of the depth buffer decreases dramatically.

\$\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.