cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Modify the color of the node after the gltf model is loaded

Open runningREAL opened this issue 2 years ago • 11 comments

In the callback after loading the gltf model, I used getByNode() to retrieve this node. I found the matrix, but I couldn't find anything related to materials or colors. "Because I want to individually change the appearance of the node in the model to highlight it, ask for help." image

runningREAL avatar Mar 27 '23 10:03 runningREAL

Hi @runningREAL,

Unfortunately, this is not possible in the current Cesium API. There's an issue that requests similar functionality at #8919, but it hasn't been addressed yet.

j9liu avatar Mar 27 '23 18:03 j9liu

@j9liu Thank you for your reply. It turns out that this feature is not available. No wonder I can't find it. I thought for a moment. I probably can only combine Threejs and Ceiumjs to solve this problem, which adds some complexity. I haven't tried much in this area, and I may encounter some unforeseen problems. Good luck, hh.

runningREAL avatar Mar 28 '23 08:03 runningREAL

@pjcozzi @ggetz Hi! Is it possible to change the color of a separate model nodes in a cesium latest version v1.113 ?

ViachaslauBohdan avatar Jan 04 '24 17:01 ViachaslauBohdan

@ViachaslauBohdan There hasn't been any activity on this item recently. If you'd like to add more information about your use case, that may help us prioritize. If you are interesting in contributing, please let us know and we'd be happy to discuss implementation or review a PR.

ggetz avatar Feb 23 '24 18:02 ggetz

There are several issues and forum threads that are revolving around that topic. Condensing them is a bit difficult, due to the slight differences in the terms that are used ("color", "material", "appearance", "style", "texture" and others for the thing that should be changed, and "node", "mesh", "primitive", "part" and others for the thing where the change should happen). Existing threads and workarounds often drilled holes into some._private._model._properties, and of course, zero of them are still working after the last model refactoring. Right now, it is only possible to change the material of a glTF model as a whole. But there is no way to acess sub-components (meshes/primitives) of that model, to change the material (or to do anything else with them, for that matter).

  • Be able to highlight a picked node: https://github.com/CesiumGS/cesium/issues/2387 . It has been closed, but only because the class ModelMesh that it refers to does no longer exist. The requirement is still there.
  • Highlight a single picked mesh in a gltf model: https://groups.google.com/g/cesium-dev/c/HGUDMzBBIeo
  • Change a model texture: https://github.com/CesiumGS/cesium/issues/5094 (this should be done on the level of the things that have textures - i.e. on the level of mesh primitives, and not the model as a whole)
  • "Select components" from within a model https://github.com/CesiumGS/cesium/issues/7009 (the goal is to show information on picks - probably some sort of extras/metadata)
  • Modify transparency of a "node" (i.e. a mesh), to show other meshes that may be hidden by it: https://github.com/CesiumGS/cesium/issues/8919
  • Add textures to individual parts of a (glTF) model that is otherwise untextured: https://community.cesium.com/t/how-to-change-models-material/28078
  • Changing the material of a single mesh in a model: https://community.cesium.com/t/changing-material-of-single-mesh-in-model/8462 (with broken workarounds and some "I-have-the-same-problem" posts...)
  • Chainging the material of a model after clicking it: https://community.cesium.com/t/how-to-color-specific-part-of-model/14898
  • Change a material of a model (this time, as a whole - this is possibe, but maybe not obvious): https://community.cesium.com/t/can-i-change-material-of-loaded-gltf-model/24993
  • Highlighting individual buildings that are combined in a glTF: https://community.cesium.com/t/highlighting-objects-using-entitymodelcolor-js/4474
  • Highlighting specific mesh in a glTF: https://community.cesium.com/t/gltf-mesh-picking-highlight/6765 (pointing to an open issue, and a comment two years later asking "What about now?"...)
  • Iterating over a model with the goal to change materials of meshes: https://community.cesium.com/t/iterate-over-loaded-gltf/19134
  • Change the color of a single building in a glTF: https://community.cesium.com/t/how-to-color-single-building-in-a-gltf/5156

javagl avatar Feb 23 '24 22:02 javagl

Thanks for the list of related forum threads @javagl! That's a big help.

Just to play devil's advocate, but would converting to a workflow using 3D Tiles and feature picking & styling better address these user's requirements?

ggetz avatar Feb 26 '24 13:02 ggetz

I'm not entirely sure what the last part referred to.

It might be what ... I actually started implementing a few days ago, namely: Iterate over all meshes/primitives/nodes of a glTF, and convert this into a tileset.json where each tile content is just a "sub-GLB" that only contains the respective mesh primitive.

But splitting a model like this raises a bunch of questions (e.g. what if there's a 4k x 4k texture that is used in all meshes as an atlas texture? Yeah, it would have to either be replicated in each GLB, or "pulled out" and referred to via a URL). Also, there is no reasonable way to retain animations and many other things with this approach...

So this cannot be "the solution". It could, at best, be a (quirky) workaround that might be applicable in certain, very constrained cases. But generally, people want to load a glTF model from a single GLB, and still have access to its components.

(One could dive into details of "what do people want to do with that". Maybe they want to programmatically restructure the asset, e.g. reparenting nodes or changing animation keyframes or whatnot. Not all of this would (or should, or could reasonably) be possible. But changing the material of a single mesh seems to be a very important use case, with a potentially good implementation-effort-to-usefulness ratio...)

javagl avatar Feb 26 '24 16:02 javagl

I'll post some more threads here as they pop up

  • Coloring a single part of a GLB: https://community.cesium.com/t/color-single-part-node-tile-in-a-tileset/30198
  • Applying a CustomShader to part of a GLB https://community.cesium.com/t/is-shader-applicable-to-a-full-glb-model-tileset-only/30199
  • Modify color of part of GLB https://community.cesium.com/t/selecting-elements-and-changing-its-color-of-glb/29076

javagl avatar Feb 28 '24 16:02 javagl

Any updates here @ggetz? As @javagl pointed out there are so many related questions and requests and #2387 even got the 'priority - high'-tag back in 2017.

Just to play devil's advocate, but would converting to a workflow using 3D Tiles and feature picking & styling better address these user's requirements?

I can not speak for all the other linked issues. But in the project in which I'm involved it would be so much simpler to handle this, when coloring a single gltf node would be possible. We have a site plan and are going to have hundreds of 3D building models consisting of several levels each (each level is a its own glTF file). There will be a feature to show a specific level of a building to have a look at the rooms on this floor. Each floor of each room is a single node in the level's glTF with its database id as name attribute. So when we have a model in Cesium and click on a floor of a building, we can already get the name of that node. Now we would like to color it as selected. Also we would want to color the room, when it was found in our search etc. So what I'm trying to say is, that everything would be ready for this, if one could color specific nodes of a glTF. And the alternatives are not very tempting:

  • If we would solve this by also having each room as a single glTF file, we would need to handle about 30k more files, tilesets would get way more confusing and also we would have to change major parts of our current workflow.
  • Using feature Ids, we would 'bloat up' our glTF files with information that they already contain (the name attribute of a node referring to a room, is the rooms id in our database => all information we need). Also, again, we would have to change our workflow and even write some extra scripts to modify the glTF files and create the property table(s). The latter being more annoying than it sounds because the 3D models will change over time.

ChrisClsg avatar Jul 02 '24 15:07 ChrisClsg

Hi @ChrisClsg, no updates yet. Thanks for the additional context!

If you are interesting in contributing, please let us know and we'd be happy to discuss implementation or review a PR. Thanks!

ggetz avatar Jul 02 '24 16:07 ggetz