tentone / geo-three

Tile based geographic world map visualization library for threejs
https://tentone.github.io/geo-three/docs/
MIT License
647 stars 105 forks source link

Project mercator tiles on to sphere #74

Open cmurphy23 opened 1 week ago

cmurphy23 commented 1 week ago

Hi, thanks for this great project.

Since mercator projected tiles don't map on to the sphere, I was wondering if you could recommend a tileset that is warped to fit on to it?

cmurphy23 commented 1 week ago

I took a look at the Cesium viewer (which I'm trying not to use, because I want to keep using three), and according to the network traffic, it's loading in the same tiles from Bing. That is to say the tiles are for the web mercator projection, and the application is warping them to fit the sphere. It is also my understanding that Google Earth more or less does the same thing.

I'm going to check out the Cesium source code a bit and see how what's going on underneath. Will let you know what I find.

cmurphy23 commented 1 week ago

It seems like Cesium is setting up a WebGL texture, and computing the color value of each pixel by converting its coordinates to mercator, and then sampling the mercator tile pixel at that coordinate.

I wrote a python script to test this projection out, using the following tile. a0

First, the current geo-three projection Screenshot from 2024-06-22 16-39-26

Here the script projects the tile on to a sphere first naively (mostly matches the geo-three projection, though I forgot to leave out the region where mercator is invalid, I corrected that before doing the projection below) proj1

Lastly, using described projection method, the results look like this: proj2

I think it looks pretty good. Here's Cesium for comparison: Screenshot from 2024-06-22 17-41-04

The next step would to try to make a Shader material that does this calculation and lookup in real time. I'll try to give that shot.

cmurphy23 commented 1 week ago

In case anyone is curious, the place they do that in Cesium, while spread across multiple files, I would say for the most part happens here (they describe the calculation in comments here at least): https://github.com/CesiumGS/cesium/blob/cbd13cee0959d2de6e01f355dd1cd73342467102/packages/engine/Source/Scene/ImageryLayer.js#L1506

cmurphy23 commented 1 week ago

Okay, did a quick proof of concept by hardcoding some stuff for this tile, here's how it looks: image

I will try to generalize it so that it works on all the other tiles, and I'll make a PR.

I am still curious if the tiles should have equal heights, or if that will cause problems from zooming in with this projection, hopefully we'll find out soon.

cmurphy23 commented 1 week ago

All right, made some more progress, I have the projection working properly for the first zoom level: Screenshot from 2024-06-23 12-58-15 Screenshot from 2024-06-23 12-58-32

However, I have some bugs to track down. For zoom levels beyond 1, there starts to be some distortion for the tiles that aren't closest to the equator.

Zoom level 2: Screenshot from 2024-06-23 13-02-40

Looking into this next.

cmurphy23 commented 1 week ago

Getting really close now.

The problem above is caused by the size of the geometric tile section on the sphere's surface not matching the expected bounds for the mercator image tile. I was able to fix that for latitude and now tiles load nicely with zoom... to a point. image

There is still a misalignment for longitude at higher zooms, shown here. Tackling this next. Screenshot from 2024-06-23 16-00-14

cmurphy23 commented 1 week ago

I got it :)

Things are looking pretty good even at high zooms, although a small border is still visible at those levels. Screenshot from 2024-06-23 16-32-33

Here's a video of the LOD adjusting while zooming in (although not as nicely as possible). https://github.com/tentone/geo-three/assets/3690500/28c9d69f-47a1-4d17-bcb1-e59d78c96f83

There's also a visible seam at the international date line still. Screenshot from 2024-06-23 16-38-27

I'm hoping this is good enough for a PR, so I'm going to clean everything, make a fork, and open one up.

tentone commented 4 days ago

Hello

Wow, you have done an impressive ammount of work here 👍

Will be more than happy to help you finishing and merging this code into the library.

This was something that was discarded on the first version because of tile fit, the way sampling is done this way seems to work nicely.