CesiumGS / cesium-unreal

Bringing the 3D geospatial ecosystem to Unreal Engine
https://cesium.com/platform/cesium-for-unreal/
Apache License 2.0
952 stars 296 forks source link

CesiumPolygonRasterOverlay causes issues with multiple raster overlays #1551

Closed j9liu closed 1 day ago

j9liu commented 1 week ago

Reported on the forum here:

I was able to reproduce this myself in UE 5.3, v2.10.0 by doing the following:

You'll see some weird glitchy artifacts in the area affected by the polygon. When you remove the WMS, the artifacts won't disappear right away, but you can refresh and the clipping will appear as normal.

image

For curiosity's sake, I tried it the other way around, by adding the WMS after the polygon overlay. The polygon clipping works, but the WMS shows up as this blocky blue gradient over a lot of the tiles. 🤔

image

I have not tested this, but this reportedly happens as far back as v2.8.0. The behavior works as expected in v2.6.0. It might be prudent to check if this happens with v2.7.0 -- that release introduces some CesiumPolygonRasterOverlay bugfixes, as well as custom ellipsoids.

kring commented 1 week ago

@j9liu I'm not able to reproduce this. I tried DX12+SM6, DX12+SM5, and Vulkan, and all three seem to work fine. Actually the first time I tried to use Vulkan, I got this: image But it worked fine subsequently. I have an Intel Arc A750 GPU, so take from that what you will. If you have a level saved that demonstrates the problem immediately on load, it could be worth sending that my way just to eliminate some variables. Also, I should mention I tested with a Debug build out of main.

I'll see if I can reproduce it on my NVidia GTX 1650 laptop.

kring commented 1 week ago

Ok yep I can reproduce it on the NVidia laptop! 😱

kring commented 6 days ago

I think I'm finally getting to the bottom of this, after hours of debugging...

So the immediate problem is that when we're setting the material parameters for the Clipping layer, the textureCoordinateID coming in is 2. Which should be impossible, because it means we have three different sets of texture coordinates for raster overlays. We should have one set of texture coordinates per projection, and we only support two projections currently (Web Mercator and Geographic), so... how do we have three sets of overlay texture coordinates? It shouldn't ever happen.

And the code assumes that it can't happen. There's a "map" called overlayTextureCoordinateIDToUVIndex which isn't actually a map, it's an array hard-coded to have two elements. So when we get this mysterious textureCoordinateID=2, we end up reading outside array bounds, leading to undefined behavior. In some cases, that undefined behavior is apparently weird rendering artifacts.

Ok, so how do we have three sets of texture coordinates? Well, that happens because we have three different projections. One is Geographic, two are Web Mercator. The two Web Mercators aren't the same projection because they have different ellipsoids. The X and Y radii are the same, but the Z radius is different in the 13th significant digit. Here are the two numbers:

6356752.3142451793
6356752.3142449996

One of the ellipsoids (the first one) is our regular WGS84. The second one comes from the new Unreal WGS84 ellipsoid definition stored as an asset. Apparently, when we type the first number into an Unreal Engine details panel, rather than storing that actual number, Unreal gets tired and stores a rounded version of that number instead. To be clear: this difference is well outside the precision limitations of a double, so there's no legitimate excuse for this; Unreal just isn't storing the whole thing.

So I can fix the bug described here just by allowing up to 3 sets of texture coordinates (I confirmed that works). But that's not the right solution. Still working on a proper solution...