Random Point on Sphere Surface in Three.js
Generating a pseudo-random point on the surface of a sphere is a common requirement in 3D graphics, often used for positioning particles, spawning objects, or calculating lighting effects. This article demonstrates how to achieve a uniform distribution on a sphere’s surface using Three.js, covering both the quick modern shorthand method and the manual mathematical approach using Three.js utility functions.
Method 1:
Using Vector3.randomDirection() (Recommended)
The easiest and most efficient way to get a random point on a unit
sphere (a sphere with a radius of 1) is to use the built-in
randomDirection() method of the THREE.Vector3
class. This method automatically calculates a random, uniformly
distributed unit vector.
import * as THREE from 'three';
// Create a vector to store the coordinates
const point = new THREE.Vector3();
// Generate a random point on a sphere of radius 1
point.randomDirection();
// Scale the point if you need a specific sphere radius (e.g., radius of 5)
const radius = 5;
point.multiplyScalar(radius);
console.log(`X: ${point.x}, Y: ${point.y}, Z: ${point.z}`);Method
2: Manual Spherical Coordinates with THREE.MathUtils
If you are using an older version of Three.js that lacks
randomDirection(), or if you need to restrict the point
generation to a specific portion of the sphere (like a dome or
hemisphere), you can calculate the point manually using spherical
coordinates and THREE.MathUtils.
To ensure the points are uniformly distributed across the surface without clumping at the poles, you must distribute the cosine of the polar angle (\(\phi\)) rather than the angle itself.
import * as THREE from 'three';
function getRandomSpherePoint(radius) {
const point = new THREE.Vector3();
// Generate uniform random variables between 0 and 1
const u = Math.random();
const v = Math.random();
// Theta is the azimuthal angle (around the Y axis)
const theta = u * 2.0 * Math.PI;
// Phi is the polar angle (from the positive Y axis)
// Using acos ensures uniform distribution across the surface area
const phi = Math.acos(2.0 * v - 1.0);
// Set coordinates using Three.js built-in spherical converter
point.setFromSphericalCoords(radius, phi, theta);
return point;
}
// Example usage
const targetRadius = 10;
const randomPoint = getRandomSpherePoint(targetRadius);Understanding the Mathematics
In Method 2, simply picking a random angle for \(\phi\) between \(0\) and \(\pi\) results in “polar crowding,” where
points bunch up at the top and bottom poles of the sphere. By mapping a
flat random value \(v\) to
Math.acos(2.0 * v - 1.0), you compensate for the narrowing
circumference of the sphere near the poles, resulting in an
mathematically perfect, uniform distribution.