我按照教程添加了简单的漫反射照明,但照明非常破碎:
除了不一致之外,所有漫反射组件在某些相机Angular 完全消失(相机位置似乎对此没有影响)
顶点着色器:
#version 450 core
layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec4 vNormal;
layout (location = 2) out vec4 fNormal;
layout (location = 3) out vec4 fPos;
uniform mat4 MVMatrix;
uniform mat4 PMatrix;
void main()
{
gl_Position = PMatrix * (MVMatrix * vPosition);
fNormal = normalize(inverse(transpose(MVMatrix))*vNormal);
fPos = MVMatrix * vPosition;
}
片段着色器:
#version 450 core
layout (location = 0) out vec4 fColor;
layout (location = 2) in vec4 fNormal;
layout (location = 3) in vec4 fPos;
uniform vec4 objColour;
void main()
{
vec3 lightColour = vec3(0.5, 0.0, 0.8);
vec3 lightPos = vec3(10, 20, 30);
float ambientStrength = 0.4;
vec3 ambient = ambientStrength * lightColour;
vec3 diffLightDir = normalize(lightPos - vec3(fPos));
float diff = max(dot(vec3(fNormal), diffLightDir), 0.0);
vec3 diffuse = diff * lightColour;
vec3 rgb = (ambient + diffuse) * objColour.rgb;
fColor = vec4(rgb, objColour.a);
}
正常计算(由于Python的性质,我没有遵循教程,这可能是问题所在)
self.vertices = np.array([], dtype=np.float32)
self.normals = np.array([], dtype=np.float32)
data = Wavefront(r"C:\Users\cwinm\AppData\Local\Programs\Python\Python311\holder.obj", collect_faces=True)
all_vertices = data.vertices
for mesh in data.mesh_list:
for face in mesh.faces:
face_vertices = np.array([all_vertices[face[i]] for i in range(3)])
normal = np.cross(face_vertices[0]-face_vertices[1], face_vertices[2] - face_vertices[1])
normal /= np.linalg.norm(normal)
self.vertices = np.append(self.vertices, face_vertices)
for i in range(3): self.normals = np.append(self.normals, normal)
self.index = index_getter(len(self.vertices))
self.vertices.resize((len(self.vertices)//3, 3))
self.vertices = np.array(self.vertices * [0.5, 0.5, 0.5], dtype=np.float32)
型
(The局部顶点和法线随后被附加到全局顶点和法线缓冲区,该缓冲区在初始化后被推送到OpenGL)
创建VBO(也可能是个问题)
vPositionLoc = glGetAttribLocation(self.program, "vPosition")
vNormalLoc = glGetAttribLocation(self.program, "vNormal")
self.Buffers[self.PositionBuffer] = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.Buffers[self.PositionBuffer])
glBufferStorage(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, 0)
glVertexAttribPointer(vPositionLoc, 3, GL_FLOAT, False, 0, None)
glEnableVertexAttribArray(vPositionLoc)
self.Buffers[self.NormalBuffer] = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.Buffers[self.NormalBuffer])
glBufferStorage(GL_ARRAY_BUFFER, self.normals.nbytes, self.normals, 0)
glVertexAttribPointer(vNormalLoc, 3, GL_FLOAT, False, 0, None)
glEnableVertexAttribArray(vNormalLoc)
环境光,矩阵,顶点处理都是功能,事情只是打破了当我添加法线和(试图)漫射光
2条答案
按热度按时间x3naxklr1#
这里的问题是法线的类型是
np.float64
。下面代码中的
self.normals
是np.float64
,而不是您所期望的np.float32
。要修复它,您可以执行以下操作:
关于着色器,你确实需要使用
mat3x3
来进行vec3
法线变换。另外,对于旋转矩阵,transpose
等于inverse
,因此inverse(transpose(Rot)) = Rot
。因此看起来有些多余,你可以将其重写为:型
别忘了检查片段着色器中的法线方向。它看起来应该是:
vc6uscn92#
vNormal
是一个有3个分量的向量。你必须用法向矩阵来转换法向向量。法向矩阵是模型视图矩阵左上角3x3分量的逆转置(无平移):这与以下内容相同:
如果未指定或仅部分指定某个属性,则x、y和z分量默认为0.0,但w分量默认为1.0。
fNormal = normalize(inverse(transpose(MVMatrix)) * vec4(vNormal.xyz, 1.0));
,这是错误的,因为您正在将模型视图矩阵的转换应用到法向量此外,
fNormal
必须在片段着色器中规格化,因为通过插值,长度不会保持为1.0。