Custom water mask

Hi there,

I am using my own custom water mesh with cesium which is working really well, however there are certain areas with which the mask accuracy is less than desired. (Note mask resolution is fine, however it cuts into the land in certain areas meaning the coastline isn’t as accurate as I would like)

In the opposite instance (where there is aerial photography of water being rendered as terrain as it is not masked) it is solvable by using a Cartographic polygon along with a CesiumPolygonRasterOverlay
to cull the offending bits of aerial photography water.

Where there isn’t terrain however as a result of the water mask this isn’t possible.

Is there a way to override/provide my own mask for specific tiles?

Or, alternatively, use a Cartographic polygon to force specific areas to ignore the mask?

Thanks,
Chris

This isn’t simple, but it’s definitely possible. You can provide your own water mask by using the raster overlay system. Then copy and customize the material used to render tiles so that your raster overlay is used as a water mask rather than to color pixels like a normal raster overlay would.

The easiest way to create the mask is probably to create a GeoTIFF in a GIS program. Then, upload that GeoTIFF to Cesium ion to create an asset that can be used with a Cesium ion Raster Overlay.

As far as customizing the material, this tutorial walks through the basics:

Hi Kevin,

Thanks for taking the time to reply. To update you - I have had success understanding the GeoTIFF side of things, creating a test GEOTiff, uploading it to Cesium and getting to to render draped over the terrain as an additional raster overlay.

I am however struggling with the mask side of things. I’ve had a bit of a play with the MF_CesiumWaterMaskSample but trying to tweak the output to anything other than what’s provided seems to result in an entirely grey texture. (I tried just feeding it a checker with the input uv’s at different scales + using world texture coordinates)

I would be really grateful if you could give me a few more pointers as to where I should be digging / if I’m on the right lines. ( Happy to get my hands dirty with the actual mask logic - I’m just not entirely sure if I’m going about it in the right place)

On an additional note - I’m currently only using one geotiff for my mask. I suspect I will need several along the coastline. Can I zip these up or similar and upload to Cesium as a collection/single asset to be used as a single raster overlay?

Thanks

I am however struggling with the mask side of things. I’ve had a bit of a play with the MF_CesiumWaterMaskSample but trying to tweak the output to anything other than what’s provided seems to result in an entirely grey texture.

Are you using the latest version of Cesium for Unreal (v1.28.0)? This sounds like a bug we had once, but it was quite awhile ago.

I would be really grateful if you could give me a few more pointers as to where I should be digging / if I’m on the right lines.

Start by copying MI_CesiumThreeOverlaysAndClippingAndWater and editing the copy. On the “Material Parameters” tab, notice that there’s a layer named “Water” and three others labeled “Overlay0”, “Overlay1”, and “Overlay2”. You basically need to combine elements of Water and one of the elements.

First, change the “Layer Asset” in the “Water” layer from ML_CesiumWaterMask to ML_CesiumRasterOverlay. Then rename the Water layer to something else, like MyWater. Back in your level, add a Cesium ion Raster Overlay for your water mask, and set its Material Layer Key to the same name you renamed the water layer in the material to (MyWater). Select your new material instance for all three materials on the tileset (Material, Translucent Material, and Water Material).

Try it out. You might get something useful, or you might not. If it’s not quite right, the next step is to copy the “Blend Asset” used in the water layer in your material instance (MLB_CesiumSimpleWater), select the copy in your material instance, and modify it as necessary.

In the MLB_CesiumSimpleWater, there’s a a GetMaterialAttributes node that gets the pixel value from the raster overlay, which in this case is your water mask. You need to turn that pixel value into the correct input to the ML_CesiumLandWaterBlend function. You want to pass a value of 1.0 where there is water, and 0.0 where there is land. So do whatever manipulations you need to do to the pixel color values from the mask geotiff to make that happen.

On an additional note - I’m currently only using one geotiff for my mask. I suspect I will need several along the coastline. Can I zip these up or similar and upload to Cesium as a collection/single asset to be used as a single raster overlay?

Yep, you can upload multiple GeoTIFFs to make a single imagery tileset. No need to ZIP, just select all the files when you upload to Cesium ion.

Hi Kevin,

This worked! Thanks so much for the speedy reply and the very clear instructions.

One final quick question for you -

I have a bit of an issue where my 3d water assumes the terrain height is 0 (which obviously it isn’t in certain places) this mostly looks good but I had a bit of a brainwave to fudge/resolve in the instances where it doesn’t.

To combat this I made a hack to the base Cesium material where it would grab the worldposition, min the Z with 0, multiply by -1 and then push that into the WorldPositionOffset node. (Such that the Cesium terrain height would always be clamped to never be lower than 0) (I’m more concerned that terrain is never underwater vs instances of it floating slightly)

This mostly works (with a little bit of an offset) but I’m getting what looks like z fighting. Interestingly however, it seems to flicker every single frame (without any camera movement) i.e one frame I’m getting water, the next the cesium terrain. Weirdly if I have the CesiumWorldTerrain actor selected in the outliner in Unreal it sorts/behaves totally fine, but if I select anything else, the flicker is there.

I appreciate this is a bit of a hack but if you happen to have any obvious brainwaves I’d love to know.

Thanks again for your help!

I’m not sure. I have seen cases where a scene with depth fighting flickers even without camera movement. It might have something to do with how Unreal does anti-aliasing, but I don’t know the details.

Thanks Kevin,
I will continue to investigate - that is drifting a little from the initial topic of the thread however so please consider the water mask matter resolved/closed!
Thanks again for your help - Have a great weekend!
Cheers,
Chris