Closed kylebarron closed 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.
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.
Thanks for your helpful input!
Wow super cool! I'll have to read up on your code
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, theHorizonOcclusionPoint
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.