Three.js Globe: Building an Interactive 3D Earth
A Three.js globe starts as a textured sphere (a SphereGeometry with an equirectangular Earth texture map), with data points and connection arcs plotted onto its surface by converting latitude/longitude coordinates to 3D positions with spherical-to-Cartesian math. This is the technique behind every "interactive data globe" visualization on the web.
The base sphere
A globe is a SphereGeometry with a texture mapped onto it: a day-map Earth texture at minimum, often layered with a normal map (for terrain bump) and a specular/roughness map (oceans reflect differently than land). A separate, slightly larger transparent sphere with a Fresnel-based glow shader is the common technique for the soft atmospheric rim visible around most globe visualizations. It's a cheap effect that adds significant perceived polish.
Rotation is usually just mesh.rotation.y += delta * speed for a slow idle spin, paused on user drag via OrbitControls or custom pointer handling.
Converting latitude/longitude to 3D positions
Every data point or city marker needs converting from latitude/longitude to a 3D position on the sphere's surface, using the standard spherical-to-Cartesian formula:
function latLngToVector3(lat, lng, radius) {
const phi = (90 - lat) * (Math.PI / 180)
const theta = (lng + 180) * (Math.PI / 180)
return new THREE.Vector3(
-radius * Math.sin(phi) * Math.cos(theta),
radius * Math.cos(phi),
radius * Math.sin(phi) * Math.sin(theta)
)
}
The sign and offset conventions (the - and +180) depend on how your texture is UV-mapped. If points appear mirrored or rotated relative to the texture, this is almost always where to look first, not the data itself.
Animated connection arcs between points
The "flight path" arcs common in globe visualizations are QuadraticBezierCurve3 or CubicBezierCurve3 paths between two surface points, with a control point lifted above the surface (along the midpoint's normal) so the arc curves outward rather than cutting straight through the sphere. Animate them by progressively revealing the curve (drawing more of its length over time) or by animating a small sprite/point moving along the curve's getPoint(t). Both read as "data flowing" far more effectively than a static line.
See it in production
Browse the full showcase →Code
Learn this properly
Learn Practical TSL
Your First Node Material
The Fresnel glow technique used for the globe's atmosphere is built with node materials.
Frequently asked questions
How do I plot data points on a Three.js globe?
Convert each point's latitude/longitude to a 3D position using the standard spherical-to-Cartesian formula, then place a marker mesh (or point in a THREE.Points system for many markers) at that position on the sphere's surface.
How do I add the glowing atmosphere effect to a Three.js globe?
A separate, slightly larger sphere with a Fresnel-based shader (a custom ShaderMaterial or TSL node material) rendered with backface culling reversed (THREE.BackSide) and additive or alpha blending: brighter at the silhouette edge, transparent facing the camera directly.
Why are my globe data points in the wrong place?
Almost always a sign/offset mismatch in the latitude/longitude-to-3D conversion relative to how your Earth texture is UV-mapped. Check the formula's sign conventions against your specific texture rather than assuming the data is wrong.
Keep reading
Sky & Clouds
Three.js scenes get a sky one of three ways: a static skybox/environment map for the fastest setup, the built-in procedu…
Particles
Three.js particle systems are built with THREE.Points: a single geometry holding thousands of positions, rendered as cam…
WebGPU vs WebGL
WebGPU is the successor to WebGL: a lower-level, more modern graphics API that exposes compute shaders and reduces CPU o…
All Three.js Guides
Back to the guides hub.