在 GLSL 中使相机正常

Get the camera normal in GLSL

我有一个 OpenGL 场景,我在其中查看这样的对象:

gluLookAt(10, 10, -10, -10, -10, 10, 0, 1, 0);

所以我知道如果我想在着色器中使用相机的 z 轴,它看起来会像这个的归一化向量:

vec3(1.0, 1.0, -1,0);

有没有办法在顶点着色器中计算这个向量

我想计算 near/far 裁剪平面的法线,但无法在顶点(或片段)着色器中找到执行此操作的方法。

我使用的是旧管道 (OpenGL v2.0/ GLSL v. 1.10),不想将矢量传递给着色器(尽管我知道这是执行此操作的常用且高效的方法).

(已弃用)gluLookAt 的参数是 (vec3) eye_、center_ 和 up_ 的分量(x_ 表示向量值数据 x_

f: ℝ^3 x ℝ^3 x ℝ^3 -> ℝ4xℝ4 
eye_, center_, up_ -> ViewMatrix

因此您可能寻找的是

dir_ = normalize(center_ - eye_), 

在着色器中获取它们的最佳方式和位置取决于您使用的 GL 和 GLSL 版本。

这个向量

vec3(1.0, 1.0, -1,0);

btw has length sqrt(3), thus it's not normalized.

编辑

了解 OpenGL 和 GLSL 版本后,可以从

legacy GLSL 1.10.59 doc

GLSL 1.10.59 已经有了自定义制服(我记不清了,2.0/1.10 太久远了);因此,您只需将该向量作为制服传入即可,仅此而已。

因为它用于每个顶点,所以计算一次比在着色器中再次为每个顶点计算一次更有效(当然,假设渲染的顶点块相当大)。

将其作为制服传递给您的着色器。请参阅 glUniform3f.

的文档

在客户端代码中,执行如下操作:

auto cameraUp = camera.getUp();
glUniform3f(uniformLocationInShader, cameraUp.x, cameraUp.y, cameraUp.z)

在顶点着色器中,为相机向上矢量添加统一,然后按预期使用它。

uniform vec3 cameraUp;

void main() 
{
   // do stuff with cameraUp
} 

固定函数顶点变换通过应用两个矩阵来工作:

  1. 从对象 space 到眼睛 space
  2. 的 "ModelView" 矩阵变换
  3. 从眼睛 space 到剪辑 space
  4. 的 "Projection" 矩阵

gluLookAt() 所做的是通过在 world space 中定义一些相机来指定视图矩阵。而你似乎要重构的是这个世界的视线方向space.

但是,对于固定功能 GL,不可能。您所拥有的只是 产品 view * model。如果没有更多信息,您无法将其分解为 viewmodel 部分。 none 这些信息存在于固定函数 GL 中——它从来没有 一个世界 space,或者关心一个单独的视图矩阵。这种区别确实发生在应用程序逻辑中 - 如果有的话。

有趣的问题是:你甚至需要世界 space 的观察方向做什么?固定函数 GL 在眼睛 space 中进行此类计算,其中观察方向只是 (0,0,-1,0)。

所以我看到两个选项供您选择:

  1. 使用统一(或其他将数据传输到着色器的方法)来指定一些附加信息,就像其他答案已经建议的那样
  2. 直接用眼睛进行计算space