Apply Texture to GLB
Repaint a GLB's texture without breaking its rig
- texture
- glb
Image-to-3D in 2026 gives you a usable mesh and a texture you'd rather replace. The silhouette is often fine; the albedo looks like a photo of a painting of a table. So you generate a fresh top-down texture in ComfyUI - Flux, Qwen, whatever - and now you need it on the .glb without touching the geometry, the UVs, the skin, or the animation tracks that took the model three minutes to produce.
That's the whole job of LF_ApplyTextureToGLB. It bolts one image onto one material of one existing GLB and hands you back the file in memory.
How it works
The clever part is what it doesn't do. It never re-exports the scene. It parses the GLB's JSON chunk, appends a PNG to the binary chunk, clones the texture binding, and points the selected material's base-color texture index at the new image. The original binary prefix is preserved byte for byte, so the scene graph, geometry, UV sets, inverse bind matrices, skeletons, animations and material settings all survive untouched. Other materials that happened to share the old image reference stay on the old image - only material_index changes.
Two constraints fall out of that approach, and they're the ones that bite. The GLB must be self-contained GLB 2 with embedded images, and the texture source must be a texture source - Blender's exporter and most "export glTF binary" paths produce this, but a glTF with sidecar .bin and .png files, or a file using an extension like KHR_texture_basisu, fails explicitly rather than half-working.
The inputs and outputs that matter
source_glb- an absolute path to a.glbon disk, or a filename resolved through ComfyUI's input folder. It is read-only; nothing anywhere writes back to your source file.texture- exactly one RGB or RGBA image. Batches and lists raise an error instead of silently picking one. Supplied alpha is preserved, but the source material's own alpha mode (OPAQUE / MASK / BLEND) still applies.material_index- default 0, zero-based. Set this one deliberately: it's which material's base-colour map gets replaced.glb- the only output, aFILE_3D_GLB. Wire it into Comfy's Preview 3D (Advanced) to look at it,SaveGLBto write it, or straight intoLF_ScaleGLBNodesif you're also fixing proportions.
The graph cache behaves itself here: the node hashes the source file, so editing or re-exporting the GLB invalidates it and you don't sit there wondering why your new mesh looks old.
How to install it
ComfyUI Manager → search LF Nodes → install → restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/lucafoscili/lf-nodes
python -m pip install -r lf-nodes/requirements.txt
Run that pip line with the interpreter that actually runs ComfyUI, not a system Python. Two install notes specific to this pack, because it's 154 nodes in one repo: the requirements are not small (torch, av>=17, opencv-python, rembg, onnxruntime, transformers, kornia, timm), so a fresh install pulls real weight even if you only want the GLB nodes. And there's an older, archived repo - lucafoscili/comfyui-lf - that the author retired in October 2025 and replaced with this one. Plenty of older tutorials still link it. You want lf-nodes.
No model downloads. This node is pure Python on a file you already have.
Common issues & troubleshooting
"Expected a complete GLB 2 file." You fed it a GLB 1, or a truncated download, or a .gltf renamed to .glb. Re-export as glTF Binary.
It fails on a GLB that opens fine in other viewers. External resources - a glTF with a separate texture file, or a texture-source extension. Fix it by re-exporting with images embedded. The tooltip says "self-contained" and means it.
Nothing visibly changes. Wrong material_index. A generated asset can easily carry three or four materials (body, hair, clothing, base plate), and the index follows the order in the file, not the order in Blender's outliner. Open the GLB in Blender, look at the material list, count from zero. Also check you're not previewing a cached copy - SaveGLB the output if you're unsure you're looking at the new bytes.
Transparency looks wrong. The node preserves your alpha but doesn't change the material's alpha mode. A cut-out PNG dropped on an OPAQUE material renders with hard black instead of transparent.
A batch of textures errors out. By design: one texture, one material, per node. For a set of variants, run one node per material or loop the graph.
Last thing worth knowing: this doesn't unwrap UVs and it doesn't project anything. If your texture is a full atlas and your model's UVs are machine-generated garbage - which, per the community's own blunt assessment of image-to-3D, they usually are - a texture swap will faithfully show you garbage mapping. Fix the UVs in Blender first, or accept the stretch.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| source_glb | STRING | Existing absolute GLB filepath or Comfy input filename. Read only; no source copies. | |
| texture | IMAGE | Exactly one RGB/RGBA texture. Preserves supplied alpha and material alpha mode. | |
| material_index | INT | 0 | Replace only this material base-color map; shared maps on other materials stay unchanged. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| glb | FILE_3D_GLB | In-memory GLB with the selected base-color texture; geometry, UVs, skins and animations retained. |