首页 > 解决方案 > 3D模型上的光虫

问题描述

我有下面这张显示 3D 模型的图片,并且光线与我预期的不一样,我已经尝试了很多方法,但我不知道如何修复它。我的法线向量很好

立方体

几何学:

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

        /* GENERATE THE BUFFERS */
        glGenBuffers(1, &bufferArray);

        /* SELECT THAT BUFFER TO WORK WITH */
        glBindBuffer(GL_ARRAY_BUFFER, bufferArray);
        glBufferData(GL_ARRAY_BUFFER, myMeshes.at(j).realPositions.size() * sizeof(float), (GLfloat*)RealPos, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
glGenBuffers(1, &normalArray);
        glBindBuffer(GL_ARRAY_BUFFER, normalArray);
        glBufferData(GL_ARRAY_BUFFER, myMeshes.at(j).realNormals.size()*sizeof(float), (GLfloat*)RealNor, GL_STATIC_DRAW);
        glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(3);

这是我的代码:

while (!glfwWindowShouldClose(window))
    {

        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glm::mat4 view = glm::mat4(1.0f); 
        glm::mat4 projection = glm::mat4(1.0f);
        projection = glm::perspective(glm::radians(45.0f), (float)width / (float)heigh, 0.1f, 100.0f);

        view = glm::translate(view, glm::vec3(0.0f, 0.0f, transZ)); //this is for scroll mouse
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -2.0f));
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -5.0f));
                
        glUseProgram(programT);
        int lightColorLoc = glGetUniformLocation(programT, "lightColor");
        glUniformMatrix4fv(lightColorLoc, 1, GL_FALSE, glm::value_ptr(glm::vec3(1.0f, 0.0f, 0.0f)));

        int objectColorLoc = glGetUniformLocation(programT, "objectColor");
        glUniformMatrix4fv(objectColorLoc, 1, GL_FALSE, glm::value_ptr(glm::vec3(1.0f, 0.5f, 0.31f)));

        glm::vec3 lightPos(2.0f, 4.0f, 5.0f);
        int lightPosLoc = glGetUniformLocation(programT, "lightPos");
        glUniformMatrix4fv(lightPosLoc, 1, GL_FALSE, glm::value_ptr(lightPos));

        int projectionLocLight = glGetUniformLocation(programT, "projection");
            glUniformMatrix4fv(projectionLocLight, 1, GL_FALSE, glm::value_ptr(projection));
        glm::mat4 modelLight = glm::mat4(1.0f);
        int modelLocLight = glGetUniformLocation(programT, "model");
        glUniformMatrix4fv(modelLocLight, 1, GL_FALSE, glm::value_ptr(modelLight));

        glm::mat4 viewLight = glm::mat4(1.0f); 
        int viewLocLight = glGetUniformLocation(programT, "view");
        glUniformMatrix4fv(viewLocLight, 1, GL_FALSE, glm::value_ptr(viewLight));

        int viewLoc = glGetUniformLocation(programT, "view");
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));

        int projectionLoc = glGetUniformLocation(programT, "projection");
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));

        model = glm::rotate(model, glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f));
        model = glm::rotate(model, glm::radians(rotY), glm::vec3(.0f, 1.0f, .0f));
        model = glm::rotate(model, glm::radians(rotZ), glm::vec3(.0f, 0.0f, 1.0f));
        int modelLoc = glGetUniformLocation(programT, "model");
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

                 

        glGenerateMipmap(GL_TEXTURE_2D);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureArray[0]);
        glUniform1i(glGetUniformLocation(programT, "ourTexture"), 0);
            


            glBindVertexArray(VAOArray[0]);
        glDrawArrays(GL_TRIANGLES, 0, myMeshes.at(0).Indices.size());
    

        
        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
        glfwSetKeyCallback(window, key_callback);
        glfwSetScrollCallback(window, scroll_callback);
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
        
    }

用于此项目的顶点着色器:

#version 330 core


layout (location = 0) in vec3 RealPos;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec2 vertex_textcoord;
layout (location = 3) in vec3 RealNor;


out vec3 vs_pos;
out vec3 vs_color;
out vec2 vs_text;
out vec3 normal;
out vec3 FragPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    vs_pos = RealPos;
    vs_color = vertex_color;
    vs_text=vertex_textcoord;
    
    FragPos = vec3(model * vec4(vs_pos, 1.0));
    mat3 normalMat = mat3(inverse(transpose(model)));
    normal = RealNor * normalMat;
    gl_Position = projection * view * model * vec4(vs_pos, 1.0);
}

使用的片段着色器:

#version 330 core

in vec2 vs_text;
in vec3 normal;

in vec3 FragPos;

uniform vec3 lightPos;
out vec4 gl_FragColor;



uniform vec3 objectColor;
uniform vec3 lightColor;


uniform sampler2D ourTexture;



void main()
{
    vec3 norm = normalize(normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;
    float diff = max(abs(dot(norm, lightDir)), 0.0);
    vec3 diffuse = diff * lightColor;
    vec3 result = (ambient + diffuse) * objectColor;
    gl_FragColor =  texture(ourTexture, vs_text) * diff;
}

有人可以帮我解决这个问题,或者指导我解决它吗?

谢谢

标签: c++opengllighting

解决方案


它适用于矩阵 * 向量 == 向量 * (matrix)^T

您正在通过计算法线normal = RealNor * normalMat;

这不等于normalMat * RealNor导致错误的法线。因此,将表达式转换为normalMat * RealNor并查看它是否解决了问题。


推荐阅读