We convert our water masks to metallicRoughnessTextures in our 3D Tiles export from Remoscape. These textures have blue color (0,0,254) for water and green (0,255,1) for the rest and we map them on layer 2 in our B3DM files. This works to let the water reflect the sky in Unity and Cesium JS but not in Cesium for Unreal. Here is the 3D Tiles dataset:
See screenshots from Unity compared to Unreal below (don’t mind the failed i3dm instanced tree geometry in Unity):
You should see a reflection in Unreal if your roughness value is 0 (or close to it) and your metallic value is 1 (or at least greater than 0).
Our default material explicitly sets the Specular output to 0.0. I can’t say whether that is technically correct, but we found that UE’s default (0.5) made the terrain surface far too shiny-looking in our sunlit scenes, even with a roughness of 1. By setting Specular to 0.0, we get rid of the shininess, while still allowing reflections by increasing the metallic value.
If increasing the metallic factor doesn’t work for you, another option is to customize the material to change the specular factor back to 0.5. To do this, you’ll need to copy the following from the plugin:
Instances/MI_CesiumThreeOverlaysAndClipping
Layers/ML_CesiumGltf
MaterialFunctions/CesiumGlTFFunction
Change the bottom layer of the material instance to point to the copied material layer, and change the node in the material layer to refer to the copied function. Then, in the copied function, change the node that assigns 0.0 to the Specular pin to 0.5 or whatever you like. Finally, select the copied material instance in the “Material” field on your Cesium3DTileset.
Thanks Kevin, your suggestion works fine! It even reflects the nearby terrain and trees. But what does this tell us, that setting specular to 0.0 doesn’t allow metallic? Maybe there’s something to be done in the plugin to fix this?
I did some tests with your data and it looks like metallic values are not coming through from your source data. See the comparison image below from Unity, essentially the default (your data with no custom materials) is displaying a metallic output of 0, the far right slice displays the output if it’s entirely 1 meaning that whatever blue values are set on your metallicRoughnessTexture are not making it to the final output.
Unity with HDRP incorporates specular value based on the albedo base color, so the reflection you’re seeing is in part due to that, while you see no reflection from Unreal because Unreal requires at least a Specular value above 0 or a metallic value above 0. Our base material in Unreal hard-sets the Specular to 0 since the metallic workflow is more favorable for terrain, and it appears as well in Unreal that tweaking the metallic values results in reflections showing up on the water.
I’d suggest re-verifying that your metallicRoughnessTexture is indeed packed with the values you mentioned above. We will also investigate whether or not the texture is coming in as expected.
I’ve also uploaded an image of your data in a URP scene, and reflections don’t show due to the separate render pipeline handling specular defaults differently.
Thanks for looking into this! You’re right, I experimented with setting all water pixels to black here and the result is the same in Unreal with Kevin’s suggested material workaround. So it seems to be the absence of green roughness that makes the water specular rather than the blue metallic.
I have now tried without the material workaround and with metallic pixels as (0,0,254) (still can’t remember who recommended trying 254 instead of 255), (10, 10, 245), (0,0,255) and (245,10,10) (in case it’s interpreted as BGR instead of RGB), all to no avail. I’m just editing all *_water.jpg textures in Gimp and I can verify the exact values there. You can also have a look in those files and try editing them if you want, there are 15 of them.
I think the fact that the roughness makes a difference in my metallicRoughnessTexture shows that it’s actually being used. I’m looking forward to the results of your further investigations!