3D Math for Games
Every frame of a 3D game is a long chain of math: objects are placed in the world with transforms, viewed through a camera, projected onto the screen, lit using normals, moved with velocities, rotated with quaternions, and tested for hits with rays. Engines hide much of it behind components and editors, but the moment you write a camera controller, an aiming system, a shader, or a physics query, you are working directly with vectors, matrices, and coordinate spaces.
Most 3D math bugs are not hard math — they are convention bugs: multiplying transforms in the wrong order, mixing local and world space, assuming the wrong handedness or up axis, interpolating rotations as Euler angles, or forgetting to scale by frame time. This page covers the core tools and the conventions that trip people up.
TL;DR
- Vectors represent positions, directions, and velocities; the dot product measures alignment, the cross product gives a perpendicular.
- Objects move through coordinate spaces: local → world → view → clip → normalized device → screen.
- Engines differ in handedness and up axis; know your engine's conventions before porting math.
- Transform order matters: scale, then rotate, then translate (in the usual column-vector convention).
- Use quaternions for rotation and interpolation; keep Euler angles for editors and input.
- Mind projection and depth precision, transform normals correctly, scale motion by delta time, and watch float precision far from the origin.
Quick Example
Building a model matrix, projecting a point, measuring an angle, and rotating with a quaternion (NumPy, right-handed, column vectors):
Core Concepts
Vectors, Dot, and Cross
The sign of a dot product tells you whether something is in front of or behind you; the sign of a cross product's component tells you left or right.
Coordinate Spaces
Physics, gameplay, and AI usually work in world space; shaders move vertices through all of them. Name variables by space (posWorld, dirLocal) to avoid mixing them.
Handedness and Engine Conventions
Importers convert between tools, but hand-written math, shaders, and data from other tools must use the right convention. Check also whether matrices act on column vectors (M·v, composed right to left) or row vectors (v·M, composed left to right).
Transforms and Order
A transform matrix combines translation, rotation, and scale (TRS). With column vectors, T · R · S · v scales first, rotates second, translates last; reversing the order rotates the object around the world origin instead of its own. Parent–child hierarchies multiply transforms down the tree: world = parentWorld · childLocal.
Rotations: Euler Angles and Quaternions
Euler angles (pitch, yaw, roll) are intuitive for editors and player input but suffer from gimbal lock and blend poorly. Quaternions represent orientation without gimbal lock, compose by multiplication, and interpolate smoothly with slerp. Keep orientation as quaternions internally; accumulate player yaw and pitch as angles (clamping pitch) and convert to a quaternion each frame. See Robot Kinematics and Dynamics for the same mathematics applied to robots.
Projection and Depth
A perspective projection makes distant objects smaller and is defined by field of view, aspect ratio, and near and far planes; an orthographic projection keeps sizes constant (2D games, strategy views, UI). Depth buffer precision is distributed non-linearly — most precision sits near the near plane — so a tiny near plane causes z-fighting in the distance. Push the near plane out, or use reversed-Z with a floating-point depth buffer, which many engines now do. See OpenGL.
Normals
Surface normals must be transformed by the inverse transpose of the model matrix's upper 3×3, not the model matrix itself, or non-uniform scaling skews lighting. Renormalize after transforming and after interpolation in shaders. See Shader Programming.
Interpolation and Easing
Linear interpolation is mechanical; easing curves (smoothstep, cubic, spring damping) make motion feel natural. For framerate-independent smoothing toward a target, use exponential decay: value = lerp(target, value, exp(-rate * dt)), not a fixed fraction per frame.
Rays and Intersections
Raycasts — a point plus a direction — power shooting, mouse picking, line of sight, and ground detection. Core tests include ray–plane, ray–sphere, ray–box (axis-aligned bounding boxes with the slab method), and ray–triangle. Engines provide optimized physics queries; understanding the math helps with custom gameplay checks and debugging. See Game Physics.
Time and Precision
Multiply velocities by delta time so movement does not depend on frame rate, and use fixed timesteps for physics. Single-precision floats lose precision far from the origin — jittering cameras and physics in open worlds — so large worlds use origin rebasing or double-precision world coordinates, as in Unreal Engine 5's Large World Coordinates.
Best Practices
Name Spaces and Conventions Explicitly
Label positions and directions by space and document handedness, up axis, and matrix convention.
Prefer Quaternions for Orientation
Store and interpolate rotations as quaternions; convert to and from Euler angles only at the edges.
Visualize Vectors While Debugging
Draw debug lines for normals, directions, and rays; most math bugs are obvious when visible.
Make Motion Frame-Rate Independent
Scale motion and smoothing by delta time and run physics at a fixed step.
Common Mistakes
Wrong Multiplication Order
Per-Frame Smoothing Without Delta Time
Transforming Normals Like Positions
FAQ
What math do I need for 3D game development?
Vectors and their operations, matrices for transforms and projection, quaternions for rotation, basic trigonometry, and interpolation. Collision and physics add geometry and some calculus.
What is the dot product used for in games?
Measuring how aligned two directions are: facing and view-cone checks, projecting movement onto surfaces, and lighting calculations.
Why use quaternions instead of Euler angles?
Quaternions avoid gimbal lock, combine cleanly, and interpolate smoothly between orientations. Euler angles are easier for humans to read and edit.
What is the difference between left-handed and right-handed coordinates?
The direction of the third axis relative to the other two. Engines and tools choose different conventions, so data and math must be converted when moving between them.
What causes z-fighting?
Two surfaces with nearly the same depth competing for the same pixels, made worse by limited depth-buffer precision — especially with a very small near plane. Increasing the near plane distance or using reversed-Z depth helps.
Related Topics
- Game Development — Building games
- Shader Programming — Math on the GPU
- Game Physics — Collisions, rays, and rigid bodies
- OpenGL — Transforms and projection in a graphics API
- Probability and Linear Algebra for Computing — Vectors and matrices
- Robot Kinematics and Dynamics — The same transforms applied to robots