🎨 Swap BaseColor Texture (projected→rigged, preserve rig)
Keep the rig, steal the texture
- textured_rigged_glb_path
If you've done texture projection on a rigged character with ComfyUI-3D-Pack, you know this pain. [Comfy3D] Save 3D Mesh does a trimesh round-trip on export, and that round-trip silently drops the entire rig - skins, joints, WEIGHTS_0/JOINTS_0, the node hierarchy, animation samplers. You get a beautifully textured mesh that no longer bends.
So you have two files: the original rigged GLB with stale textures, and the freshly projected GLB with no bones. Swap BaseColor Texture is the surgical answer - take the projected texture out of one, drop it into the other, touch nothing else.
How it works
Two passes over the GLB JSON. First it locates the projected file's baseColorTexture image and pulls out the raw PNG bytes plus its MIME type. Then it resolves the original rigged file's same texture slot and writes the new image in, reusing the incoming image index while leaving the rest of the document alone - the rig, the skins, the joints, the animations, the node hierarchy, all untouched. The output is a textured and rigged GLB that the rest of the pack can consume: RaySomaxBake to animate it, CompositeCharacter to assemble it.
This is a ComfyUI node port of a helper the pack's server-side pipeline already had, so the behaviour is the same thing the author's own tooling was doing over HTTP, now wired into the graph.
Inputs and outputs
projected_glb_path- the derigged, textured GLB out of Comfy3D's Save 3D Mesh. Resolves against ComfyUI'sinput/first, thenoutput/, then an absolute path, so a node that just wrote intooutput/chains fine.rigged_glb_path- the original rigged GLB. ItsbaseColorTexturegets replaced; everything else survives.
One output: textured_rigged_glb_path, written to output/. The node also surfaces the source filenames and a textured: true flag in its UI payload, which helps when you're chaining several of these and want to confirm which is which. Output node - it runs on its own.
Install
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/JayDataEngineer/melite-poser-nodes.git
Restart, or install melite-poser-nodes from ComfyUI Manager. Pack deps are py-soma-x[anny], trimesh and xatlas, but this node needs none of them - it's pure JSON and buffer manipulation. Which is lucky, because the other half of this workflow is ComfyUI-3D-Pack territory, and the KB's 3D generation doc is honest about how that goes: the pack depends on a stack of compiled CUDA extensions pinned to one exact torch/CUDA combination, ships prebuilt wheels for a single target, and has an issue tracker with things like "it is absolutely impossible to install this" on it. Budget an evening if you're building it from scratch, or use a packaged installer.
Where people get burned
Your projected GLB must actually contain a baseColorTexture image. This node extracts one; it can't invent one. A vertex-coloured or material-less export has nothing to lift, and you'll get a lookup failure rather than a nice default.
It swaps base colour only. No normal map, no metallic-roughness, no occlusion. If your projected pass produced other channels and you were hoping to bring them across, this isn't that node.
Matching UV layouts are assumed. The projection pipeline normally re-uses the same geometry UVs, so a straight image swap makes sense. If someone re-unwrapped the mesh between the two files, you're swapping a texture into a UV space it wasn't painted for, and it'll look like a bad decal. Same mesh, same UVs, or don't bother.
Path resolution is input → output → absolute. Slightly different from the sibling nodes that want input/ only, which is nice, but it also means a stale file of the same name in input/ can shadow the fresher one in output/. Name your intermediates distinctly.
This is a workaround, remember. The reason it exists is that the 3D-Pack's mesh exporter loses rigs. If a future version of that exporter preserves skins, this node becomes a no-op you can delete - the author's own README calls the whole pack "zero-deviation" tooling, i.e. glue that exists to stitch gaps between other tools.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| projected_glb_path | STRING | Derigged textured GLB from [Comfy3D] Save 3D Mesh (filename in input/ or output/, or absolute path). | |
| rigged_glb_path | STRING | ORIGINAL rigged GLB (skin/joints/weights preserved). Its baseColorTexture is replaced. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| textured_rigged_glb_path | STRING | — |