I'm using three.js to display a globe. At first, the image is low-quality, and as a user zooms in, the images become higher quality. This is done using tiling. Each tile is 256px x 256px. For the lowest zoom, there are only a couple tiles, and for the largest, there are thousands.
The issue is that the images are still low quality, even at the highest zoom. I think this is because of the canvas I'm using. It's 2000px x 1000px. Even if I increase this canvas, the image at its highest quality is 92160px x 46080px, which is too large of a canvas to render in most browsers.
What approach can I use to display tiles at high quality, but not have a huge canvas? Is using a canvas the right approach? Thanks!
I figured out a way of doing it, though I'm not sure it's a great approach. For every tile that needs to be displayed, I create a sphere. I make the sphere match the size of the tile on the map using phiStart
, phiLength
, thetaStart
, thetaLength
. Then I create a 256px x 256px canvas, put the tile image on the canvas, and put the canvas on the tile. Essentially I'm placing parts of spheres on top of a low-resolution sphere, which is the sphere that loads when the page is loaded.
I calculated the four variables by taking a whole sphere (which is 2*Pi
for each variable), then multiplying by the percentage of the sphere I want to fill. Here is the four variables:
// `sphereCanvasWidth` is the width of the low-resolution sphere's canvas
// `canvasX` is the top left pixel of where you want to draw on the canvas
phiStart = (2 * Pi) * (canvasX / sphereCanvasWidth)
// `numPixelsTileX` is the number of pixels the canvas should cover
phiLength = (2 * Pi) * (numPixelsTileX / sphereCanvasWidth)
// `canvasY` is the bottom left pixel of where you want to draw on the canvas
thetaStart = (2 * Pi) * (canvasY / sphereCanvasWidth)
// `numPixelsTileY` is the number of pixels the canvas should cover
phiLength = (2 * Pi) * (numPixelsTileY / sphereCanvasWidth)
For example, if I want to fill the top left 1/4 of the sphere, it'd be:
phiStart = 0
phiLength = (2 * Pi) * .25
thetaStart = 0
thetaLength = (2 * Pi) * .25
The three.js documentation has a sphere you can test the variables on. Here's what the example above generates: