【问题标题】:OpenGL Diffuse Lighting Shader Bug?OpenGL漫反射照明着色器错误?
【发布时间】:2010-03-13 09:42:40
【问题描述】:

橙皮书第 16.2 节列出了实现漫反射照明:

void main()
{
  vec3 N = normalize(gl_NormalMatrix * gl_Normal);
  vec4 V = gl_ModelViewMatrix * gl_vertex;
  vec3 L = normalize(lightPos - V.xyz);
  gl_FrontColor = gl_Color * vec4(max(0.0, dot(N, L));
}

但是,当我运行它时,当我移动相机时,灯光会发生变化。 另一方面,当我改变时

  vec3 N = normalize(gl_NormalMatrix * gl_Normal);

到 vec3 N = normalize(gl_Normal);

我得到了像固定管道一样工作的漫射照明。

这个 gl_NormalMatrix 是什么,删除它做了什么,...这是橙皮书中的错误...还是我的 OpenGl 代码设置不正确?

[为了完整性,片段着色器只复制颜色]

【问题讨论】:

    标签: fragment-shader vertex-shader


    【解决方案1】:

    好的,希望半年多后回答您的问题没有问题? :)

    所以这里有两件事要讨论:


    a) 着色器应该是什么样子的

    您应该通过模型视图矩阵转换您的法线 - 这是给定的。考虑如果你不这样做会发生什么 - 你的模型视图矩阵可以包含某种旋转。您的立方体将被旋转,但法线仍将指向旧方向!这显然是错误的。

    所以:当您通过模型视图矩阵转换顶点时,您还应该转换法线。您的法线是vec3 而不是vec4,并且您对平移不感兴趣(法线仅包含方向),因此您可以将法线乘以mat3(gl_ModelViewMatrix),这是左上角的3-3 子矩阵。

    那么:这几乎是正确的,但还是有点错误——原因是well-described on Lighthouse 3D - go have a read。长话短说,你必须乘以它的逆转置,而不是 mat3(gl_ModelViewMatrix)

    OpenGL 2 非常有帮助,它会为您预先计算为gl_NormalMatrix。因此,正确的代码是:

    vec3 N = normalize(gl_NormalMatrix * gl_Normal);
    

    b) 但它不同于固定管道,为什么?

    我首先想到的是“您使用固定管道有问题”。

    我并不是很喜欢 FP(着色器万岁!),但据我所知,当您通过 glLightParameterfv(GL_LIGHT_POSITION, something) 指定灯光时,这会受到模型视图矩阵的影响。在错误的坐标系中指定灯光位置(或定向灯光的灯光方向)很容易(至少对我来说:))。

    我不确定我是否记得正确,因为我现在使用 GL3 和着色器,但让我试试......你的模型视图矩阵的状态是什么?我认为您可能已经在对象空间而不是眼睛空间中指定了定向光的方向,这样您的光就会与您的对象一起旋转。 IDK 如果这与此处相关,但在使用 FF 时请务必注意这一点。这是我记得自己在使用 GL 1.1 时经常犯的错误。

    根据模型视图的状态,您可以在以下位置指定灯光:

    • 眼睛(相机)空间,
    • 世界空间,
    • 对象空间。

    确定是哪一个。

    嗯..我希望这能让你的话题更清楚。结论是:

    1. 始终在顶点着色器中随顶点变换法线,并且
    2. 如果它看起来与您的预期不同,请考虑如何指定灯光位置。 (也许你也想在着色器中乘以灯光位置向量?关于灯光位置坐标系的评论仍然成立)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 2015-02-05
      • 2012-09-08
      • 2014-05-30
      • 1970-01-01
      • 2017-09-04
      • 1970-01-01
      相关资源
      最近更新 更多