如何从 webgl 中的 forward/left/up 向量创建投影矩阵

How to create projection matrix from forward/left/up vectors in webgl

我有 webgl 代码,它使用 3 个旋转角度来旋转相机,然后 returns 向前、向左和向上向量。它工作正常:

function matrixFromPositionAndRotation(aPosition, aRotX, aRotY, aRotZ) {
    var matrix = mat4.create();
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 2000.0, matrix);

    mat4.rotateX(matrix, aRotX);
    mat4.rotateY(matrix, aRotY);
    mat4.rotateZ(matrix, aRotZ);

    mat4.translate(matrix, aPosition);

    return {
        matrix: matrix,
        forward: vec3.create([matrix[2], matrix[6], matrix[10]]),
        left: vec3.create([matrix[0], matrix[4], matrix[8]]),
        up: vec3.create([matrix[1], matrix[5], matrix[9]])
    };
}        

然而我想反其道而行之。我知道位置、前向、左向和向上向量,我想计算投影矩阵。我尝试了相反的方法,但它不起作用:

function matrixFromPositionAndVectors(aPosition, aForward, aLeft, aUp) {
    var matrix = mat4.create();
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 2000.0, matrix);

    mat4.translate(matrix, aPosition);

    matrix[0] = aLeft[0];
    matrix[4] = aLeft[1];
    matrix[8] = aLeft[2];

    matrix[2] = aForward[0];
    matrix[6] = aForward[1];
    matrix[10] = aForward[2];

    matrix[1] = aUp[0];
    matrix[5] = aUp[1];
    matrix[9] = aUp[2];

    return {
        matrix: matrix
    };
}     

您可能需要将您拥有的矩阵乘以您正在创建的矩阵

    mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 2000.0, matrix);

    mat4.translate(matrix, aPosition);

    const m = [
      ...aLeft, 0,
      ...aUp, 0,
      ...aForward, 0,
      0, 0, 0, 1,
    ];
    mat4.multiply(matrix, matrix, m);

请注意,我希望 aLeft 实际上是 aRight。换句话说,考虑 identiy

[
  1, 0, 0, 0,    // points right (x = 1)
  0, 1, 0, 0,    // points up    (y = 1)
  0, 0, 1, 0,    // points ??    (z = 1) If you define +Z as forward.
  0, 0, 0, 1,
]

对于相机矩阵,-Z 通常是向前的。

我还猜测您不熟悉 WebGL (OpenGL) 矩阵。他们称行 "columns"

[
  1, 0, 0, 0,    // column 0
  0, 1, 0, 0,    // column 1
  0, 0, 1, 0,    // column 2
  0, 0, 0, 1,    // column 3
]

xAxis 在这里

[
  Xx, Xy, Xz,  0,    // column 0 (xAxis)
   0,  1,  0,  0,    // column 1
   0,  0,  1,  0,    // column 2
   0,  0,  0,  1,    // column 3
]

虽然您当然没有post您的数学图书馆。 mat4 不是任何标准的一部分,因此在没有看到它的情况下我们无法知道它在做什么,只能猜测。

你可以测试一下。这样做

console.log(mat4.translate(mat4.create(), [11, 22, 33]));

你可能会得到

[
   1, 0, 0, 0,
   0, 1, 0, 0,
   0, 0, 1, 0,
  11,22,33, 1,
]