【问题标题】:How to translate using shaders and matrices?如何使用着色器和矩阵进行翻译?
【发布时间】:2015-02-01 16:19:49
【问题描述】:

我正在使用 LWJGL 和着色器来尝试翻译我在着色器程序中绘制的所有内容。 我使用的是 4 x 4 矩阵

1,0,0,x,
0,1,0,y,
0,0,1,z,
0,0,0,1

x,y,z 是我用来翻译的值。然后我用

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * transformMatrix

transformMatrix 是我从上面的矩阵中得到的统一 mat4。 它可以很好地平移 x 和 y,但不能在 z 轴上(向前和向后)。

是矩阵错误还是着色器方法错误? (或两者兼有)

我该如何解决这个问题,使它像glTranslatef 一样翻译?谢谢

【问题讨论】:

  • 您可能不应该使用 gl_ 输入(它们已被弃用)而是使用 glVertexAttribPointer 和 VBO,并使用适当的制服
  • 烧杯:修复了 z 轴平移,但现在所有 x 和 y 都是倾斜的。 Ratchet:一切似乎都被弃用了。我转向着色器,因为 glTranslatef 被弃用了。

标签: opengl matrix glsl shader lwjgl


【解决方案1】:

矩阵本身看起来不错。请记住,OpenGL 默认使用列优先存储矩阵,因此当您指定它时,该矩阵的元素将按如下顺序排列:

{1.0f, 0.0f, 0.0f, 0.0f,
 0.0f, 1.0f, 0.0f, 0.0f,
 0.0f, 0.0f, 1.0f, 0.0f,
 x,    y,    z,    1.0f}

如果您想在代码中坚持行优先顺序,您还可以指定 GL_TRUE 作为 glUniformMatrix4fv()' 的第三个参数 (transpose)。

您似乎被困在两个不同级别的 OpenGL 之间。为了说明这一点,让我列出 OpenGL 的一些主要发展阶段。以下不是官方术语,我只是编造的。

  • 第一阶段:固定功能管道。渲染纯粹是通过指定状态和发出绘图命令来执行的。状态包括矩阵堆栈、光照和材质属性等。
  • 第 2 阶段:具有固定功能属性的可编程管道。着色器用于控制渲染,但仍使用矩阵堆栈等固定功能状态。使用 GLSL 代码中的预定义变量访问此状态。
  • 第 3 阶段:完全可编程。不再使用固定函数状态,并且所有对着色器的输入都使用通用属性和制服指定。

将此与 OpenGL 版本相匹配:

  • OpenGL 1.x 严格使用 Stage 1。
  • OpenGL 2.x 代码通常使用第 2 阶段,尽管它完全向后兼容并且仍然支持第 1 阶段的所有内容。它已经具备第 3 阶段所需的大部分功能。
  • OpenGL 3.x 及更高版本仅支持带有核心配置文件的 Stage 3(在 3.2 中引入)。第 1 阶段和第 2 阶段的所有固定功能方面仅在兼容性配置文件中可用。

您的代码片段表明您正在使用第 2 阶段,并且正在尝试移至第 3 阶段。在此过程中,您在两者之间创建了一个有问题的组合。根据你想走的方向,解决方案是不同的。

固定功能状态的使用

只要您在着色器 (gl_ModelViewProjectionMatrix) 中使用固定函数矩阵堆栈中的矩阵,最简单的解决方案就是充分利用它。

所以要翻译,你调用glTranslatef(),它会为你的模型视图矩阵添加一个翻译,然后在GLSL代码中使用gl_ModelViewProjectionMatrix和类似的内置变量来访问。

固定函数和均匀的混合

使用您尝试使用的方法,最合理的解决方案是将附加的平移矩阵与内置gl_ModelViewProjectionMatrix之前的向量相乘:

gl_Position = gl_ModelViewProjectionMatrix * transformMatrix * gl_Vertex;

您需要注意,这会在模型视图转换中所有其他模型转换之前应用附加转换。假设您还使用固定函数调用指定了旋转:

glRotatef(...);

这种旋转是模型视图矩阵的一部分,现在将在您添加的平移之后应用。因此,您将旋转翻译后的坐标,这可能不是您想要的。

使用这种方法,没有好方法可以在其他模型转换后应用翻译。你基本上需要的是这样的:

gl_ProjectionMatrix * gl_ViewMatrix * transformMatrix * gl_ModelMatrix * gl_Vertex;

但由于 View 和 Model 矩阵在固定函数状态下组合,这是不可能的。

无固定功能状态

为了充分的灵活性和与当前核心配置文件的兼容性,您需要停止使用固定的函数状态,以及相应的 GLSL 内置变量,如 gl_ModelViewProjectionMatrix。为此,您需要在着色器代码中将所有需要的矩阵指定为统一变量。这使您可以完全控制所使用的矩阵,以及如何在 GLSL 代码中应用它们。

例如,如果您只需要翻译,则无需使用完整矩阵。您可以使用vec3 作为制服,并将其添加到位置向量中。

完全可编程方法的主要缺点是您不能再使用glRotatef()gluLookAtgluPerspective() 等便利功能。有提供替换的开源库,如果您愿意,也很容易自己编写类似的函数。您也不再有矩阵堆栈,因此如果您依赖于转换层次结构,则需要在自己的代码中添加更多逻辑。

【讨论】:

  • 这听起来有点难。但无论如何我都必须学习无固定功能状态的方式。并感谢矩阵的排序,这使它工作,但我想我还有更多的东西要学。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-29
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多