首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >漫射照明伪影(OpenGL 4)

漫射照明伪影(OpenGL 4)
EN

Stack Overflow用户
提问于 2017-04-09 10:37:54
回答 1查看 248关注 0票数 0

在阅读了一些教程之后,我试图实现最简单的漫射照明,但不幸的是失败了。

我从Wavefront obj文件加载三维网格,如果我不应用照明,它看起来很好。但是,当我使用照明时,动物看起来就像棋盘,而立方体更混乱:

动物比较(与正常值比较)

立方体比较(与法线比较)

这里是顶点着色器:

代码语言:javascript
复制
#version 400

layout (location = 0) in vec4 a_position;
layout (location = 1) in vec3 a_texCoords;
layout (location = 2) in vec3 a_normal;

uniform mat4 u_viewProjection;
uniform mat4 u_model;

out vec3 v_fragPos;
out vec3 v_fragNormal;

void main() {
    v_fragPos = a_position.xyz;
    v_fragNormal = a_normal;
    gl_Position = u_viewProjection * a_position;
}

我将片段位置和法线传递给片段着色器,因为我没有应用任何模型转换,我只是假设模型在从文件加载之后已经有了世界坐标(忘记u_model uniform,它现在还没有使用)。

然后,碎片着色器:

代码语言:javascript
复制
#version 400

uniform vec3 u_lightPos;
uniform vec3 u_lightColor;

uniform vec3 u_diffuseColor;
uniform vec3 u_specularColor;
uniform vec3 u_ambientColor;

in vec3 v_fragPos;
in vec3 v_fragNormal;

out vec4 o_fragColor;

void main() {
    vec3 lightDir = u_lightPos - v_fragPos;    
    float cosTheta = max(dot(normalize(v_fragNormal), normalize(lightDir)), 0.0);
    vec3 diffuseContribution = cosTheta * u_lightColor;

    o_fragColor = vec4(u_diffuseColor * diffuseContribution, 1.0);
}

没有使用模型或标准矩阵,因为目前没有对模型应用旋转(或比例)。

我考虑过不正确的法线,但至少一个简单的立方体应该有正确的法线,对吗?

此外,也许我应该提到,我在MacOS下使用的是MacOS。

任何帮助都将不胜感激。谢谢!

更新:

添加VBO设置。

这是单个顶点的样子:

代码语言:javascript
复制
struct Vertex1P1N1UV {
        glm::vec4 mPosition;
        glm::vec3 mTextureCoords;
        glm::vec3 mNormal;

        Vertex1P1N1UV();
        Vertex1P1N1UV(glm::vec4 position, glm::vec3 texcoords, glm::vec3 normal);
};

我像这样初始化我的VAO

代码语言:javascript
复制
auto* VAO = new GLVertexArray<Vertex1P1N1UV>();
VAO->initialize(subMesh.vertices(), GLVertexArrayLayoutDescription({
                static_cast<int>(glm::vec4::length() * sizeof(GLfloat)),
                static_cast<int>(glm::vec3::length() * sizeof(GLfloat)),
                static_cast<int>(glm::vec3::length() * sizeof(GLfloat)) }));

VAO初始化法

代码语言:javascript
复制
void initialize(const std::vector<Vertex>& vertices, const GLVertexArrayLayoutDescription& layoutDescription) {
    bind();

    mVertexBuffer.initialize(vertices);

    GLuint offset = 0;
    for (GLuint location = 0; location < layoutDescription.getAttributeSizes().size(); location++) {
         glEnableVertexAttribArray(location);
         GLsizei attributeSize = layoutDescription.getAttributeSizes()[location];
         glVertexAttribPointer(location, attributeSize / sizeof(GLfloat), GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void *>(offset));
         offset += attributeSize;
     }
 }

缓冲区初始化方法

代码语言:javascript
复制
void initialize(const std::vector<Vertex>& data) override {
     bind();
     glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(Vertex), data.data(), GL_STATIC_DRAW);
}

在这种情况下,顶点将变成Vertex1P1N1UV

更新:

实现正常的可视化(重新上传的屏幕截图,滚动到顶部)。困扰我的是,我可以通过网格看到法线,就像它是透明的,尽管不透明的颜色。这是深度测试问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-10 17:50:47

经过两天的挣扎,我发现了这个问题。我没有在NSOpenGLView上启用深度缓冲区。这是一行代码。如果有人无意中发现了这一点,他可以在这里测试不起作用寻找一个解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43305738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档