Skip to content

Conversation

@evnchn
Copy link
Collaborator

@evnchn evnchn commented Feb 2, 2026

Motivation

Fix #3515, where GLTF models load asynchronously as Groups, so material settings were being ignored.

Particularly, there are 3 cases to resolve (from #3515 (comment)):

  1. Calling material() on a group (or GLTF object) does not work, because the JavaScript implementation of the material() method doesn't traverse children of groups.
  2. Calling material() on a group (or GLTF object) does not work, because the group is added first and their children are added later. So traversing the group doesn't help, because there are no children yet.
  3. Calling material() immediately after creating the GLTF object does not work, because the GLTF loader loads the object(s) asynchronously. Only when this is finished, material() can actually find the corresponding objects.

NOTE: right now the test sample I can only test the GLTF case, not the group case though.

Implementation

TL-DR: Now stores pending material info on Group objects and applies settings to all mesh children after the model loads.

Material handling improvements:

  • Refactored the material method: Now, if the target object is a group (e.g., a GLTF model), material settings are stored in pendingMaterialInfo and applied to all child meshes once the group is loaded. For non-group objects, material settings are applied directly.
  • Added the applyMaterialSettings method to encapsulate the logic for updating material properties and refactored existing code to use this method.

GLTF loading enhancements:

  • Modified the GLTF loader callback to check for pendingMaterialInfo on a group after loading, and apply material settings to all child meshes using applyMaterialSettings. This ensures that material updates requested before model load are not lost.

Progress

  • I chose a meaningful title that completes the sentence: "If applied, this PR will..."
  • The implementation is complete.
  • If this PR addresses a security issue, it has been coordinated via the security advisory process.
  • Pytests pending. Likely tough and may require pixel-counting...
  • Documentation is not necessary for a bugfix.

GLTF models load asynchronously as Groups, so material settings were
being ignored. Now stores pending material info on Group objects and
applies settings to all mesh children after the model loads.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@evnchn evnchn added the bug Type/scope: Incorrect behavior in existing functionality label Feb 2, 2026
@evnchn
Copy link
Collaborator Author

evnchn commented Feb 2, 2026

This indeed does not fix the group case:

    with ui_3d_scene.group().material('#00ffff', side='both'):
        ui_3d_scene.box(1, 1, 1)

Box still white...

@evnchn
Copy link
Collaborator Author

evnchn commented Feb 2, 2026

Not sure if we really should fix the group case. I got a fix in local which does it, but then I don't see a way to override the material once an object is in a group, which sounds hardly like a good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Type/scope: Incorrect behavior in existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Double-sided material property not applied to objects loaded from gltf

1 participant