乐闻世界logo
搜索文章和话题

What are matrix transformations in WebGL? What is the MVP matrix?

3月6日 21:58

Matrix Transformations in WebGL

In 3D graphics rendering, matrix transformations are used to convert vertices from one coordinate space to another. WebGL uses 4×4 matrices for various transformation operations.

Basic Transformation Matrices

1. Translation Matrix

Moves an object along the X, Y, and Z axes

shell
| 1 0 0 tx | | 0 1 0 ty | | 0 0 1 tz | | 0 0 0 1 |
javascript
function createTranslationMatrix(tx, ty, tz) { return new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1 ]); }

2. Scale Matrix

Scales an object along each axis

shell
| sx 0 0 0 | | 0 sy 0 0 | | 0 0 sz 0 | | 0 0 0 1 |

3. Rotation Matrix

Rotation around X axis

shell
| 1 0 0 0 | | 0 cosθ -sinθ 0 | | 0 sinθ cosθ 0 | | 0 0 0 1 |

Rotation around Y axis

shell
| cosθ 0 sinθ 0 | | 0 1 0 0 | | -sinθ 0 cosθ 0 | | 0 0 0 1 |

Rotation around Z axis

shell
| cosθ -sinθ 0 0 | | sinθ cosθ 0 0 | | 0 0 1 0 | | 0 0 0 1 |

MVP Matrix Explained

The MVP matrix is the product of three matrices used to transform vertices from model space to clip space:

MVP = P × V × M

M - Model Matrix

Purpose: Transforms vertices from model space (local space) to world space

javascript
// Model matrix = Translation × Rotation × Scale const modelMatrix = mat4.create(); mat4.translate(modelMatrix, modelMatrix, [x, y, z]); mat4.rotateX(modelMatrix, modelMatrix, angleX); mat4.rotateY(modelMatrix, modelMatrix, angleY); mat4.scale(modelMatrix, modelMatrix, [sx, sy, sz]);

Use cases:

  • Object position in the world
  • Object rotation angles
  • Object size scaling

V - View Matrix

Purpose: Transforms vertices from world space to camera space (view space)

javascript
// Create view matrix using lookAt function const viewMatrix = mat4.create(); mat4.lookAt( viewMatrix, [0, 0, 5], // Camera position (eye) [0, 0, 0], // Target point to look at [0, 1, 0] // Up direction vector );

Essence of view matrix:

  • Moves world coordinate origin to camera position
  • Rotates coordinate system so camera faces -Z direction
  • Camera is at origin, looking towards -Z axis

P - Projection Matrix

Purpose: Transforms vertices from camera space to clip space

Perspective Projection

Simulates human eye visual effect, objects appear smaller with distance

javascript
const projectionMatrix = mat4.create(); mat4.perspective( projectionMatrix, Math.PI / 4, // Field of view (FOV) canvas.width / canvas.height, // Aspect ratio 0.1, // Near plane 100.0 // Far plane );

Orthographic Projection

Maintains object size, commonly used in 2D games or CAD software

javascript
mat4.ortho( projectionMatrix, -2, 2, // Left, Right -2, 2, // Bottom, Top 0.1, 100 // Near, Far );

Coordinate Space Transformation Flow

shell
Model Space (Local Space) [Model Matrix M] World Space [View Matrix V] Camera Space (View Space) [Projection Matrix P] Clip Space [Perspective Division] Normalized Device Coordinates (NDC) [Viewport Transform] Screen Space

MVP Application in Vertex Shader

glsl
// Vertex shader attribute vec3 a_position; attribute vec3 a_color; uniform mat4 u_modelMatrix; uniform mat4 u_viewMatrix; uniform mat4 u_projectionMatrix; varying vec3 v_color; void main() { // Method 1: Apply three matrices separately // vec4 worldPos = u_modelMatrix * vec4(a_position, 1.0); // vec4 viewPos = u_viewMatrix * worldPos; // gl_Position = u_projectionMatrix * viewPos; // Method 2: Use pre-computed MVP matrix (recommended) mat4 mvp = u_projectionMatrix * u_viewMatrix * u_modelMatrix; gl_Position = mvp * vec4(a_position, 1.0); v_color = a_color; }

Matrix Calculation in JavaScript

javascript
// Using gl-matrix library import { mat4, vec3 } from 'gl-matrix'; class Camera { constructor() { this.projectionMatrix = mat4.create(); this.viewMatrix = mat4.create(); this.mvpMatrix = mat4.create(); } setPerspective(fov, aspect, near, far) { mat4.perspective(this.projectionMatrix, fov, aspect, near, far); } lookAt(eye, center, up) { mat4.lookAt(this.viewMatrix, eye, center, up); } getMVPMatrix(modelMatrix) { // MVP = P × V × M mat4.multiply(this.mvpMatrix, this.viewMatrix, modelMatrix); mat4.multiply(this.mvpMatrix, this.projectionMatrix, this.mvpMatrix); return this.mvpMatrix; } } // Usage example const camera = new Camera(); camera.setPerspective(Math.PI / 4, 16/9, 0.1, 100); camera.lookAt([0, 0, 5], [0, 0, 0], [0, 1, 0]); const modelMatrix = mat4.create(); mat4.translate(modelMatrix, modelMatrix, [1, 0, 0]); const mvp = camera.getMVPMatrix(modelMatrix); gl.uniformMatrix4fv(mvpLocation, false, mvp);

Common Issues and Considerations

1. Matrix Multiplication Order

Matrix multiplication is not commutative, order is crucial:

  • Correct: MVP = P × V × M, applied to vertex: MVP × vertex
  • Transformations applied first are on the right side of the multiplication chain

2. Row-major vs Column-major

  • WebGL uses column-major matrix storage
  • Third parameter transpose of gl.uniformMatrix4fv must be false

3. Homogeneous Coordinates

Using 4D vectors (x, y, z, w):

  • Vertex position: w = 1
  • Direction vector: w = 0 (not affected by translation)

4. Performance Optimization

  • Pre-compute MVP matrix on CPU instead of multiplying separately in shader
  • Use uniforms to pass pre-computed matrices
标签:WebGL