1

我尝试使用 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

特别是第一张图片显示,灯的中心点不是直接在灯下,而是稍微移动到三角形的中心。

如果我将“pos”传递给片段着色器(即,它被插值)然后在片段着色器中计算“lightDir”,一切正常。

4

1 回答 1

3

我认为在顶点着色器中标准化你的 lightDir 会影响你在插值向量时得到的结果,因为它会从方程中取出长度,从而影响插值的“速度”。

如果您想要(视觉)解释,请尝试在纸上以 2D 形式绘制。首先画一条线(你的三角形)和一个点(光源)。为线的两端添加两条线 (lightDir) 到光源,然后收缩(标准化)这些 lightDir 线,使它们具有相同的长度并且都在光源处相遇。如果您连接标准化 lightDir 线的两端,您将得到一条不平行的线(如果光源不在第一条线的中间)。现在,如果你画一条正好穿过其中一条线中间的线,你会看到它没有穿过另一条线的中间,而是向左或向右一点。

于 2009-06-14T18:34:18.323 回答