OpenGL 3.3 光照产生非常奇怪的失真
OpenGL 3.3 lighting gives really strange disortions
上个月,我一直在关注各个页面 (learnopengl.com) 上的教程。
我进入了照明部分(我首先创建了一个加载器来使用 Assimp 加载网格),我的片段着色器代码与教程照明几乎相同(learnopengl.com/basic_lighting)。
碎片代码:
#version 130
out vec4 outColor;
in vec3 fragPos;
in vec3 normal;
in vec2 texcoord;
uniform sampler2D tex;
uniform vec3 lightPos;
uniform vec3 lightColor;
void main(){
float ambientStrength = 0.1f;
vec3 ambient = ambientStrength * lightColor;
//Diffuse
vec3 norm = normalize(normal);
vec3 lightDir = normalize(lightPos - fragPos);
float diff = max(dot(norm, lightDir), 0.0f);
vec3 diffuse = diff * lightColor;
float objectColor = 0.5f;
//texture(tex, texcoord)
vec3 result = (ambient + diffuse) * objectColor;
outColor = vec4(result, 1.0f);
}
例如,当为飞机打光时,它会给我这些结果:
当我不为飞机照明时,它是纯灰色的。
这是 .obj 文件或飞机:
Blender v2.69 (sub 0) OBJ File: 'plane.blend'
# www.blender.org
mtllib plane.mtl
o Plane
v 10.000000 0.000000 10.000000
v -10.000000 0.000000 10.000000
v 10.000000 0.000000 -10.000000
v -10.000000 0.000000 -10.000000
vn 0.000000 1.000000 0.000000
usemtl None
s off
f 2//1 1//1 3//1
f 4//1 2//1 3//1
导入正确,每个顶点的法线都是 { 0, 1, 0} 并且索引也是正确的。
在搜索 "OpenGL light disortions" 或 "OpenGL lighting" 之类的内容时,我找不到这样的内容。所以我真的不知道出了什么问题。
哦,是的,我使用 openGL 3.3,并且我有一个集成的英特尔 GPU。
CPU是intel core i3-2367M,以防硬件有问题
感谢您的宝贵时间:D
编辑:
所以我只是试着在平面上显示法线的颜色,它们应该是纯绿色,但它们太可恶了:
我还将在这里转储我的顶点着色器代码:
#version 130
in vec3 position;
in vec3 normal;
in vec2 texCoord;
out vec3 fragPos;
out vec3 Normal;
out vec2 texcoord;
uniform mat4 transform;
uniform mat4 view;
uniform mat4 projection;
void main(){
texcoord = texCoord;
Normal = normal;
fragPos = vec3(transform * vec4(position, 1.0f));
gl_Position = projection * view * transform * vec4(position, 1.0);
}
这是我设置网格的方法:
void mesh::bindVertices(){
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0); // Position
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, normal)); //Normal
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texCoord)); //Texcoord
glBindVertexArray(0);
}
Vertex.h
#ifndef VERTEX_H
#define VERTEX_H
#include <vector>
#include <glm/glm.hpp>
class Vertex
{
public:
Vertex(){
position = glm::vec3(0.0f, 0.0f, 0.0f);
normal = glm::vec3(0.0f, 0.0f, 0.0f);
texCoord = glm::vec2(0.0f, 0.0f);
};
Vertex(glm::vec3 pos, glm::vec3 nor, glm::vec2 tex){
setUpVertex(pos, nor, tex);
};
~Vertex(){}
void setUpVertex(glm::vec3 pos, glm::vec3 nor, glm::vec2 tex){
this->position = pos;
this->normal = nor;
this->texCoord = tex;
};
void print(){
std::cout << "Position: { " << position.x << ", " << position.y << ", " << position.z << " }\n";
std::cout << "Normals: { " << normal.x << ", " << normal.y << ", " << normal.z << " }\n";
std::cout << "Texture Coordinates: { " << texCoord.x << ", " << texCoord.y << " }" << std::endl;
}
glm::vec3 position;
glm::vec3 normal;
glm::vec2 texCoord;
protected:
private:
};
#endif // VERTEX_H
打印函数是用来调试的,而且输出的值是正确的,所以我真的不知道是怎么回事。
有一件事不是问题,那就是加载到模型中是我设法收集到的,法线表现得非常奇怪。
您没有正确地将法线数据从顶点着色器传递到片段着色器。您在 VS 中使用 out vec3 Normal
,但在 FS 中使用 in vec3 normal
(注意小写),因此您的输入值未定义。
上个月,我一直在关注各个页面 (learnopengl.com) 上的教程。
我进入了照明部分(我首先创建了一个加载器来使用 Assimp 加载网格),我的片段着色器代码与教程照明几乎相同(learnopengl.com/basic_lighting)。
碎片代码:
#version 130
out vec4 outColor;
in vec3 fragPos;
in vec3 normal;
in vec2 texcoord;
uniform sampler2D tex;
uniform vec3 lightPos;
uniform vec3 lightColor;
void main(){
float ambientStrength = 0.1f;
vec3 ambient = ambientStrength * lightColor;
//Diffuse
vec3 norm = normalize(normal);
vec3 lightDir = normalize(lightPos - fragPos);
float diff = max(dot(norm, lightDir), 0.0f);
vec3 diffuse = diff * lightColor;
float objectColor = 0.5f;
//texture(tex, texcoord)
vec3 result = (ambient + diffuse) * objectColor;
outColor = vec4(result, 1.0f);
}
例如,当为飞机打光时,它会给我这些结果:
当我不为飞机照明时,它是纯灰色的。
这是 .obj 文件或飞机:
Blender v2.69 (sub 0) OBJ File: 'plane.blend'
# www.blender.org
mtllib plane.mtl
o Plane
v 10.000000 0.000000 10.000000
v -10.000000 0.000000 10.000000
v 10.000000 0.000000 -10.000000
v -10.000000 0.000000 -10.000000
vn 0.000000 1.000000 0.000000
usemtl None
s off
f 2//1 1//1 3//1
f 4//1 2//1 3//1
导入正确,每个顶点的法线都是 { 0, 1, 0} 并且索引也是正确的。
在搜索 "OpenGL light disortions" 或 "OpenGL lighting" 之类的内容时,我找不到这样的内容。所以我真的不知道出了什么问题。
哦,是的,我使用 openGL 3.3,并且我有一个集成的英特尔 GPU。 CPU是intel core i3-2367M,以防硬件有问题
感谢您的宝贵时间:D
编辑:
所以我只是试着在平面上显示法线的颜色,它们应该是纯绿色,但它们太可恶了:
我还将在这里转储我的顶点着色器代码:
#version 130
in vec3 position;
in vec3 normal;
in vec2 texCoord;
out vec3 fragPos;
out vec3 Normal;
out vec2 texcoord;
uniform mat4 transform;
uniform mat4 view;
uniform mat4 projection;
void main(){
texcoord = texCoord;
Normal = normal;
fragPos = vec3(transform * vec4(position, 1.0f));
gl_Position = projection * view * transform * vec4(position, 1.0);
}
这是我设置网格的方法:
void mesh::bindVertices(){
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0); // Position
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, normal)); //Normal
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texCoord)); //Texcoord
glBindVertexArray(0);
}
Vertex.h
#ifndef VERTEX_H
#define VERTEX_H
#include <vector>
#include <glm/glm.hpp>
class Vertex
{
public:
Vertex(){
position = glm::vec3(0.0f, 0.0f, 0.0f);
normal = glm::vec3(0.0f, 0.0f, 0.0f);
texCoord = glm::vec2(0.0f, 0.0f);
};
Vertex(glm::vec3 pos, glm::vec3 nor, glm::vec2 tex){
setUpVertex(pos, nor, tex);
};
~Vertex(){}
void setUpVertex(glm::vec3 pos, glm::vec3 nor, glm::vec2 tex){
this->position = pos;
this->normal = nor;
this->texCoord = tex;
};
void print(){
std::cout << "Position: { " << position.x << ", " << position.y << ", " << position.z << " }\n";
std::cout << "Normals: { " << normal.x << ", " << normal.y << ", " << normal.z << " }\n";
std::cout << "Texture Coordinates: { " << texCoord.x << ", " << texCoord.y << " }" << std::endl;
}
glm::vec3 position;
glm::vec3 normal;
glm::vec2 texCoord;
protected:
private:
};
#endif // VERTEX_H
打印函数是用来调试的,而且输出的值是正确的,所以我真的不知道是怎么回事。
有一件事不是问题,那就是加载到模型中是我设法收集到的,法线表现得非常奇怪。
您没有正确地将法线数据从顶点着色器传递到片段着色器。您在 VS 中使用 out vec3 Normal
,但在 FS 中使用 in vec3 normal
(注意小写),因此您的输入值未定义。