Fix material settings not applying to GLTF models#5708
Fix material settings not applying to GLTF models#5708evnchn wants to merge 1 commit intozauberzeug:mainfrom
Conversation
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 <noreply@anthropic.com>
|
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... |
|
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. |
|
I just added MREs for each of the three problems: #3515 (comment). # Problem 1: Group material is not applied to child objects
with ui.scene() as scene:
with scene.group() as group:
scene.sphere()
group.material('red')
# Problem 2: Group is still empty when created with material
with ui.scene() as scene:
with scene.group().material('red'):
scene.sphere()
# Problem 3: GLTF loader is not ready when applying material
avocado = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Avocado/glTF-Binary/Avocado.glb'
with ui.scene() as scene:
scene.gltf(avocado).material('red').scale(100)At the moment, this PR only solves problem 3. Solving problem 2 could be considered a breaking change, because it would turn this blue sphere red: with scene.group().material('red'):
scene.sphere().material('blue')Instead we could agree that material is only applied to the currently existing children and you need to apply it later (like in the first example) if you want to color all children. Problem 1 could probably be easily solved by traversing the group when applying material. Overall I'm not 100% sure about the desired behavior. If Three.js doesn't automatically apply group material to children, maybe we shouldn't try doing it ourselves. Maybe there's a way to initialize objects with undefined material so that Three.js automatically applies their group's material (if any)? |
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)):
NOTE: right now the test sample I can only test the GLTF case, not the
groupcase 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:
materialmethod: Now, if the target object is a group (e.g., a GLTF model), material settings are stored inpendingMaterialInfoand applied to all child meshes once the group is loaded. For non-group objects, material settings are applied directly.applyMaterialSettingsmethod to encapsulate the logic for updating material properties and refactored existing code to use this method.GLTF loading enhancements:
pendingMaterialInfoon a group after loading, and apply material settings to all child meshes usingapplyMaterialSettings. This ensures that material updates requested before model load are not lost.Progress