为什么GLSL光照代码会随着相机移动而改变光源位置?

7

我正在尝试制作一个自定义的轻量级着色器,并在不断尝试各种方法。

我发现有些解决方案效果更好,而有些则更差。对于这个问题,我使用了到目前为止效果最好的解决方案。

我的问题是,如果我移动"相机",光的位置似乎也会移动。这个解决方案中有非常轻微但明显的运动,并且光的位置似乎在它应该在的上方。

默认的OpenGL照明(没有任何着色器)效果很好(稳定的光位置),但我需要着色器来进行多重纹理,并计划在其工作后使用其中的一部分进行照明效果。

顶点源代码:

varying vec3 vlp, vn;

void main(void)
{
    gl_Position = ftransform();

    vn = normalize(gl_NormalMatrix * -gl_Normal);
    vlp = normalize(vec3(gl_LightSource[0].position.xyz) - vec3(gl_ModelViewMatrix * -gl_Vertex));

    gl_TexCoord[0] = gl_MultiTexCoord0;
} 

碎片源代码:

uniform sampler2D baseTexture;
uniform sampler2D teamTexture;
uniform vec4 teamColor;

varying vec3 vlp, vn;

void main(void)
{
    vec4 newColor = texture2D(teamTexture, vec2(gl_TexCoord[0]));
    newColor = newColor * teamColor;
    float teamBlend = newColor.a;

    // mixing the textures and colorizing them. this works, I tested it w/o lighting!
    vec4 outColor = mix(texture2D(baseTexture, vec2(gl_TexCoord[0])), newColor, teamBlend);

    // apply lighting
    outColor *= max(dot(vn, vlp), 0.0);
    outColor.a = texture2D(baseTexture, vec2(gl_TexCoord[0])).a;

    gl_FragColor = outColor;
}

我做错了什么?


1
一些图片,甚至是指向问题的Youtube视频链接,将有助于我们诊断问题。 - Nicol Bolas
1个回答

5
我不能确定这些是问题,但它们可能会引起问题。
首先,您需要规范化每个顶点的vnvlp(顺便说一下,请尝试使用更具描述性的变量名。 viewLightPositionvlp更容易理解)。我知道您在顶点着色器中对它们进行了规范化,但片段着色器插值将使它们失去规范化。
其次,这并不特别错误,只是多余。 vec3(gl_LightSource [0] .position.xyz)。“position.xyz”已经是一个vec3,因为swizzle掩码(“.xyz”)只有3个分量。您不需要再将其强制转换为vec3。

1
哇,再次在片段着色器中对两个变量进行了规范化,从顶点着色器中去掉了gl_Normalgl_Vertex的否定,现在它可以工作了。非常感谢! - Cobra_Fast

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