I’m using TMS Tile images to define the areas to be displayed as water.
I followed the idea of this link to do it:How do I set a water mask material? - #5 by Kevin_Ring
But I don’t understand “create a custom material that reads from the overlay texture”, how to reads from the overlay texture,and what should be read? What I mean is how to match custom materials with the Raster overlay? I want to render the TMS Raster overlay as a water effect instead of the entire Earth.
Looking forward to your reply, thank you!
In other words, how to determine which Raster Overlay the current mesh corresponds to?
Hi @lxq11111, welcome to the community!
First of all, please understand that this is an advanced thing to do. We don’t have step-by-step instructions, and you’ll need to figure out a lot of details yourself. However, we can point you in the right direction, and may be able to help if you get stuck.
To get started, make a copy of CesiumDefaultTilesetShader
and CesiumDefaultTilesetMaterial
, which are found in the Cesium for Unity package’s Runtime/Resources folder, because you’re going to need to modify them. Open up the Shader in the Unity editor and take a look at it. The topmost part of the graph is labelled “Raster Overlays”. For each of the three raster overlays, it makes a call to CesiumRasterOverlay
, which returns the pixel value sampled from the raster overlay (in your case, your TMS) alpha blended with the layer below it. You can use this value to determine whether the current pixel is land or water. Then you need to add further nodes to actually render the water effect for the pixels that are water.
Thank you very much for your response! However, I still have some questions.
I followed the idea you provided,and use the pixel value to determine whether the current pixel is land or water, but some pixels on land are also treated as water. I can get the height (mesh.transform.GetComponent<CesiumGlobeAnchor>().longitudeLatitudeHeight.z
) of the current terrain to make a judgment, but some terrain tiles contain both land and water, and using height information to make a judgment is also inaccurate. Can I obtain the zoom level of the current Raster Overlays in the script? or do you have a better idea?
If I knew the current zoom level(level-of-detail), I could use height information at the most detailed level to determine, making the water effect only effective below a certain height.
Hi @lxq11111,
I’m not sure I understand the problem. Why are some pixels on land being treated as water? Do you mean that the mask data in your raster overlay is incorrect? Or is it somehow not coming through to the material correctly?
Thank you @Kevin_Ring, I want to put the mask data containing water on a separate layer. However, most of these images are of water and also include land, such as the coastline. I was thinking about using pixel color to distinguish between the water and land, but it cannot completely to distinguish
I need to create water effects on the global ocean
I think trying to use satellite images to separate water from land is going to be extremely error-prone, and I don’t know what you could do to solve that. Based on a quick search, there are some papers about how to do this:
https://www.tandfonline.com/doi/full/10.1080/1755876X.2018.1529714
Perhaps you can get access to those results, or recreate them? Or find some other dataset that is an actual mask explicitly separate water from land, rather than colors that need to be interpreted?
The easiest thing by far is to use Cesium World Terrain, which already has such a mask built in. Have you already considered that possibility?
Hi @Kevin_Ring First and foremost, thank you for your response.
I referred to these questions:How do I set a water mask material? Unity Cesium Water System and Custom Water Cesium. I thought there was no water mask in Cesium for Unity before -_-||… How should I access the water mask if i use Cesium World Terrain? I didn’t see it in the Cesium3DTileset.cs
Additionally, should I edit a GeoTIFF file that only contains the global ocean and use its Raster Overlay to render the water effect if using custom terrain?
I want to render wave effects for all sea land boundary also, which is usually achieved by calculating the depth of water and the current depth of land in the depth map to determine the range of wave appearance, UV offset, color gradient or other effects. Water and land use the same material in Cesium for Unity, and their depths will be written into the depth map. Do you have any ideas to achieve this effect? thanks!
Oh, I’m sorry, I misread and thought you were using Cesium for Unreal. You’re right that Cesium for Unity does not support the Cesium World Terrain water mask.
Unfortunately water rendering is not a built-in capability, and it’s not something I can walk you through because I’ve never done it myself. It’s theoretically possible, but there will be a lot of problems to solve along the way.
You’re right that you can’t use a separate material for land and water. You’ll need to use a single material that chooses between and land and a water appearance based on some mask.
For the mask, I don’t have any easy answers for you. You might be able to source some bathymetry data in GeoTIFF format, and then upload that to Cesium ion to tile as Imagery. Then you can access that as a raster overlay from Cesium for Unity and do your material magic to render water in the right places. I know that’s pretty hand-wavy, but I don’t have any more specific instructions for you.
Another possibility is to add support for the Cesium World Terrain water mask to Cesium for Unity. To get started, you can take a look at how it’s done in Cesium for Unreal: