UV Snap Selected
The node that keeps avatar UVs on the texel grid
- BPY_OBJ
- BPY_OBJ
Texture bleeding is the enemy, and UV Snap Selected is one of your best weapons against it. It takes the selected UVs and snaps them to a target - most importantly the pixel grid - so that island edges land exactly on texel boundaries instead of straddling them. On an animated avatar, that's the difference between a crisp mouth line and a smeared one.
It wraps Blender's bpy.ops.uv.snap_selected() in the Avatar Graph pack's auto-generated Blender operator family. Like all the UV nodes here it runs inside the pack's embedded Blender scene, in edit mode on your BPY_OBJ, and hands the same mesh back with the selection's coordinates rewritten.
The target setting
The single input that matters:
- target - one of:
PIXELS- snap to the nearest texel corner. This is the one you'll reach for constantly. When two islands share an edge in the texture, snapping both to the pixel grid makes the shared boundary land on exactly the same texels, so there's no half-pixel gap to bleed through during animation.CURSOR- snap the selected UVs to the 2D cursor's location. Moves a whole selection to a point you aimed at earlier (see UV Snap Cursor).CURSOR_OFFSET- move the selection by the distance it is from the cursor, snapping relative offsets. Fiddly, and rarely needed in avatar work.ADJACENT_UNSELECTED- snap each selected UV to the nearest unselected UV. The merge-adjacent cleanup: pull stray duplicated UVs onto their neighbors so the seam disappears.
How it works and why it fits
Standard wrapper behavior: select what you want to align, run the node, and the selection's UV coordinates get quantized to the target. Selection persists on the mesh, so snapping is a natural step between selecting an island and exporting or shape-keying it. In a lipsync rig, the mouth's UV outline snapped to PIXELS is what keeps the open-mouth texture from crawling across the closed-mouth one.
Inputs and outputs
- BPY_OBJ in/out - the mesh object.
- target - the enum above.
Installing it
Same pack, same install. Avatar Graph pins bpy==3.6.0, which means Python 3.10 in your ComfyUI environment or nothing loads. ComfyUI Manager: search "Avatar Graph." Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/avatechai/avatar-graph-comfyui
cd avatar-graph-comfyui
python -m pip install -r requirements.txt
Restart ComfyUI, and let the first launch download the SAM ViT-H model (~2.5 GB) plus mediapipe landmarkers in the background. Run ComfyUI with --enable-cors-header for the live preview in editor.avatech.ai; otherwise export a .GLB via right-click on Avatar Main Output.
Troubleshooting
If snapping to PIXELS doesn't seem to change anything, it's usually because your selection was already on the grid - nothing to snap. If it looks like it snapped but the texture still bleeds, the other island on the shared boundary probably wasn't snapped too; snap both sides. And ADJACENT_UNSELECTED will silently merge UVs if they're close enough - if vertices vanish on you, that's not a bug, that's the operator welding them, so make sure that's what you wanted before running it.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| BPY_OBJopt | BPY_OBJ | — | |
| targetopt | COMBO | 4 options: PIXELS, CURSOR, CURSOR_OFFSET, ADJACENT_UNSELECTED |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| BPY_OBJ | BPY_OBJ | — |