What normalize() does (and why Three.js raycasting needs it)
Source: Dev.to
What normalize() does
normalize() makes a vector exactly 1 unit long while keeping its direction unchanged.
const rayDirection = new THREE.Vector3(10, 0, 0); // length = 10
rayDirection.normalize(); // → (1, 0, 0)
Mathematically, normalization divides a vector by its length:
[ \text{normalized} = \frac{v}{|v|} ]
const v = new THREE.Vector3(10, 0, 0);
console.log(v.length()); // 10
v.normalize();
console.log(v.length()); // 1
The direction stays the same; only the magnitude changes.
Why Three.js raycasting needs a normalized direction
Distance calculations assume unit length
When a ray hits something, Three.js computes how far along the ray the intersection occurs. Those distance values are meaningful only if the direction vector has length 1. If the direction were length 10, the internal math would scale everything incorrectly, and distances would no longer correspond to world units.
Intersection formulas assume a unit vector
Many ray‑geometry intersection formulas (and the Three.js documentation) require the direction vector to be a unit vector. Skipping normalization leads to undefined behavior, even if it sometimes appears to work.
How to use normalize() correctly
Typical ray‑casting setup
const rayOrigin = new THREE.Vector3(-3, 0, 0);
const rayDirection = new THREE.Vector3(10, 0, 0);
rayDirection.normalize(); // ensure unit length
const raycaster = new THREE.Raycaster(rayOrigin, rayDirection);
- Origin: starts at
x = -3 - Direction: points straight right along the X axis, now normalized
Calling:
raycaster.intersectObjects(scene.children);
will return intersection distances that are correct and consistent.
Preserve the original vector (if needed)
const original = new THREE.Vector3(10, 0, 0);
const direction = original.clone().normalize(); // original stays unchanged
Controlling the ray’s range
Do not scale the direction vector to limit range. Instead set the raycaster’s near and far properties:
raycaster.near = 0;
raycaster.far = 100; // limit to 100 world units
Keep the direction normalized; let the raycaster handle the distance limits.
Visual analogy
Think of a direction vector as a compass needle.
- Before normalization: a 10‑meter‑long arrow.
- After normalization: a 1‑meter‑long arrow pointing the same way.
Three.js raycasting expects the 1‑meter version so that all distance calculations remain clean and predictable.