В библиотеке Three.js для работы с преобразованиями в 3D-пространстве используются объекты Matrix3 и Matrix4. Они обеспечивают возможность представления, комбинирования и применения линейных преобразований, включая повороты, масштабирование, перенос и перспективные преобразования. Основное отличие заключается в размерности: Matrix3 — 3×3, обычно используется для нормалей и двумерных преобразований, Matrix4 — 4×4, применяются для 3D-трансформаций с переносом.
Matrix3 создаётся стандартно через конструктор:
const m3 = new THREE.Matrix3();
По умолчанию создаётся единичная матрица. Для явной установки
значений можно использовать метод set:
m3.set(
1, 2, 3,
4, 5, 6,
7, 8, 9
);
Для Matrix4 подход аналогичный:
const m4 = new THREE.Matrix4();
m4.set(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
Единичная матрица создаётся по умолчанию и может быть восстановлена
через identity():
m4.identity();
Умножение матриц позволяет комбинировать преобразования. В Three.js существуют методы multiply и premultiply:
const a = new THREE.Matrix4().makeRotationX(Math.PI / 4);
const b = new THREE.Matrix4().makeTranslation(10, 0, 0);
const result = new THREE.Matrix4();
result.multiplyMatrices(a, b); // result = a * b
multiply применяется справа:
this = this * m. premultiply — слева:
this = m * this.
Для Matrix3 синтаксис аналогичен:
const m1 = new THREE.Matrix3().set(
1, 2, 3,
0, 1, 4,
5, 6, 0
);
const m2 = new THREE.Matrix3().set(
-1, 2, 0,
0, 1, 3,
4, 0, 1
);
m1.multiply(m2); // m1 = m1 * m2
Важно учитывать порядок умножения: в 3D-преобразованиях порядок матриц критически влияет на результат.
Инверсия позволяет «отменить» преобразование. Для
Matrix3 используется метод invert():
const m3 = new THREE.Matrix3().set(
2, 0, 1,
1, 1, 0,
0, 0, 1
);
const m3Inverse = new THREE.Matrix3();
m3Inverse.copy(m3).invert();
Для Matrix4 также используется
invert():
const m4 = new THREE.Matrix4().makeRotationY(Math.PI / 2);
const m4Inverse = new THREE.Matrix4();
m4Inverse.copy(m4).invert();
При инверсии важно проверять, что матрица невырожденная. Если
определитель равен нулю, метод возвращает null или
выбрасывает предупреждение.
Транспонирование меняет строки и столбцы матрицы местами. В Three.js
выполняется через transpose():
const m3 = new THREE.Matrix3().set(
1, 2, 3,
4, 5, 6,
7, 8, 9
);
m3.transpose();
Для Matrix4 принцип аналогичный:
const m4 = new THREE.Matrix4().set(
1, 0, 0, 0,
0, 1, 2, 0,
0, 3, 4, 0,
0, 0, 0, 1
);
m4.transpose();
Транспонирование особенно полезно при работе с нормалями: при применении нелинейного масштабирования к объекту нормали преобразуются с помощью транспонированной обратной матрицы.
Matrix3 применяется к Vector3 для нормалей и 3D-векторов без переноса:
const normal = new THREE.Vector3(1, 0, 0);
normal.applyMatrix3(m3);
Matrix4 учитывает перенос и полное 3D-преобразование:
const position = new THREE.Vector3(1, 2, 3);
position.applyMatrix4(m4);
Для комбинированных трансформаций матрица объекта сцены обычно
строится через методы makeRotationX,
makeTranslation, makeScale и умножается друг
на друга для получения итоговой матрицы объекта.
normalMatrix), чтобы ускорить расчёты освещения.const normalMatrix = new THREE.Matrix3();
normalMatrix.setFromMatrix4(m4);
const m = new THREE.Matrix4()
.makeRotationX(Math.PI / 2)
.multiply(new THREE.Matrix4().makeTranslation(5, 0, 0))
.scale(new THREE.Vector3(2, 2, 2));
Matrix3 с транспонированием и инверсией.Three.js обеспечивает полное управление матрицами через удобные методы для создания, умножения, инверсии и транспонирования, что позволяет эффективно работать с любыми линейными и аффинными преобразованиями в 3D-пространстве.