使用GLSL着色器+光照/法向量

3
我有一个基于瓷砖的游戏项目,使用OpenGL是我的第一个真正意义上的IT技术项目。我想将每个瓷砖渲染成一个3D对象。所以我首先创建了一些对象,如立方体和球体,并为它们提供了顶点法线,在平面着色的即时模式下进行渲染。但由于每个层级有大约10,000个对象,速度有点慢。所以我把我的顶点和法线放到了VBOs里。
这就遇到了第一个问题:在使用VBOs之前,我只是对每个对象使用push()pop()矩阵,并使用glTranslate/glRotate来将它们放置在我的场景中。但当我使用VBOs时,灯光开始表现得很奇怪。光源似乎不再是相机后面的固定位置,而是随着我的物体旋转。当我绕着它们移动180度时,我只能看到阴影。
所以我做了一些研究。我没有找到任何关于我的具体问题的答案,但我读到,应该实现着色器并为其提供统一的矩阵,而不是使用glTranslate/glRotate
我想“也许这也可以解决我的问题”,并实现了一个第一个小的顶点着色器程序,它只是稍微拉伸了我的对象,只是为了看看是否能够让着色器工作,然后再关注细节。
void main(void)
{
    vec4 v = gl_Vertex;
    v.x = v.x * 0.5;
    v.y = v.y * 0.5;
    gl_Position = gl_ModelViewProjectionMatrix * v;
}

嗯,我的对象被拉伸了-但现在OpenGL的平面着色已经不可用。我只能得到白色阴影。我找不到任何有用的信息。所以我有几个问题:

  • 我只能同时使用一个着色器吗?当使用自己的着色器时,OpenGL的平面着色会关闭吗?因此,我是否必须自己实现平面着色?

  • 那么我的向量法线呢?我在某处读到,有一种称为normal-matrix的东西。也许我修改顶点时也必须对我的法线进行操作?

1个回答

1

如果您的矩阵操作导致灯光出现问题,那么您对glLightfv(..., GL_POSITION, ...)的调用发生在错误的上下文中(不是OpenGL上下文,而是矩阵状态等)。

我的对象被拉伸了 - 但现在OpenGL的平面着色已经失效了。我只得到白色阴影

我想你指的是Gourad着色(平面着色意味着不同)。问题是:如果您正在使用顶点着色器,则必须执行固定功能管道所做的所有操作。这包括光照计算。Lighthouse3D有一个很好的教程http://www.lighthouse3d.com/tutorials/glsl-tutorial/lighting/,Nicol Bolas也有一个http://arcsynthesis.org/gltut/Illumination/Illumination.html


我重写了Cocoa的NSOpenGLView,并将glLightfv()方法放入[prepareOpenGL]方法中。这应该是正确的。同时,它在立即模式下确实有效,但自从我切换到VBOs后就出现了问题,所以它在我放置它的地方是有效的,但与VBOs不兼容。 - cargath
大多数人称之为“平面着色”。在OpenGL本身中,它甚至被称为“平面着色”:glShadeModel(GL_FLAT)。但我明白你的意思,有一种着色方法可以真正使所有具有相同名称的对象变平。我猜你所说的固定功能管道所做的一切都是指FFP在顶点转换阶段所做的一切? - cargath
谢谢。我能找到的所有教程都将它放在prepareOpenGL方法中,所以我猜我学错了。但是把它放在我的绘图函数中也没有帮助。 - cargath
经过更多的实验,我不认为光线还会随着我的物体旋转了。我尝试使用一个立方体,灯光确实在旋转过程中发生了变化,只是它会从明亮到暗淡再到明亮,然后又变暗,如此循环...很奇怪。 - cargath
好的,非常抱歉,事实证明我只是太蠢了:我不小心打开了TEX_COORD_ARRAY而不是NORMAL_ARRAY,所以灯光无法正常工作。既然你能帮我解决其他问题,这就是正确的答案。谢谢。 - cargath
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接