nonta1234 / terraining-heightmap-generator

Terraining - Online heightmap generator for "Cities: Skylines".
MIT License
28 stars 4 forks source link

How are the tiles merged together? #23

Closed delebash closed 3 months ago

delebash commented 3 months ago

I previously talked to you about my app where I adopted the Cities Skylines and added features for Unreal Engine. I did not modify any of the heightmap creation as I really do not understand the math. My question is during the bicubic interpolation or bilinear interpolation is that where the tiles are merged together or is that just the resampling/resizing from the original mapbox 512 to 1081 or 4096. Could I remove that interpolation and get a resulting combined tiles heightmap of 512 without losing any data? Thanks. In my app I have to resample the combined images to many different sizes and I am using GDAL or wasm version of GDAL with a resampling method of Lanczos. For resampling this type of heightmap data is Bicubic a better option? TY

My goal is to get the highest quality heightmap. The default CS uses Bilinear but since I have to resample to multiple different sizes, I thought it would be better not to do any resampling in the code ahead of time and just let GDAL do the resampling but I am not sure how to remove the resampling code and still combine the tiles. Also, with my app I can change the landscape size down to 4km but anything lower than that and it throws an error. Again, I really don't understand the math in merging of the tiles, so I am guessing this is has something to do with setting the Map faces, Map size, and Cell size. For UE I do not really need a start area and a play area I just need to have a bbox that I can change the size of in km. TY

nonta1234 commented 3 months ago

Describe the workflow.

First, Terraining draws them side by side on the canvas for debugging. They have not been resized at this point. Next, since Mapbox Terrain-DEM v1 is not easy to use as is, both the Cities-Skylines-heightmap-generator and Terraining decode into a single Float32Array. In other words, they are merged at this point, and also, at this point, it is no longer image data. Then, the size of this array is changed and interpolated. During interpolation, Terraining also performs an affine transformation for the rotated grid.

Regarding interpolation, bilinear interpolation tends to lose some detail, so in most cases, bicubic interpolation provides higher quality. If Lanczos is available, it should be fine as it offers nearly the same quality as bicubic interpolation.

nonta1234 commented 3 months ago

This is the process of calculating and downloading the required tiles.

https://github.com/sysoppl/Cities-Skylines-heightmap-generator/blob/5ac2306fe45243ecec927d209b6c1dee7e553492/src/app.js#L695C1-L746C6

https://github.com/nonta1234/terraining-heightmap-generator/blob/1d53348bb873b520ca2b26f1ee7d8fa6ea310be3/src/assets/workers/getHeightmapWorker.ts#L166C1-L241C2

delebash commented 3 months ago

Thank you very much so at this point https://github.com/nonta1234/terraining-heightmap-generator/blob/1d53348bb873b520ca2b26f1ee7d8fa6ea310be3/src/assets/workers/getHeightmapWorker.ts#L166C1-L241C2 'const elevations = decodeElevation(pixelData)', I have the combined heightmap data and could just convert the elevations variable to png via png = UPNG.encodeLL([v], 512, 512, 1, 0, 16);, or pass that data to GDAL for resampling? At this point before the interpolation it would be a size of 512?

nonta1234 commented 3 months ago

const pixelData = (await processTiles(tileList)).data const elevations = decodeElevation(pixelData)

pixelData is Uint8ClampedArray. elevations is Float32Array

The return value of processTiles is one ImageData of the combined tiles. I don't know what types GDAL requires, so please try using these.

please try! https://terraining.ateliernonta.com/?debug=true

delebash commented 3 months ago

I appreciate the help. Thanks. Cheers!