在WebGL中,视图矩阵(View Matrix)定义了观察者(相机)在世界空间中的位置和方向,它实现了从世界坐标系到相机坐标系的转换。
视图矩阵是一个4x4的矩阵,用于:
视图矩阵通常通过以下步骤构建:
数学上可以表示为:
ViewMatrix = RotationMatrix × TranslationMatrix
注意:这个顺序与模型矩阵相反
最常用的方法是使用lookAt
函数,它需要三个参数:
// 使用gl-matrix库
import {mat4} from 'gl-matrix';
const viewMatrix = mat4.create();
const eye = [0, 0, 5]; // 相机位置
const target = [0, 0, 0]; // 观察目标
const up = [0, 1, 0]; // 上方向向量
mat4.lookAt(viewMatrix, eye, target, up);
如果不使用矩阵库,可以手动计算:
function createViewMatrix(eye, target, up) {
const zAxis = normalize(subtractVectors(eye, target)); // 相机朝向
const xAxis = normalize(cross(up, zAxis)); // 右向量
const yAxis = normalize(cross(zAxis, xAxis)); // 实际上向量
return [
xAxis[0], xAxis[1], xAxis[2], -dot(xAxis, eye),
yAxis[0], yAxis[1], yAxis[2], -dot(yAxis, eye),
zAxis[0], zAxis[1], zAxis[2], -dot(zAxis, eye),
0, 0, 0, 1
];
}
const viewMatrix = mat4.create();
mat4.lookAt(viewMatrix, [0, 1, 5], [0, 0, 0], [0, 1, 0]);
const uViewMatrix = gl.getUniformLocation(program, 'uViewMatrix');
gl.uniformMatrix4fv(uViewMatrix, false, viewMatrix);
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
void main() {
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aPosition, 1.0);
}
实现第一人称相机控制:
// 相机参数
let cameraPosition = [0, 0, 5];
let cameraTarget = [0, 0, 0];
let upVector = [0, 1, 0];
function updateViewMatrix() {
mat4.lookAt(viewMatrix, cameraPosition, cameraTarget, upVector);
gl.uniformMatrix4fv(uViewMatrix, false, viewMatrix);
}
// 移动相机
function moveCamera(dx, dy, dz) {
cameraPosition[0] += dx;
cameraPosition[1] += dy;
cameraPosition[2] += dz;
updateViewMatrix();
}
// 旋转相机(绕Y轴)
function rotateCameraY(angle) {
// 实现旋转逻辑...
updateViewMatrix();
}
为什么物体朝相反方向移动?
如何实现相机跟随?
如何实现俯仰和偏航?
视图矩阵是3D图形中实现相机控制的核心组件,理解它的工作原理对于实现各种相机行为至关重要。