2016-04-22 5 views
0

У меня возникают проблемы с отображением трех декартовых плоскостей в 3D, когда они вращают плоскости, растягиваются в одном направлении (ось z, синий) и сжаты в другом (по оси x , красный), как эти изображения, показывающие вращение вокруг оси у:Webgl: Вращающийся объект искажается по осям

45 градусов:

95 градусов:
enter image description here

135 градусов: enter image description here

рассчитать перспективную матрицу, с mat4.perspective из библиотеки GL-матрицы:

mat4.perspective(this.pMatrix_, this.vFieldOfView_, this.aspect_, this.near_, this.far_); 

со значениями:

private near_ = 0.1; 
private far_ = 1000.0; 
private vFieldOfView_ = 60.0 * Math.PI/180; 

Vertex Shader:

void main(void) { 
    gl_Position = uProjection * uView * uTransform * vec4(aVertexPosition, 1.0); 
} 

Матрица представления преобразует объект 2.0 единиц в сторону от камеры.

let t = new Mat4(); 
t.array[12] = v.x; 
t.array[13] = v.y; 
t.array[14] = v.z; 

я повернуть плоскости вокруг оси у с помощью матрицы, сформированной из этого кода:

// identity matrix already set 
let rad = angle * Math.PI/180; 
r.array[0] = Math.cos(rad); 
r.array[2] = Math.sin(rad); 
r.array[8] = -1.0 * Math.sin(rad); 
r.array[10] = Math.cos(rad); 

И я умножить три преобразование матрицы объекта в следующем порядке: вращения * перевод * масштаб. Использовал кватернионы для обработки поворотов, но они были так же искажены, поэтому вернулись к использованию матриц вращения и сохранили простоту вращения на одной оси. Похоже, я делаю некоторый шаг умножения в неправильном порядке или не правильно использую перспективную матрицу или неправильно признал знак.

Update:

Просто для уточнения на значении некоторых матриц в вершинном шейдере:

uProjection = pMatrix_ = значение, полученное из mat.perspective (...).

uView = [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, -2.0, 0, 0, 0, 1], т.е. матрица, переведенная на 2 единицы по оси z ,

В этом примере uTransform должна быть идентификационной матрицей.

Обновление2:

uView был на самом деле [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -2,0, 1]

+0

Почему 'новый Mat4()' вместо 'mat4.create()', если вы используете библиотеку gl-matrix? –

+1

Поскольку у вас есть такие отдельные матрицы, может оказаться полезным показать нам значение каждой матрицы. Похоже, что какой-то знак, возможно, куда-то перевернулся, поэтому я обычно придерживаюсь существующих математических библиотек, таких как gl-matrix, вместо прямого доступа к массиву. –

+0

Работает в машинописном тексте и имеет класс Mat4, чтобы упростить проверку типов, в основном это просто Float32Array (16) с оценщиками. Используйте gl-matrix для выполнения вычислений, таких как матрица перспективы. – dppower

ответ

1

Вы перенести свою матрицу просмотра. У вас есть

1 0 0 0 
0 1 0 0 
0 0 1 0 
0 0 -2 1 

Вы хотите:

1 0 0 0 
0 1 0 0 
0 0 1 -2 
0 0 0 1 

Эта ошибка никогда бы не произошло, если бы вы просто застряли с ГЛ-матрицей и используется mat4.translate(). Вот почему я не использую прямой доступ к массиву для создания матрицы, ее слишком легко заглушить.

Помните, что матрицы OpenGL хранятся как массив векторов столбцов. Таким образом, индексы идут так:

0 4 8 12 
1 5 9 13 
2 6 10 14 
3 7 11 15 
+0

Я ошибся в обновлении, я поставил матрицу представления в неправильном порядке, и я специально проверил значения этой матрицы сегодня. Я пошел и использовал функцию mat4.rotateY из gl-матрицы, и это действительно работает, поэтому я правильно выполнил перевод и перспективу, но неправильно получил матрицу вращения. Нужно пойти и изучить его еще немного. – dppower

0

Я узнал, где я буду неправильно с моей реализацией, это было с матричным умножением. Правильный код:

static multiply(a: Mat4, b: Mat4, out: Mat4) { 

    let a11 = a.array[0], a12 = a.array[1], a13 = a.array[2], a14 = a.array[3], 
     a21 = a.array[4], a22 = a.array[5], a23 = a.array[6], a24 = a.array[7], 
     a31 = a.array[8], a32 = a.array[9], a33 = a.array[10], a34 = a.array[11], 
     a41 = a.array[12], a42 = a.array[13], a43 = a.array[14], a44 = a.array[15]; 

    for (let i = 0; i < 16; i += 4) { 
     let b1 = b.array[i], b2 = b.array[i + 1], b3 = b.array[i + 2], b4 = b.array[i + 3]; 
     out.array[i] = b1 * a11 + b2 * a21 + b3 * a31 + b4 * a41; 
     out.array[i + 1] = b1 * a12 + b2 * a22 + b3 * a32 + b4 * a42; 
     out.array[i + 2] = b1 * a13 + b2 * a23 + b3 * a33 + b4 * a43; 
     out.array[i + 3] = b1 * a14 + b2 * a24 + b3 * a34 + b4 * a44; 
    } 
}; 
+0

OpenGL/WebGL не используют транспонирование матрицы, если вы не попросите его, передав «GL_TRUE» параметру транспонирования 'glUniformMatrix'. OpenGL использует обычные матрицы, как и все остальные. –

Смежные вопросы