Skin Apply (attach detail maps to a SOMAX body)
Bolt albedo and normal maps onto a rigged body without touching the rig
- albedo
- normal
- glb_path
- skin_record
Texture and rig are two separate problems, and the tools that solve one usually break the other. That's the whole reason this node exists: it takes a body GLB with joints, weights and animations intact, adds a skin material to it, and writes it back out - without a mesh round-trip, without rebuilding anything.
If you've been burned by an exporter that stitched the rig off to do a texture pass (looking at you, Comfy3D's Save 3D Mesh), this is a much more careful way to do it.
How it works
Bytes surgery on the glTF document. It parses the GLB, checks that every primitive has TEXCOORD_0 - a body without UVs is refused, because "detail maps have nowhere to land" - then appends the albedo and normal PNGs into the binary chunk as new buffer views, registers them as images, adds a texture sampler and two textures, and points the material's baseColorTexture at the albedo.
The material values are hard-set rather than defaulted, and the reasoning is in the comments. The albedo and normal are attached with the meld skin law: metallic 0, roughness 0.82, normalTexture.scale: 0.0. The comment explains the author's own bug - UV-path bump through the projection's tangent space produces visible mottling, "skin on the actual character is fucked" - so the normal map is packed in for later harvest but muted at scale 0 for now. Metallic and roughness are overwritten rather than setdefault, because in their pipeline the placeholder template values (a roughness of 0.85, say) need to lose to the skin law every time.
The sampler is set to repeat wrapping with linear filtering and mipmapping, so tiling detail maps behave themselves.
It returns a record alongside the GLB: how many materials were touched, how many primitives, the PNG sizes, the sampler mode, and the law that was applied (meld-4.38-v1.4-bump-off). That's your receipt.
Inputs and outputs
body_glb_path- the body to skin, resolved from ComfyUI'sinput/or as an absolute path.albedo- an IMAGE.SkinPack's albedo output is the obvious source.normal- an IMAGE. Same, fromSkinPack.
Two outputs: glb_path (the skinned GLB, written to output/) and skin_record, a JSON string of the record. It's an output node, so it runs on its own, and the log line includes the materials-touched count.
Install
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/JayDataEngineer/melite-poser-nodes.git
Restart, or install melite-poser-nodes via ComfyUI Manager. Pack deps are py-soma-x[anny], trimesh and xatlas, and this node needs none of them - numpy, PIL and hand-rolled GLB parsing. py-soma-x only matters if you're generating the body in the same graph.
Where people get burned
UVs are mandatory and the error is specific. A primitive without TEXCOORD_0 gets refused with the primitive indices listed - "detail maps have nowhere to land (non-somax UVs)". That's the classic case of a mesh that was exported without a proper unwrap. Nothing to fix at this node; go re-UV upstream.
It will not alter your rig - including when you wish it would. No joints, no weights, no animations are touched. If the body you're skinning has bad weights, this node will faithfully apply a lovely texture to a badly deforming mesh.
One material, all of them. Every material in the document gets the new base colour texture and the muted normal. On a multi-material body you'll texture parts that maybe shouldn't be skin. The record tells you how many were touched, so check it rather than assuming.
The material factors are opinionated. Roughness 0.82 and metallic 0 are hard-set, so a body whose authored materials had a deliberate glossy or metallic look will come out matte. That's the pack's "meld" look, not a neutral default.
Non-GLB bytes get refused. The check is deliberate - a .gltf+.bin pair or an .obj won't work here; you need a self-contained binary glTF.
Pair this with SkinPack for the maps and CompositeCharacter afterwards to add hair and outfit on top; the ordering matters, since the composite operates on GLB paths and doesn't care about materials.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| body_glb_path | STRING | — | |
| albedo | IMAGE | — | |
| normal | IMAGE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| glb_path | STRING | — |
| skin_record | STRING | — |