The cross product of two 3D vectors a and b produces a third vector that is perpendicular to both. It is only defined in 3D (and 7D, though the 7D case has no practical use in games).
a × b = ┌ ay·bz - az·by ┐
│ az·bx - ax·bz │
└ ax·by - ay·bx ┘
A memory aid — expand along the top row of this determinant:
a × b = det ┌ î ĵ k̂ ┐
│ ax ay az │
└ bx by bz ┘
= î(ay·bz - az·by) - ĵ(ax·bz - az·bx) + k̂(ax·by - ay·bx)
Mnemonic: the result's x = (ay·bz - az·by), cycling through y→z, z→x, x→y. Each component skips its own axis.
2
Geometric Interpretation
The cross product a × b has two geometric properties:
Direction
The result is perpendicular to both a and b. If a and b define a plane, the cross product is the plane's normal vector.
Magnitude
The magnitude equals the area of the parallelogram formed by a and b:
‖a × b‖ = ‖a‖ · ‖b‖ · sin θ
where θ is the angle between a and b.
‖a × b‖ = 0 when a and b are parallel (sin 0° = 0)
‖a × b‖ = ‖a‖·‖b‖ when a and b are perpendicular (sin 90° = 1)
If ‖a × b‖ ≈ 0, the two vectors are nearly parallel and the cross product is unreliable as a normal. This happens when computing a face normal from two edges that are almost collinear — always check for this in mesh-processing code.
3
Properties
Anti-Commutativity
Swapping the operands negates the result:
a × b = -(b × a)
This means the direction of the perpendicular vector flips. Consistent operand order is critical for consistent normal orientation.
Standard Basis Cross Products
î × ĵ = k̂ ĵ × k̂ = î k̂ × î = ĵ
ĵ × î = -k̂ k̂ × ĵ = -î î × k̂ = -ĵ
Magnitude and Dot Product Relationship
The dot and cross products together give the full picture of the angle between two vectors:
a · b = ‖a‖·‖b‖·cos θ (0 when perpendicular)
‖a × b‖ = ‖a‖·‖b‖·sin θ (0 when parallel)
Perpendicularity Check
The result of a cross product is always perpendicular to both inputs. You can verify:
(a × b) · a = 0
(a × b) · b = 0
Distributive Over Addition
a × (b + c) = (a × b) + (a × c)
NOT Associative
a × (b × c) ≠ (a × b) × c in general
4
The Right-Hand Rule
In a right-handed coordinate system, use your right hand to determine the direction of a × b:
Point your fingers in the direction of a
Curl them toward b (through the smaller angle)
Your extended thumb points in the direction of a × b
In a left-handed system (Unreal, DirectX), use the left hand — or equivalently, the result of a × b points in the opposite direction compared to a right-handed system. This is why the same cross product code for computing normals can produce inside-out results when switching between OpenGL and DirectX coordinates.
5
Applications in Game Development
Surface Normals
Given a triangle with vertices P₁, P₂, P₃ (in counter-clockwise order for a right-handed system):
e₁ = P₂ - P₁
e₂ = P₃ - P₁
n = normalize(e₁ × e₂)
This normal points "outward" from the front face and is used in lighting, backface culling, and collision response.
Camera Right Vector
When building a view matrix, the camera's right vector is perpendicular to both the forward vector and the world up:
right = normalize(forward × worldUp)
up = right × forward (re-orthogonalize to avoid drift)
Rotation by 90° Around an Axis
Crossing a unit vector with one of the cardinal axes rotates it 90° around that axis — useful for quick perpendicular finding without trig:
perp = normalize(v × (1, 0, 0)) (if v is not parallel to X)
perp = normalize(v × (0, 1, 0)) (fallback if v is near X)
Torque and Angular Momentum (Physics)
Torque τ = r × F (the cross product of the moment arm and force). Angular momentum L = r × p. These are fundamental to rigid-body physics engines.
Area of a Triangle
Area = ‖e₁ × e₂‖ / 2
Checking Triangle Winding
The sign of the z-component of e₁ × e₂ tells you if vertices are wound clockwise or counter-clockwise in screen space — used for backface culling.
6
Exercises
1. Compute a Cross Product
Compute a × b for a = (1, 0, 0) and b = (0, 1, 0).
a × b = (0·0 - 0·1, 0·0 - 1·0, 1·1 - 0·0) = (0, 0, 1). This is k̂ — the Z axis. Matches the right-hand rule: fingers point X, curl to Y, thumb points Z.
2. Triangle Normal
A triangle has vertices A = (0,0,0), B = (1,0,0), C = (0,1,0). Find the normalized surface normal.
e₁ = B - A = (1,0,0). e₂ = C - A = (0,1,0). e₁ × e₂ = (0,0,1). Already unit length. Normal = (0,0,1) — pointing up the Z axis.
3. Perpendicularity Verification
Verify that (a × b) · a = 0 for a = (2, 3, 1) and b = (1, -1, 4).
How do you compute a camera's right vector if you know the forward direction and world up?
right = normalize(forward × worldUp). Then re-orthogonalize up = right × forward (not worldUp, because forward may not be perfectly perpendicular to worldUp, especially when looking straight up/down). This gives you an orthonormal camera basis without any trig functions.
Interview Question
What does the magnitude of a cross product represent, and why does it go to zero when vectors are parallel?
‖a × b‖ = ‖a‖·‖b‖·sin θ — it equals the area of the parallelogram spanned by a and b. When vectors are parallel (θ = 0° or 180°), sin θ = 0, so they span no area and the cross product is the zero vector. This is also why you can't compute a meaningful normal for a degenerate triangle (where two edges are collinear).
Interview Question
How does the cross product behave differently in a left-handed vs right-handed coordinate system?
The mathematical formula is the same, but the physical direction of the result flips. X × Y = +Z in a right-handed system, but X × Y = −Z in a left-handed system. When porting rendering code between OpenGL (RH) and DirectX (LH), cross-product-derived normals and camera vectors often need to be negated.