【问题标题】:Not sure how to properly use Matrix4.LookAt in this situation不确定在这种情况下如何正确使用 Matrix4.LookAt
【发布时间】:2021-02-14 22:20:53
【问题描述】:

我正在尝试光线行进,并一直关注Jamie Wong's tutorial.

当移动相机部分来时,他们使用该功能

mat4 viewMatrix(vec3 eye, vec3 center, vec3 up) {
    vec3 f = normalize(center - eye);
    vec3 s = normalize(cross(f, up));
    vec3 u = cross(s, f);
    return mat4(
        vec4(s, 0.0),
        vec4(u, 0.0),
        vec4(-f, 0.0),
        vec4(0.0, 0.0, 0.0, 1)
    );
}

生成可用于转换方向向量的矩阵,以便相机看到正确的对象。

我想将矩阵计算移出着色器,因为它更适合作为制服,所以我这样做了,但是 OpenTK 的函数 Matrix4.LookAt() 产生了非常不同的结果,我不确定如何通过 Jamie 的函数给出的简单乘法将它们应用于射线。

我已确认矩阵已正确加载到制服中,只是不适用于方向向量。

编辑:我知道我可以将 Jamie Wong 的函数从 GLSL 翻译成 C#,但我想知道 Matrix4.LookAt 的正确用法。

【问题讨论】:

  • 好吧,您引用的 viewMatrix 函数不是“LookAt”函数,因为它通常用于计算机图形的上下文中;您的函数仅设置 旋转矩阵 并且不会根据 eye 位置进行平移。至少非常不幸的是,如果它真的只对视图方向感兴趣,它使用参数eyecenter,并且真的误导用户认为它可能会创建一个lookAt 矩阵(不确定是有意还是不是)
  • @derhass 那是有道理的。那么 LookAt 函数是否相关,还是我应该将 viewMatrix 函数翻译成 C#?
  • 嗯,情况更糟。它被称为viewMatrix,但创建了我们通常称为视图矩阵的(它应该从世界空间转换到视图空间)。从概念上讲,代码的作用与Transpose(LookAt( (0,0,0), center-eye, up)) 的作用相同。
  • 请注意,这段代码没有任何问题 - 进行逆变换对光线投射完全有意义,它只是不符合这个概念 - 和 术语 -像LookAt 这样的矩阵辅助函数用于光栅化管道。

标签: c# opengl matrix glsl opentk


【解决方案1】:

OpenTK 在OpenTK.Mathematics 命名空间中提供数据类型Vector3Vector4Matrix4

假设你有向量:

Vector3 center;
Vector3 eye;
Vector3 up;

如下计算视图矩阵

var f = Vector3.Normalize(center - eye);
var s = Vector3.Normalize(Vector3.Cross(f, up));
var u = Vector3.cross(s, f);
var viewMatrix = new Matrix4(
    new Vector4(s, 0.0f),
    new Vector4(u, 0.0f),
    new Vector4(-f, 0.0f),
    new Vector4(0.0f, 0.0f, 0,0f, 1.0f),
);

mat4 类型的制服可以用GL.UniformMatrix4 设置。例如:

uniform mat4 viewMatrix;
int viewMatrixLoc = GL.GetUniformLocation(0, "viewMatrix");
GL.UniformMatrix4(viewMatrixLoc, false, ref viewMatrix);

您的“视图矩阵”从视图空间转换为世界空间。它将“视图”光线转换为世界。
Matrix4.LookAt 则相反。它计算一个将世界空间转换为视图空间的矩阵。它会生成一个用于光栅化的矩阵,其中必须将对象从世界转换为视图。
所以你需要invert你从Matrix4.LookAt得到的矩阵:

Matrix4 viewMatrix = Matrix4.LookAt(
    new Vector3(0.0f),
    center - eye,
    up
).Inverted();

【讨论】:

  • 是的,我知道我可以将 Jamie 的函数翻译成 C#,但我想知道如何在适用的情况下正确使用内置的 Matrix4.LookAt 方法。抱歉,我应该在我的问题中更清楚地说明这一点。
  • @Salmon 我已经扩展了答案。
猜你喜欢
  • 2020-08-06
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 2013-11-21
  • 1970-01-01
相关资源
最近更新 更多