CesiumGS / cesium-unreal

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

Add support for 3D Tiles Styling Language #1392

Open yuziqii opened 7 months ago

yuziqii commented 7 months ago

Is there any updates about Styling metadata?

I've noticed the material system is already supports metadata styling by using the CesiumFeaturesMetadataComponent, which is quite impressive. However, there seem to be two limitations: But we have to generate the material layer first, and as far as I can see, there are two limitations:

  1. We're unable to generate the material layer and add the new material layer to the material instance at runtime.
  2. We can only hard code the styling conditions in material layer or material layer blend, making it impossible to evaluate a styling expression and style the mesh based on metadata.

In light of this, I delved into the code found out a potential solution. Here's my thoughts:

  1. We could introduce a simple js interpretor like tiny-js to evaluate the styling expression. It's simple and easy to integrate and offers a useful function to bind native c++ functions to js functions, allowing us to easily utilize built-in functions defined in 3dtiles 1.1.
  2. After obtaining the evaluation result of the styling expression, we could parse it to FColor, then encode the result to a texture pamameter defined in material layer or material layer blend. This process is just like encoding metadata to the corresponding texture parameter, with an additional evaluation step.
  3. Subsequently, we'd set the material attribute using this StylingResult texture parameter.

And I have tried to implement this, here is the result:

demo9

However, I encountered some issues. In order to set the vertex opacity, I changed the material blend mode to Translucent. Strangely, the tileset appeared darker then when using the blend mode Opaque or Mask. Yet, if I switch to the Mask blend mode, I can't set the tileset to be translucent. It can only be either transparent or opaque. Thus, I'm wondering if there is any way to use blend mode Mask to achive translucent in the tileset? Any help would be greatly appreciated!

image image

j9liu commented 7 months ago

Hi @yuziqii,

The project board you linked hasn't been updated in a long time 😅 Yes, we have updated Cesium for Unreal to support EXT_mesh_features and EXT_structural_metadata as of version 2.0.0. But it looks like you're talking about styling with the 3D Tiles styling language in CesiumJS. Yes, this is fairly different from the current system.

Those limitations that you listed are true, and they're due to several factors:

So unfortunately, to take advantage of Unreal's node-based material graphs, you have to do it all at the beginning, and it can't be changed at runtime.

However, your work with the 3D Tiles styling language looks awesome! This would be a cool community contribution, if you're willing.

Regarding your question, I don't think I follow. The Mask blend mode is not meant to be used for translucency. It defines an alpha "cutoff" value. Anything below this value will be completely transparent, and anything above it will be completely opaque. You won't be able to use it for translucency. Is there something that makes the other blend modes not sufficient for your use case?

yuziqii commented 7 months ago

@j9liu Thanks for your reply.

The reason I use the Translucent blend mode is to ensure that the styling result matches that of CesiumJS. In CesiumJS, the styling result can be translucent. If I use the Mask blend mode, it will not be able to achieve translucency, which I believe is not an ideal solution. In this scenario, I can utilize the 'Lerp' function to blend the original color and styling color with opacity. However, this approach will not result in translucency, it will simply blend the layer base color.

Therefore, I prefer the 'Translucent' blend mode. However, as you can see from the pictures in my previous comment, simply changing the blend mode from Mask to Translucent results in quite different appearances. Is there any way to make these two blend modes look the same?

By the way, I would love to submit a PR about this feature once I resolve these minor issues. I'm open to discussing this further if anyone has ideas.