在阅读了一些教程之后,我试图实现最简单的漫射照明,但不幸的是失败了。
我从Wavefront obj文件加载三维网格,如果我不应用照明,它看起来很好。但是,当我使用照明时,动物看起来就像棋盘,而立方体更混乱:
这里是顶点着色器:
#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,它现在还没有使用)。
然后,碎片着色器:
#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设置。
这是单个顶点的样子:
struct Vertex1P1N1UV {
glm::vec4 mPosition;
glm::vec3 mTextureCoords;
glm::vec3 mNormal;
Vertex1P1N1UV();
Vertex1P1N1UV(glm::vec4 position, glm::vec3 texcoords, glm::vec3 normal);
};我像这样初始化我的VAO
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初始化法
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;
}
}缓冲区初始化方法
void initialize(const std::vector<Vertex>& data) override {
bind();
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(Vertex), data.data(), GL_STATIC_DRAW);
}在这种情况下,顶点将变成Vertex1P1N1UV
更新:
实现正常的可视化(重新上传的屏幕截图,滚动到顶部)。困扰我的是,我可以通过网格看到法线,就像它是透明的,尽管不透明的颜色。这是深度测试问题吗?
发布于 2017-04-10 17:50:47
经过两天的挣扎,我发现了这个问题。我没有在NSOpenGLView上启用深度缓冲区。这是一行代码。如果有人无意中发现了这一点,他可以在这里测试不起作用寻找一个解决方案。
https://stackoverflow.com/questions/43305738
复制相似问题