Open janichk opened 1 year ago
@loaders.gl / parse_terrain.ts /getMeshAttributes where the 32 bit resolution forces multiple x and y coordinates into the same values
Maybe we could add an option there for whether to use float32 or float64
but the rendering is still messy like in the picture above
I can't tell what you're saying is wrong in the wireframe. If anything, it looks from that image to be "blocky" instead of a smooth terrain. I think that's usually an artifact from setting meshMaxError
to 0, since you don't have any simplification across similar nearby pixel values.
@loaders.gl / parse_terrain.ts /getMeshAttributes where the 32 bit resolution forces multiple x and y coordinates into the same values
Maybe we could add an option there for whether to use float32 or float64
but the rendering is still messy like in the picture above
I can't tell what you're saying is wrong in the wireframe. If anything, it looks from that image to be "blocky" instead of a smooth terrain. I think that's usually an artifact from setting meshMaxError
to 0, since you don't have any simplification across similar nearby pixel values.
@loaders.gl / parse_terrain.ts /getMeshAttributes where the 32 bit resolution forces multiple x and y coordinates into the same values
Maybe we could add an option there for whether to use float32 or float64
but the rendering is still messy like in the picture above
I can't tell what you're saying is wrong in the wireframe. If anything, it looks from that image to be "blocky" instead of a smooth terrain. I think that's usually an artifact from setting meshMaxError
to 0, since you don't have any simplification across similar nearby pixel values.
What we're seeing in the wireframe, is multiple z coordinates in the same x-y positions. It is very apparent as I zoom in beyond zoom level 17 that there is a granularity issue with the x-y coordinates. Setting meshMaxError to zero is not necessary, its just a means to make the problem more visible. In our application we need to show fine details in the terrain, 25 cm resolution or finer. I have tested our tile-server with CesiumJS, and the visualization there is showing the fine details. We would much rater use deck.gl for our application though..
What I suspect is that all tiles are visualized in the same larger CRS, where eventually the granularity of float32 is insufficient to represent the subdivisions in x-y direction. Beyond a certain zoom level, the size of those blocks in the wireframe are the same size, while more and more z values are stacking up.
Unfortunately we are unable to share our tile-server, but the problem can easily be reproduced using a single terrain png and narrowing in the bounds until you see the same "blocking" as in the image above. My expectation is that the terrain representation would be the same regardless of the size of the bounds, but at different zoom levels.
I modified the Codepen from https://deck.gl/docs/api-reference/geo-layers/terrain-layer to illustrate the issue. Although in this case delatin meshing is used, the result is the same.
It is definitely related, but the response in that thread is incorrect. At zoom level 22, the bounds in my case are [264.1475830078125, 360.439208984375, 264.147705078125, 360.4393310546875] in double representation, which translates to [264.14758, 360.43920, 264.14770, 360.43933] in 32 bit representation (assuming 8 significant digits, IEEE float 32 has 6-9 with an average of 7 significant digits). Now see how many distinct x and y coordinates can be represented in those ranges given the 32 bit limitation. As mentioned initially, I found a workaround for the issue in getMeshAttributes, using relative bounds instead of absolute (freeing up some digits), but the visualization of the tiles is still the same. My conclusion is therefore that the 32 bit issue is not limited to the function mentioned in #6620
Is this related to the sudden change in elevation that happen when zooming out and in in the terrain layer example https://deck.gl/examples/terrain-layer ?
I stumbed upon the same issue while trying to display a custom (dense) terrain mesh with a cell size of 0.5m. This is what I get due to the 32bit resolution (this is actually a 100x100 cell grid). I created a modified TerrainLayer that instantiates the SimpleMeshLayer like this:
renderLayers(): Layer | null | LayersList {
const { color, material, elevationData, texture, wireframe, bounds } =
this.props;
if (!elevationData) {
return null;
}
const [minX, minY, maxX, maxY] = bounds;
const xScale = maxX - minX;
const yScale = maxY - minY;
const SubLayerClass = this.getSubLayerClass('mesh', SimpleMeshLayer);
return new SubLayerClass(
this.getSubLayerProps({
id: 'mesh',
}),
{
data: DUMMY_DATA,
mesh: this.state.terrain,
texture,
_instanced: false,
getPosition: () => [bounds?.[0] ?? 0, bounds?.[1] ?? 0, 0],
getScale: () => [xScale, yScale, 1],
getColor: color,
material,
wireframe,
},
);
}
My question is, whether we can somehow circumvent the precision issues since the large coordinates could be avoided in the camera frame for rendering. The grid vertices are already normalized to the range [0,1] and then only scaled via getScale
and the offset is provided by getPosition
.
Description
I am attempting to visualize high resolution terrain data using the TerrainLayer, but it seems that at higher zoom levels the layer is unable to correctly render the tiles. The cause of this seems to be a rounding error due to use of float32.
The problem starts at zoom level 17 in my case, but I guess this will depend on the cartesian offset.
Wireframe showing the rounding error.
While debugging this issue, the first problem was actually found in the @loaders.gl / parse_terrain.ts /getMeshAttributes where the 32 bit resolution forces multiple x and y coordinates into the same values. I overcame this issue by modifying the code to use zero based bounds and a scaling factor, then communicating these parameters with the generated mesh so that the creation of the SimpleMeshLayers in TerrainLayer.renderSubLayers can compensate through getPosition and getScale.
Now I can verify that the mesh generated by the TerrainLoader is ok, but the rendering is still messy like in the picture above, and i assume this is caused by later mesh processing. I have spent a few days digging, but I'm still unable to pinpoint exactly where the error lies. Suspecting it could be mesh_layers/utils/matrix.ts ...
Flavors
Expected Behavior
At a minimum, the limitations in the TerrainLayer and TerrainLoader should be documented, e.g. max supported zoom level..
I would love to get some pointers on how to solve this issue in my current project short term, and of course get a long term solution in place in an upcoming release.
Steps to Reproduce
Problem should be visually apparent
Environment
Logs
No response