【问题标题】:GLSL point light shader moving with cameraGLSL 点光源着色器随相机移动
【发布时间】:2014-08-31 18:05:00
【问题描述】:

我一直在尝试使用着色器为 LWJGL 游戏制作基本的静态点光源,但是当摄像机的位置被平移和旋转时,光源看起来好像在移动。这些着色器是从 OpenGL 4.3 指南稍微修改的,所以我不确定为什么它们没有按预期工作。谁能解释为什么这些着色器没有按预期工作以及我可以做些什么来让它们工作?

顶点着色器:

varying vec3 color, normal;
varying vec4 vertexPos;

void main() {
    color = vec3(0.4);
    normal = normalize(gl_NormalMatrix * gl_Normal);
    vertexPos = gl_ModelViewMatrix * gl_Vertex;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

片段着色器:

varying vec3 color, normal;
varying vec4 vertexPos;

void main() {
    vec3 lightPos = vec3(4.0);
    vec3 lightColor = vec3(0.75);
    vec3 lightDir = lightPos - vertexPos.xyz;
    float lightDist = length(lightDir);
    float attenuation = 1.0 / (3.0 + 0.007 * lightDist +  0.000008 * lightDist * lightDist);
    float diffuse = max(0.0, dot(normal, lightDir));
    vec3 ambient = vec3(0.4, 0.4, 0.4);
    vec3 finalColor = color * (ambient + lightColor * diffuse * attenuation);
    gl_FragColor = vec4(finalColor, 1.0);
}

【问题讨论】:

  • 如果有人感兴趣,我最终找到了解决方案。删除对 gl_NormalMatrix 和 gl_ModelViewMatrix 的调用解决了这个问题。
  • 您应该将此作为答案发布并接受。

标签: opengl glsl shader lwjgl


【解决方案1】:

如果有人感兴趣,我最终找到了解决方案。删除对 gl_NormalMatrix 和 gl_ModelViewMatrix 的调用解决了这个问题。

【讨论】:

    【解决方案2】:

    这里的临界值 lightPos 被设置为 vertexPos 的函数,您已经在屏幕空间中表达了它(这是因为它的原始世界空间形式乘以 modelView)。屏幕空间由相机保留,而不是 3D 世界中的任何东西。因此,对于世界空间中的某个绝对点(如 [4.0, 4.0, 4.0]),要拥有一个不移动的光源,您可以将对象的点留在您发现的那个空间中。

    但是摆脱模型视图并不是一个好主意,因为模型矩阵的重点是将对象放置在它们所属的位置(因此您可以重用顶点数组,只更改模型矩阵,而不是让他们从头开始指定每个形状的顶点位置)。

    更好的方法是在 vertexPos 和 lightPos 上执行 modelView 乘法。这样,您将 lightPos 视为最初是世界空间中的一个量,然后在屏幕空间中进行比较。从法线获取光强度的数学计算在任一空间中都将相同,您将获得一个外观正确的光源。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 2011-05-21
      • 2011-09-20
      • 1970-01-01
      相关资源
      最近更新 更多