davenquinn / cesium-martini

On-the-fly meshing of raster elevation tiles for the CesiumJS virtual globe
MIT License
79 stars 17 forks source link

Cool project! #1

Closed kylebarron closed 4 years ago

kylebarron commented 4 years ago

First as a little background, I've been working on some similar terrain projects with deck.gl a 3D-capable geospatial rendering engine, which now has support for extruded terrain. I've found that using Martini to generate the mesh client-side has good, but not necessarily great, performance. So I'm testing out an alternative approach: to run Martini and generate a Quantized Mesh format in a serverless function in AWS Lambda. This should be fast and relatively cheap, maybe ~$10 per million tile requests.

Regardless, I'm tackling essentially the same problem you are: running Martini and generating a Quantized Mesh-compliant tile, just that I'm doing it in Node and you're doing it client side. My WIP Quantized Mesh encoder and the WIP lambda function to take a heightmap, run Martini on it, and then encode into quantized mesh.

A few notes:

BoundingSphere, HorizonOcclusionPoint

https://github.com/davenquinn/cesium-martini/blob/be4c1e918dce47e76644fe6991a7d74f4f714f37/src/terrain-provider.ts#L152-L162

I think these might be wrong. First, the BoundingSphere is the minimal bounding sphere of the tile not of the earth. It's used to prevent rendering unnecessary tiles. Second, the HorizonOcclusionPoint is defined as a point where if the point is not visible, then no portion of the tile is visible. Here's an image from Cesium; P is the horizon occlusion point, which by definition must be "above" the tile in 3D space.

https://github.com/davenquinn/cesium-martini/blob/be4c1e918dce47e76644fe6991a7d74f4f714f37/src/terrain-provider.ts#L204-L209

Why inside the if block? This seems like an ideal way to create the bounding sphere for all tiles.

A couple helpful references if you haven't seen them:

Free Terrarium heightmap tiles

You're currently pulling Mapbox's Terrain RGB tiles, but you can also use AWS Terrain Tiles for free. Just note that they use a different encoding.

davenquinn commented 4 years ago

Thanks for the code review and attention to these details.

I definitely phoned in some of these (important!) bits as I was building a basic understanding how Cesium operates internally, copying code from the QuantizedMeshTerrainProvider until something kinda-sorta worked. Improving these transforms is an important next step, especially to enable work with data in different coordinate systems, such as "off-the-shelf" Mars planetary data.

This explanation of how horizon occlusion should work is helpful; I will look to this code for details and add some calculations based on the tile 3d bounding volume.

Your AWS approach is attractive, but for most of our use-cases we are interested in fidelity and flexibility (in terms of data sources/pipelines) over speed, at least right now. But it's good to have both of these options available, and some cross-talk or sharing between node and client-side meshing code will be valuable going forward. Some features such as low-zoom-level mesh densification (to handle Earth curvature) aren't implemented here yet but will be needed going forward.

To your last point, I'm happy to accept pull requests for enabling other commonly-used formats in this renderer, and will probably add some options of my own going forward.

davenquinn commented 4 years ago

I fixed some of the details with tile bounding box calculation (it was actually doing the correct thing, but the control flow was overcomplex).

I also improved the tile occlusion calculations according to the resources you provided. I used a few simplifications over the full approach to speed things up: only using maximum terrain heights, for instance, and using the ellipsoid's maximum radius. These may need to be revisited if we want to map strongly non-spherical bodies (e.g. asteroids!). But this is not currently in-scope.

Below is a summary of the occlusion calculations I have implemented.

horizon occlusion calculations

Thanks for your helpful input!

kylebarron commented 4 years ago

Wow super cool! I'll have to read up on your code