这是搞砸了 Normals 的工作还是它可能是什么?
Is this the work of messed up Normals or what could it be?
所以我正在上一门图形课程,我正在编写着色器。在课程中,我们可以访问服务 运行ning webgl 以及一堆要编译的 C++ 代码,以获得一个运行几个模型的环境。但是,无论我是在 Windows 还是 Linux 上编译这段代码都没有关系,我没有得到我应该得到的结果。
这就是我使用与此结果完全相同的 glsl 代码得到的结果:
我还没有编写足够的 C++ 来调试程序,但我怀疑程序本身而不是着色器中存在错误,所以我想知道是否有人可以根据经验判断这是什么类型的问题然后我将尝试找到处理它的代码。
我的猜测是它与法线有关,但我不太确定,因为我刚开始接触图形,那是两年前我正确地进行了线性代数。因为我不知道 C++ 源代码(我现在正在分析它,所以我可以理解流程)我不知道在哪里调试。
顶点着色器:
....
attribute vec3 VertexPosition
attribute vec2 VertexST
attribute vec3 VertexNormal
....
void main(void) {
Position = ProjectionMatrix * ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
Normal = normalize ((ViewMatrix * WorldMatrix * vec4 (VertexNormal, 0)).xyz);
EyeSpaceLightPosition = ViewMatrix * LightPosition;
EyeSpaceVertexPosition = ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
EyeSpaceObjectPosition = ViewMatrix * WorldMatrix * vec4 (0, 0, 0, 1);
STCoords = VertexST;
gl_Position = Position;
}
像素着色器:
void main(void) {
fragColor = vec4 (Normal, 1.0);
gl_FragColor = fragColor;
}
这段代码实际上是运行ning。之前有声明和东西,但是是的。实际文件中有更多代码,但它们已被注释,因此这些行不会 运行.
所以问题解决了,原因是在顶点着色器中有三个声明告诉着色器信息在数组中是如何排序的。它说:
attribute vec3 VertexPosition;
attribute vec2 VertexST;
attribute vec3 VertexNormal;
这是错误的,因为从 CPU 提供给 GPU 的信息实际上是按 Position、Normal、ST 排序的。
这意味着它们应该切换,发生的事情是着色器获取了错误的信息并将其继续发送到试图在没有任何法线的情况下进行照明的像素着色器(我相信在这种情况下我们没有ST信息,我认为是纹理坐标)。
这使得模型无法像问题中的第一张图片那样正确渲染,但是在切换这些行之后:
attribute vec3 VertexPosition;
attribute vec3 VertexNormal; // Switched these two
attribute vec2 VertexST; //
现在着色器可以正确解释提供给它的信息,结果是预期的。
编辑:这是程序实际定义的内容,可以通过不同的方式完成。但是就我分配给我的程序而言,它是按此顺序排列的。但正如评论者所说,这取决于。但问题仍然是程序中的声明顺序与着色器中的顺序不同
所以我正在上一门图形课程,我正在编写着色器。在课程中,我们可以访问服务 运行ning webgl 以及一堆要编译的 C++ 代码,以获得一个运行几个模型的环境。但是,无论我是在 Windows 还是 Linux 上编译这段代码都没有关系,我没有得到我应该得到的结果。
这就是我使用与此结果完全相同的 glsl 代码得到的结果:
我还没有编写足够的 C++ 来调试程序,但我怀疑程序本身而不是着色器中存在错误,所以我想知道是否有人可以根据经验判断这是什么类型的问题然后我将尝试找到处理它的代码。
我的猜测是它与法线有关,但我不太确定,因为我刚开始接触图形,那是两年前我正确地进行了线性代数。因为我不知道 C++ 源代码(我现在正在分析它,所以我可以理解流程)我不知道在哪里调试。
顶点着色器:
....
attribute vec3 VertexPosition
attribute vec2 VertexST
attribute vec3 VertexNormal
....
void main(void) {
Position = ProjectionMatrix * ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
Normal = normalize ((ViewMatrix * WorldMatrix * vec4 (VertexNormal, 0)).xyz);
EyeSpaceLightPosition = ViewMatrix * LightPosition;
EyeSpaceVertexPosition = ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
EyeSpaceObjectPosition = ViewMatrix * WorldMatrix * vec4 (0, 0, 0, 1);
STCoords = VertexST;
gl_Position = Position;
}
像素着色器:
void main(void) {
fragColor = vec4 (Normal, 1.0);
gl_FragColor = fragColor;
}
这段代码实际上是运行ning。之前有声明和东西,但是是的。实际文件中有更多代码,但它们已被注释,因此这些行不会 运行.
所以问题解决了,原因是在顶点着色器中有三个声明告诉着色器信息在数组中是如何排序的。它说:
attribute vec3 VertexPosition;
attribute vec2 VertexST;
attribute vec3 VertexNormal;
这是错误的,因为从 CPU 提供给 GPU 的信息实际上是按 Position、Normal、ST 排序的。
这意味着它们应该切换,发生的事情是着色器获取了错误的信息并将其继续发送到试图在没有任何法线的情况下进行照明的像素着色器(我相信在这种情况下我们没有ST信息,我认为是纹理坐标)。
这使得模型无法像问题中的第一张图片那样正确渲染,但是在切换这些行之后:
attribute vec3 VertexPosition;
attribute vec3 VertexNormal; // Switched these two
attribute vec2 VertexST; //
现在着色器可以正确解释提供给它的信息,结果是预期的。
编辑:这是程序实际定义的内容,可以通过不同的方式完成。但是就我分配给我的程序而言,它是按此顺序排列的。但正如评论者所说,这取决于。但问题仍然是程序中的声明顺序与着色器中的顺序不同