Nodes/Melite Poser Nodes/🔧 Fix Mesh Winding (TRELLIS Cleanup)
ComfyUI Node

🔧 Fix Mesh Winding (TRELLIS Cleanup)

Why your TRELLIS mesh renders inside-out

By JayDataEngineer·Created 2 months ago·Updated 5 days ago· 1
🔧 Fix Mesh Winding (TRELLIS Cleanup)
    • glb_path
    ◄glb_path—►
    â—„preserve_rigfalseâ–º

    You drop a generated GLB into a viewer and half the surface is black, or flat-shading spikes shoot out of the shoulders like the model is having a bad day. That's not a lighting bug and it's not your renderer - a big chunk of the faces have their vertices wound backwards, so their geometric normal points into the body. MeshFixWinding is a single-purpose fix for exactly that, and the pack's own docstring says it plainly: TRELLIS output arrives with roughly 25–45% of faces inward-facing.

    If you've ever watched a vision model score your asset 1/10 and call it "severe mesh corruption", this is usually the cause. The silhouette looks fine in a thumbnail; the normals are garbage.

    How it works

    For every triangle it computes the geometric normal with a cross product, then compares it against a vector from the mesh centroid to the face centre. Dot product negative means the face is pointing back toward the middle of the object, so it swaps vertex 1 and vertex 2, which flips the normal outward. Then it writes the patched indices back into the BIN chunk and re-emits the GLB.

    There's a second job hiding in the same node: texture re-encoding. Generated meshes often pack WebP textures, and a lot of downstream consumers choke on those. With preserve_rig off (the default), it also converts packed textures to PNG. That's why the flag exists - the conversion runs the mesh through a trimesh round-trip, which is not something you want happening to a rigged file.

    Inputs and outputs

    • glb_path - the GLB to repair: a filename in ComfyUI's input/, or an absolute path.
    • preserve_rig - leave false for fresh TRELLIS output you're about to texture and rig. Flip it to true for any GLB that already has skinning, joints, or animation, so the texture pass is skipped and the rig stays intact.

    The output is a new glb_path in ComfyUI's output/, with a three_model UI entry pointing at it. It's marked as an output node, so it fires even with nothing wired after it.

    Where you'd put it in a workflow

    Front of the mesh chain. Generate → Fix Winding → dedup → decimate → rig/texture. Doing this last is a common mistake: if you fix winding after you've already baked a normal map or projected a texture, you've done the work against broken normals and you get to start over.

    Install

    cd /path/to/ComfyUI/custom_nodes
    git clone https://github.com/JayDataEngineer/melite-poser-nodes.git
    

    Restart ComfyUI, or install the pack from ComfyUI Manager by searching melite-poser-nodes. requirements.txt pulls py-soma-x[anny], trimesh and xatlas - the fix-winding path itself needs trimesh (for the texture re-encode) plus numpy and PIL, which ComfyUI already has.

    Where people get burned

    The centroid test is a heuristic, and it fails on concave shapes. "Face points away from the middle of the object" is true for a torso, a sword, a helmet shell. It is wrong for geometry that legitimately faces inward: the inside of a cup, the inner surface of a hollow coat, an ear canal, a hollow skull. Those faces can get flipped away from you and now the interior renders backwards. If you're cleaning something with real hollow structure, check the result in a viewer instead of trusting the log percentage.

    Only the first primitive gets fixed. The flip pass reads meshes[0].primitives[0] - one primitive. A GLB with multiple primitives per mesh (common when a model has several material slots) will have the others left exactly as they were. If your asset has more than one material, run the node and then look at the parts, don't assume it's uniform.

    preserve_rig: false on a rigged file is not recoverable. The PNG conversion rebuilds the mesh from scratch. Keep the original. There is no undo beyond re-running upstream.

    Nothing here fixes self-intersections or non-manifold geometry. Winding is one specific defect. If the mesh is still ugly after this, the problem is topology, and the honest advice from the KB's 3D generation doc applies: no open model gives you production topology, so for anything that has to deform you're retopologising anyway.

    The pack is MIT, published from an internal estate pipeline in late 2026, and has no public issue tracker chatter to lean on - the class docstring is unusually candid about the mechanism, which is exactly what made this article possible. Read the source when the output surprises you; it's short.

    CategoryTechNoir/Mesh

    Inputs (2)

    NameTypeDefaultDescription
    glb_pathSTRING—
    preserve_rigBOOLEANfalse—

    Outputs (1)

    NameTypeDescription
    glb_pathSTRING—