不确定如何在这种情况下正确使用 Matrix4.LookAt

Not sure how to properly use Matrix4.LookAt in this situation

我正在试验光线行进,并且一直在关注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.

的正确用法

OpenTK 在 OpenTK.Mathematics 名称space.

中提供数据类型 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),
);

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

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

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

得到的矩阵
Matrix4 viewMatrix = Matrix4.LookAt(
    new Vector3(0.0f),
    center - eye,
    up
).Inverted();