Drawing curves on WebGL Globe using THREE.js and D3

Young (xiaoyang) Zhao
2 min readNov 11, 2017

This tutorial shows how to draw curves on a WebGL Globe.

Step 1: Create an interactive 3D Globe

This is not the focus of this tutorial. There are some differences between this tutorial and the original WebGL Globe:

  1. Use ES6
  2. Use hammer.js for easier event handling
  3. All the meshes are added to a root mesh. Mouse drag events rotate the root mesh instead of the camera. This simplifies the logic to calculate rotations.

Step 2: Draw curve to 3D Globe

A 3D curve consists of a start and end point, and one or more middle control points. THREE.js provides two 3D curve methods: QuadraticBezierCurve3 and CubicBezierCurve3. Here we want to use CubicBezierCurve3 because it has 2 control points, meaning that we have more control on the curvature.

Image credit: https://stackoverflow.com/a/16901608

The input is an array of geolocations, i.e., latitude and longitude coordinates:

const coords = [ 
[ startLat, startLng, endLat, endLng ],
[ startLat, startLng, endLat, endLng ],
...
];

First we convert these coordinates into 3D points on the globe/sphere:

const points = [ 
[ start, mid1, mid2, end ],
[ start, mid1, mid2, end ],
...
];

With the start, end and 2 middle control points, we can use CubicBezierCurve3 to construct a 3D spline:

const spline = new THREE.CubicBezierCurve3(start, mid1, mid2, end);

Here is the complete logic:

Here is the diagram:

To adjust the curvature of the spline, change the position of the 2 middle control points (currently at 0.25 and 0.75 along the curve) and the logic to calculate altitude.

With this spline, you can draw a 3D curve using THREE.Geometry (or THREE.BufferGeometry) and add it to a THREE.Line. Alternately, if you want to add some thickness to the path, use THREE.TubeGeometry(or THREE.TubeBufferGeometry) and add it to a THREE.Mesh. The benefit of Buffer geometry is that you can use the setDrawRange to animate the paths.

Here is the complete source code for this tutorial on stackblitz:

https://stackblitz.com/edit/webgl-globe-1

--

--