Yes, I’m thinking about some changes to the terrain format. The biggest change, as I may have mentioned before, is a move toward triangle meshes instead of heightmaps. Triangles meshes give us a lot more flexibility, especially in terms of putting terrain detail where it is needed most. Cesium will always support rendering heightmap-based terrain, however, so you’re free to continue using that if it is more convenient for you.
Your approach to generating tiles sounds really interesting. I’d love to see a demo sometime.
Answers to your specific questions are below…
- Would it make sense to separate the elevation data from the water-mask
At least in our case the two come from different data sources, and since we are rendering elevation tiles on the fly from LiDAR data on the GPU. I am worried that additional steps, such as fetching/computing the water mask data may introduce bottlenecks, when instead we could be just running parallel service.
By combining terrain and the water mask (and even imagery, eventually) into a single file, we reduce the number of separate requests the client has to make, which can substantially improve performance. That said, Cesium needs to offer more flexibility here. I can easily imagine having several options: an “all-in-one” tile set that is used out-of-the-box and presumably by the vast majority of users. And then the same data presented as separate terrain, water, and imagery tile sets for users that want to use just one or two of the standard data sets and combine them with something else.
By the way, if you just want to skip the water mask for now, it’s easy enough to make a version of CesiumTerrainProvider that does not include or require a water mask. Let me know if you want to go down that road.
- Do you think a relative elevation model makes sense?
As mentioned the current format, is not able to represent the entire domain of elevations from the lowest sea level to the highest point. I think 16bit is plenty fine in terms of resolution per datapoint when looking at terrain with human eyes. There is obviously a tradeoff between having the data in a format that can just be uploaded straight to the GPU and keeping flexibility in terms of data resolution/format and bandwidth requirements(which compression may take care of?!).
The current format was chosen because it worked well with our current terrain dataset, which is GTOPO30 plus SRTM. Cesium itself (that is, everything outside of CesiumTerrainProvider) has a lot more flexibility in the formats it accepts. If you want a different format, such as one that supports a wider range of heights with less precision, or even one that uses four bytes per height instead of two, that is trivially done. Take a look at CesiumTerrainProvider.js around line 56. These parameters describe the structure of the heightmap. Detailed documention for them is found with the reference doc for HeightmapTerrainData. So you can create your own version of CesiumTerrainProvider, which is a very simple class, and plug terrain data with a substantially different format into the Cesium terrain rendering engine.
If you’re working with undersea terrain, however, Cesium may be overly aggressive in how it culls tiles. That is, tiles that you expect to be visible may not be rendered. If you see such problems, I can guide you in working around them, though there will be at least a small performance impact.
I’m also working on streaming individual LiDAR samples via websockets, because we want to display the actual point samples at high level of detail. Not sure this has much to so with the tile format, since we’re going to probably render them as point clouds / visualizations rather than height mapping the terrain mesh itself. Just thought i’d throw it out there in case it rings any bells.
Sounds cool. Mesh-based terrain might be more suitable for this than heightmaps. But if you want to display individual points, I think you’re right that this is outside the scope of terrain rendering.