From what I gathered Cesium Catrographic Polygons are not the way to go. I should rather look more into shaders and materials in Unity. I am still trying to figure out how to do this exactly.
Id say I need a âcutter objectâ that the Cesium terrain needs to intersect to get rendered. Since I am not that well versed in shader programming I would like to get some pointers from folks that know how to do this.
What are the keywords I need to look into? Stencil buffers are something that look promising, however they only define an area where everything that is within the area and successfully passes the stencil test gets rendered.
Id appreciate some help, or maybe there are open source projects already achieving this effect that I could look into.
The CesiumTileExcluder, combined with a material that discards pixels via opacity mask, may be what you need. There are some details about this approach in this PR where the CesiumTileExcluder was originally added:
You may also be interested in this related thread, though it doesnât have a concrete answer just yet:
thanks for the heads up. I was able to implement the CesiumTileExcluder based on the PR you linked, as well as your initial implementation for the mesh clipping functionality.
The thread you linked is also very interesting. Havent delved deeper into the topic myself yet. I was busy trying to adapt the tileset shader to my needs.
What I stumbled upon are issues other people also reported when trying to implement the tabletop map concept. Problems such as Y position variation when changing the Cesium Georeference scale property and how to implement map panning.
Setting Cesium Georeferenceorigin and possibly using SampleHeightMostDetailed is what Ill look into for the height variation based on these posts:
I decided to go back optimizing my terrain shader. A limitation of my initial adjustment of the CesiumDefaultTilesetShader was that the masked area stayed at 0, 0, 0 in world space.
I need to pass the position of the object I want the clipping mask to follow to the shader.
Looking at this thread I eventually managed to implement passing of values to material properties of loaded tiles during runtime after initially trying to do it through the Opaque Material property of the Cesium3DTileset component: Shader for Cesium World Terrain - Cesium for Unity - Cesium Community
Because I want the map table object to be fully interactable (transforming, scaling, rotating) I will look into passing the appropriate values to the shader and adapting the shader further eventually.
Right now I am struggling to wrap my head around the whole maintaining tileset height issue.
So I played around with the Cesium Georeference components Height and Scale properties as well as the related game objects positions but changing the scale property still leads to a change in the displayed terrains height in Unity.
Apparently I didnt manage to set up my scene as described here because that approach does not work for me:
Another thing that just came to my mind that will be relevant down the line is if Cesium for Unity allows for scaling of the displayed terrain. I read that the parent of the tilesets that hold the CesiumGeoreference component should have a local position of 0,0,0 and a scale of 1. But can I scale the georeferences parent object which would in my case be the map table without running into issues with the plugin?
Letâs start with the easiest problem (hopefully!) first. The SampleHeightMostDetailed is failing because the underlying C++ Tileset object is being destroyed after the height sampling is started but before it finishes. This is most likely because youâre changing a property of the Cesium3DTileset - possibly elsewhere in your application - and that is triggering recreation of the C++ Tileset. Does that seem plausible?
Beyond that, Iâm having a little trouble following what youâre saying about the scale. Janineâs advice in the thread you linked certainly will only work if you know the exact location and height that you want to âscale aroundâ, though, so getting SampleHeightMostDetailedworking seems like the first step.
Disabling all other scripts that access the Cesium3DTileset to see if that would prevent SampleHeightMostDetailed from failing did not work.
So I created a new Unity Project (Unity 6.2, URP Sample) and added only the Cesium for Unity plugin. In the sample scene I added the Cesium World Terrain + Bing Maps Aerial and added my script to the CesiumGeoreference game object.
Sampling of the height is unfortunately still failing.
Moving the code out of the Start() event function resolved the issue. I tested sampling the height on a button press and that works. Still not sure what happens in Start() that caused the Tileset to be destroyed though during sampling.
My approach to fixing the âscaling issueâ would be:
Whenever the user pans around the map or changes the height I need to sample the height at that new Cesium Georeference origin position using SampleHeightMostDetailed, then set that sampled height as the new Cesium Georeference origin position height.
Guess I should hook into the Cesium Georeferencechanged event to execute the sampling and setting the new origin? I am not that experienced with async/await or coroutines but I suspect having these tasks called so frequently will be an issue. Or is there a clean way to handle that?
Since I dont want the position to change instantaneously the change should also be interpolated.
Okay, so hooking into the changed event caused my application to freeze since that calls the async method way too often I assume.
Maybe fixing the height variation once the CesiumGeoreference origin position deviates a certain amount from the sampled position is more sensible.
Which property of CesiumGeoreference would be the best indicator to check for that deviation? Its still not obvious to me what exactly the problem is when you move further from the CesiumGeoreference origin that causes the height variation when scaling.
Have you considered using Physics.LineTraceSingle instead of SampleHeightMostDetailed? The advantage is that itâs synchronous and fast. You can do a line trace every frame and get the result immediately, on the very next line of code, without the need for a coroutine.
The disadvantage is that it only traces against the terrain that is currently loaded and rendered. So itâs not suitable at startup, before you show the terrain on your table. SampleHeightMostDetailed is probably still useful for that. But it may be a better way to adjust the height during movement.
Another disadvantage (maybe) is that it returns the position in Unity world coordinates, rather than Longitude / Latitude / Height that you can use to set the CesiumGeoreference origin. But you can use TransformUnityPositionToEarthCenteredEarthFixed to transform Unity coordinates to ECEF, and then georeference.ellipsoid.CenteredFixedToLongitudeLatitudeHeight to transform the ECEF coordinates to longitude/latitude/height.