【发布时间】:2010-11-02 20:15:48
【问题描述】:
我尝试使用 GLSL 在 OpenGL 中实现点光源。我将所有需要的数据发送到着色器。为简单起见,我在这里只使用漫反射光。
我的示例显示了一个巨大的三角形,我想用一个光源照亮它。光源显示为一个蓝色的小三角形。
对于漫射光,我需要知道光与表面之间的角度。因此,我计算法线和光线的方向。然后点积会给我一个介于 -1 和 1 之间的数字,而 0 和 1 之间的所有内容都会被照亮。
但是,我在这里卡住了,因为在我的示例中这个角度计算不正确。由于很难调试着色器,我使用了几个输出作为我的表面颜色。我使用法线作为三角形的颜色,无论光线在哪里,表面总是绿色。也就是说,法线指向 y 轴,因此它们被正确计算。也就是说,光的方向一定是错误的。但是,我找不到错误的原因。光的位置和顶点的位置在世界空间中传递给顶点着色器,然后将它们转换到眼睛空间,计算光的方向并将其传递给片段着色器:
顶点着色器:
vec4 pos = modelview_matrix * <input vertex>;
vec4 lightPos = modelview_matrix * <light position>;
vec3 lightDir = normalize(lightPos.xyz - pos.xyz);
片段着色器:
float NdotL = max(dot(normalize(<correct normal>), normalize(lightDir)), 0.0);
gl_FragColor = vec4(1.0, NdotL, 0.0, 1.0);
我已经附上了这个例子的一些图片,这些图片肯定表明插值真的很奇怪。我知道想知道我粘贴的代码是否正确,或者您是否需要了解更多代码。此外,这种插值行为是正常的还是我的代码中的错误?
http://img41.imageshack.us/img41/3566/interpolation.png http://img189.imageshack.us/img189/3566/interpolation.png
特别是第一张图,灯光的中心点NOT在灯光的正下方,但稍微移到了三角形的中心。
如果我将“pos”传递给片段着色器(即,它被插值),然后在片段着色器中计算“lightDir”,一切正常。
【问题讨论】:
-
不要在你的顶点着色器中标准化 lightDir。由于规范化不是线性操作,您应该只在片段着色器中进行。
-
你的照片不会去任何地方(顺便说一下,ImageShack 是一个糟糕的图像主机)。试试Imgur,当你转换链接时我会内联它们。
标签: opengl glsl interpolation lighting