Mesh Merge Normals
Fixing the shading seam where two mesh pieces meet
- BPY_OBJ
- BPY_OBJ
Join two mesh pieces together - say, a segmented eye plane glued onto a face mesh - and sometimes you get a faint crease running right along the seam, even though the surface there is dead flat. That's not a geometry problem. It's normals. Blender stores shading normals per vertex-per-face ("custom split normals"), and when two verts from two different sources happen to land at the same spot, their split normals usually don't agree, so the renderer shades that join like a hard edge. Mesh Merge Normals is Blender's one-line fix for that, exposed here as a ComfyUI node.
What it is and why you'd reach for it
This whole pack is built around chaining Blender's bpy mesh-editing operators through a ComfyUI graph, and this node is one of the plainest examples: it's a direct wrap of Blender's own "Merge Normals" operator. You'll want it anywhere your graph combines geometry from more than one source - after a Join Meshes step, after slicing a mask off a base plane and stitching it back, anywhere a seam could show up. It's cheap, it's non-destructive to the mesh's actual shape, and it only touches shading, so there's basically no reason not to run it after a join if you're chasing a weird dark line in your preview.
How it works
Averaging is the whole mechanism. Where multiple loop-normals share the same vertex position, the operator recalculates them into a single blended normal, so light falls across the join smoothly instead of snapping at a boundary. It doesn't move a single vertex - this is purely a lighting/shading fix, not a topology fix.
The inputs and outputs that matter
There's genuinely nothing to configure here - the node's schema is just BPY_OBJ in, BPY_OBJ out. No selection parameter is exposed, which is worth knowing: Blender's operator normally works on whatever's selected in Edit Mode, and since this node doesn't expose a selection input, it's almost certainly running against the whole mesh rather than a subset you pick. That makes it a blunt instrument - good for "smooth the whole thing out," not for surgical fixes on one specific seam while leaving the rest of the mesh's hard edges alone.
How to install it
Through ComfyUI Manager: search Avatar Graph (or avatar-graph-comfyui), install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/avatechai/avatar-graph-comfyui
cd avatar-graph-comfyui
python -m pip install -r requirements.txt
The one thing that trips people up before they even get this far: the pack depends on bpy, Blender packaged as a Python module, and bpy only ships wheels for specific Python minor versions. The README is explicit that you need Python 3.10.x - nothing else. On Windows the pack sidesteps this entirely by shipping its own embedded Python 3.10 build you unzip into your ComfyUI folder; on macOS/Linux, spin up a conda create --name comfyui python=3.10 environment before you install anything. Restart ComfyUI with --enable-cors-header (add --force-fp16 on Mac) if you want the live avatar preview panel talking to editor.avatech.ai - skip that flag and the graph still runs fine, you just won't get the real-time viewer, and you'd export the result as a .glb/.gltf instead.
Common issues
If pip install -r requirements.txt dies trying to build or fetch bpy, it's almost always the Python version - check python --version and confirm you're on 3.10 before debugging anything else. If you run this node and nothing visibly changes, that's often correct: it only fixes lighting artifacts at merged seams, so on a mesh with no seam problem it's a no-op. And feed it something - with no BPY_OBJ connected upstream there's no mesh to average normals across. The pack itself still carries a "we're still making changes" warning in its README, so if a node's behavior shifts between updates, that's the project, not you.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| BPY_OBJopt | BPY_OBJ | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| BPY_OBJ | BPY_OBJ | — |