1

I am trying to visualize normals values frag_color = vec4(Normal, vert_color.w); by assigning value of a normal to fragment color. However, when camera moves I noticed that colors are changing and I do not understand why.

Fragment shader:

#version 330 core

in vec4 vert_color;
in vec3 Normal;
out vec4 frag_color;

void main()
{
    frag_color = vec4(Normal, vert_color.w);
}

Vertex shader:

#version 330 core

layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
out vec4 vert_color;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec4 color;

void main()
{
    vert_color = color;
    gl_Position = projection * view * model * vec4(pos.x, pos.y, pos.z, 1.0);
    Normal = normal;
}

Vertex structure:

struct Vertex
{
    glm::vec3 position;
    glm::vec3 normal;
};

Object buffer setup:

glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);

Main loop:

    glClearDepth(1.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    glm::mat4 model, view, projection;
    model = glm::translate(model, modelPos);
    view = fpsCamera->getViewMatrix();
    projection = fpsCamera->getProjectionMatrix(windowWidth, windowHeight);
    color = glm::vec4(0.310f, 0.747f, 0.185f, 1.0f);
    
    ShaderProgram shaderProgram;
    shaderProgram.loadShaders("Shaders/phantom.vert", "Shaders/phantom.frag");

    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    shaderProgram.use();
    shaderProgram.setUniform("model", model);
    shaderProgram.setUniform("view", view);
    shaderProgram.setUniform("projection", projection);
    shaderProgram.setUniform("color", color);

    
    glStencilMask(0xFF); // Write to stencil buffer
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 0, 0xFF);  // Set any stencil to 0

    glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to object ID
    m_pantomMesh->draw();
    glStencilFunc(GL_ALWAYS, 0, 0xFF);  // Set any stencil to 0        // no need fot testing

    glFlush();

enter image description here

enter image description here

Elnur
  • 119
  • 1
  • 5
  • I think you need to transform the normal vector. See this answer: https://stackoverflow.com/a/13654662/2285811 – schteppe Jul 14 '20 at 10:42
  • 1
    Based on my understanding, when you draw the normals directly as color, it is not suppose to change based on camera position or direction. Sample code is here: https://shaderfrog.com/app/view/4513 – codetiger Jul 15 '20 at 06:14
  • 1
    @codetiger , yes it is not supposed to change. That is why I do not understand what is wrong with my code.. – Elnur Jul 15 '20 at 07:38
  • One possibility is, your triangles are very small and not connected properly. If you generated the shape from a point cloud, then triangulation is not smooth. Just to verify please render the same code using a simple smooth sphere geometry. – codetiger Jul 15 '20 at 08:34
  • @codetiger , I did not use GL_POINTS, object is generated using GL_TRIANGLES. Sorry, I am beginner in opengl but as I know opengl does not have GL_SPHERE option. `glBindVertexArray(vao);glDrawArrays(GL_TRIANGLES, 0, vertices.size()); glBindVertexArray(0);` – Elnur Jul 15 '20 at 09:13
  • @Elnur, I didn't mean to use GL_SPHERE but instead of using your current human model, you can try with sphere or standard models – codetiger Jul 15 '20 at 09:37
  • Unrelated note: `vec4(pos.x, pos.y, pos.z, 1.0)` can be written as `vec4(pos, 1.0)` – user253751 Jul 16 '20 at 16:15

0 Answers0