Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLTFLoader: Order of nodes in hierarchy is non-deterministic in some cases when compression is used #25820

Closed
hybridherbst opened this issue Apr 12, 2023 · 13 comments · Fixed by #25913
Labels

Comments

@hybridherbst
Copy link
Contributor

Description

When authoring models that use transparency for real-time use, often the order of nodes in the hierarchy is the only option for artists to control transparency sorting. However, it looks like when compression (draco) is used, the hierarchy resulting from a file is non-deterministic - sometimes node A comes before node B and sometimes after, potentially altering the resulting appearance.

The attached file exhibits this behaviour in three-based viewers, e.g.

TransparencyOrder.zip

Video of the issue: dropping the same file results in different results on different attempts. For some reason, after a few attempts the result "stabilizes" until the page is reloaded.
https://user-images.githubusercontent.com/2693840/231571409-6cb75554-bd70-4419-ae6a-ea30b7b71646.mp4

Looking at the resulting scene hierarchy, in some cases "Interior" comes after "Exterior" but sometimes the order is reverted. This seems to only happen when compression is used.

Curiously, I can't get this to reproduce in https://modelviewer.dev/editor/; @elalish are you using custom transparency sorting?

Reproduction steps

  1. Open https://gltf-viewer.donmccurdy.com/ or other viewers that use default three.js GLTFLoader + rendering
  2. Drop the file attached above
  3. Drop the file again - in some cases you'll see an appearance change
  4. Drop the file again - appearance will likely change back
  5. Refresh the page and repeat 2-4; in some cases one version will already be present at the start, in others subsequent loading will show it

Code

Live example

Screenshots

No response

Version

latest

Device

Desktop, Mobile

Browser

Chrome

OS

Windows

@elalish
Copy link
Contributor

elalish commented Apr 12, 2023

No, I don't do anything special except to clone the scene, but I doubt that's the difference. Considering it's DRACO-related, have you tried different versions of their decoder? They do fix a bug occasionally.

@hybridherbst
Copy link
Contributor Author

I'm not actually sure it's directly DRACO-related - my gut feel is that it's "some async work happens and under some conditions that changes the order of nodes" related. DRACO decoding may just be triggering the problem here.

I think one question is if "node order is deterministic" is a design goal for glTF in three.js. I asked in the glTF slack and the spec people as usual say that the glTF spec doesn't have an opinion on such mundane things as "defined order of nodes". cc @donmccurdy, would be curious what you think about that in this context

@takahirox
Copy link
Collaborator

takahirox commented Apr 14, 2023

Personally I want the node order to be deterministic unless it requires a lot of complexity in the GLTFLoader because the deterministic order may help testing, debugging, import-export circular, and so on.

And I thought the GLTFLoader is designed to keep the deterministic node order (Update: the loader didn't guarantee the order before, but at some point we changed to guarantee the order), but am not really sure if we tested/reviewed well with DRACO. If the node order is not deterministic in a certain scenario with or without DRACO, personally I want to fix it (unless it requires complexity in the code).

@elalish
Copy link
Contributor

elalish commented Apr 14, 2023

I vaguely recall @donmccurdy telling me at some point that GLTFLoader would order things pretty arbitrarily, hopefully he can chime in here. If you really need a file-based order, you can achieve it (I think) with the associations that are returned. It's quite common for implementations to mix up the nodes especially between import and export, so the rule is to not rely on it, hence the use of names.

@hybridherbst
Copy link
Contributor Author

Yeah, that's why I posed it as an issue/question here, to understand more what the general consensus is. Given that glTF doesn't have any tools for artists to specify rendering order of objects besides node order, I do understand that artists try to use this (as in the file above) for design choices. By now I've seen a lot of glass objects (think glass inside glass inside glass, like a fancy LED lightbulb) that only work because of specific node orders, so I'm curious to learn more.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Apr 14, 2023

The object order is somewhat arbitrary (e.g. should a node's light come before or after its mesh?), but certainly intended to be deterministic and influenced by the order of node children in glTF. No question that is a design goal. Probably the Draco compression just introduces some additional timing complexity (decoding w/ Web Workers) that breaks determinism here, and we should investigate that.

@donmccurdy
Copy link
Collaborator

It looks to me like what differs is not the order of nodes in the hierarchy, but the render order. Screen capture:

transparency_order.mov

Note the printer order on the RHS of the screen is the same each time, but the render changes. I tried again with a slightly modified version of the scene where pivots are centered in each geometry, and that fixes the issue as you might expect, though I understand that's not always an option.

@hybridherbst - are you seeing something else indicating a change in hierarchy? Or should we be looking for a different cause?

@donmccurdy
Copy link
Collaborator

donmccurdy commented Apr 24, 2023

@Mugen87 have we considered sorting on something other than object origin? For example:

  • (A) center of bounding box
  • (B) nearest point on bounding box

I wonder if either of those would be more robust against this situation.

EDIT: Here was the thread: google/model-viewer#3155 (comment)

@hybridherbst
Copy link
Contributor Author

@donmccurdy I had investigated this and it is indeed a change in order of hierarchy, not just sorting. I don't think this issue should be closed yet.

@donmccurdy
Copy link
Collaborator

I've tried a few different ways and can't reproduce any change in hierarchy – do you see that in the console logs of https://gltf-viewer.donmccurdy.com/ ? Or could you share a demo demonstrating the hierarchy change issue explicitly?

@hybridherbst
Copy link
Contributor Author

I'll try to demonstrate it.
We're also seeing the issue (gltfloader changing the hierarchy from what's in the file) when some nodes are animated and others are not. I'd still like this issue to be reopened if possible :)

@donmccurdy donmccurdy reopened this May 6, 2023
@donmccurdy
Copy link
Collaborator

donmccurdy commented May 6, 2023

Reopened! I think we will need a clear example for the change in node hierarchy to investigate further though. Without a way to reproduce the reported issue, I will eventually need to close this.

@donmccurdy
Copy link
Collaborator

Closing as "can't reproduce", happy to reopen if that can be addressed.

@donmccurdy donmccurdy closed this as not planned Won't fix, can't repro, duplicate, stale Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants