Как создать матрицу проекции из векторов вперед / влево / вверх в webgl - PullRequest
0 голосов
/ 04 октября 2019

У меня есть код webgl, который использует 3 угла поворота для поворота камеры, а затем возвращает векторы вперед, влево и вверх. Работает нормально:

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
    };
}     

1 Ответ

1 голос
/ 05 октября 2019

Вам, вероятно, нужно умножить матрицу, которую вы имеете, на ту, которую вы создаете

    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. Другими словами, рассмотрим идентификатор

[
  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). Они называют строки «столбцами»

[
  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
]

Хотя, конечно, вы не опубликовали свою математическую библиотеку. 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,
]
...