2009-06-14 57 views
0

我尝试使用GLSL在OpenGL中实现点光源。我将所有需要的数据发送给着色器。为了简单起见,我只在这里使用漫射光。OpenGL GLSL插值

我的例子显示了一个巨大的三角形,我想用一个光源照亮。光源显示为一个小蓝色三角形。

对于漫射光,我需要知道光线与表面之间的角度。因此,我计算法线和光线的方向。点积将给我一个介于-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”,则一切正常。

+0

不要标准化顶点着色器中的lightDir。由于规范化不是线性操作,因此您只应在碎片着色器中执行此操作。 – Hannesh 2010-12-11 09:49:54

回答

3

我认为在顶点着色器中标准化lightDir会影响插值矢量时得到的结果,因为它将长度从等式中移出,从而影响插值的“速度”。

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