У меня есть приложение WebGL, которое отображает массив кубов, каждый с разной высотой. Чтобы определить их размер, я использую матрицу преобразования для масштабирования кубов. У меня также есть камера, которую можно перемещать с помощью клавиатуры.
Для расчета матрицы модели я использую следующий код:
let matrix = matrix4Identity();
matrix = matrix4Translate(matrix, this.position);
matrix = matrix4Rotate(matrix, this.rotation[0], [1, 0, 0]);
matrix = matrix4Rotate(matrix, this.rotation[1], [0, 1, 0]);
matrix = matrix4Rotate(matrix, this.rotation[2], [0, 0, 1]);
matrix = matrix4ScaleWithVector(matrix, this.scale);
и для вычисления матрицы вида я использую этот код:
let matrix = matrix4Identity();
matrix = matrix4Rotate(matrix, camera.rotation[0], [1, 0, 0]);
matrix = matrix4Translate(matrix, [camera.position[0], camera.position[1], camera.position[2]]);
return matrix4Inverse(matrix);
и это код вершинного шейдера, который я использую:
attribute vec3 vertices;
attribute vec3 normals;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
void main(void) {
vec4 worldPosition = modelMatrix * vec4(vertices, 1.0);
vec4 modelPosition = viewMatrix * worldPosition;
gl_Position = projectionMatrix * modelPosition;
}
Однако, если вы переместите камеру, кубы будут переведены. Поэтому, когда вы перемещаете камеру вверх, Y-положение кубиков меняется (визуально). Кроме того, если вы поворачиваете камеру, она вращает кубики вокруг своей оси X.
Однако, если я уберу преобразование масштаба в матрице модели, блоки больше не меняют свое положение при перемещении камеры.
Вы можете увидеть результат проекта здесь. https://renuo.github.io/stayOFline/
Используйте WASD для перемещения по осям X и Z, R для перемещения вверх и F для перемещения вниз и o + l для вращения камеры.
Обновление:
При первом повороте и повороте камеры я получаю следующее поведение:
![rotating camera](https://i.stack.imgur.com/rHPGG.gif)
Вы можете просмотреть весь код в https://github.com/renuo/stayOFline/tree/gh-pages