CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.67k stars 3.43k forks source link

Mapzen Terrain Tiles (AWS public data set) #4685

Open YousefED opened 7 years ago

YousefED commented 7 years ago

Hi,

I recently noticed Terrain Tiles are hosted on S3, by Mapzen: https://aws.amazon.com/public-datasets/terrain/. I'm trying to add support for this, using the Terrarium format.

I gave it a go at https://github.com/YousefED/cesium/commits/mapzen-tiles-terrarium, but getting stuck with the following result:

image

Probably missing something obvious for you guys, I'm new to the internals of Cesium / 3d engines.

Thanks,

YousefED commented 7 years ago

Seems like HeightMap terrains silently fail when there's too much data.

I've tested this by looking at EllipsoidTerrainProvider.prototype.requestTileGeometry. When I set width / height to 256, I get the same, transparent globe:

var width = 256;
            var height = 256;
            return new HeightmapTerrainData({
                buffer : new Uint8Array(width * height),
                width : width,
                height : height
            });

Any further directions on recommended ways to implement S3 terrain data would be welcome!

hpinkos commented 7 years ago

@kring do you have any suggestions here?

YousefED commented 7 years ago

A proof of concept of S3 tiles is now working at https://github.com/YousefED/cesium/commit/5917d05e63381982315c98b05720c043541f224b

I've hacked around it by resizing the image tile to 64x64. This sometimes results in quirks at the edges of tiles of course:

image

I could either implement a smarter resize algorithm (leaving edges "as is"), but would be better to find and solve the root cause of the problem

kring commented 7 years ago

The story here is that WebGL, without using an optional extension, only supports two byte vertex indices. That means that the maximum number of vertices that can be in a single terrain tile mesh is 65536. A 256x256 tile is exactly 65536 vertices already, and when we add the skirts at the tile edges we end up over the limit. If you have more than 65536 vertices, the index values start wrapping when written into the index buffer, and nothing works right.

IMO 256x256 terrain tiles are not very useful anyway. They're too much detail and make rendering too slow. But if you do need to use them, you'll have to modify Cesium to require and use the OES_element_index_uint extension or break the terrain tile into multiple meshes.

YousefED commented 7 years ago

Thanks @kring.

1) Might be good to have Cesium report an error when too much vertices are passed internally? 2) I'll proceed with resizing the height tiles to 64x64. Would you agree the following would be a good approach? In order to prevent the "cracks" in between tiles; resize the N/E/S/W 1px of the tile to 64x1 (or 1x64). Then, calculate the inner 62x62 pixels by resizing the 254x254 center of the tile to 62x62. This should have consistent edges between tiles (provided the source data is ok)