Nodes/ComfyUI-GNM/GNM Head Render
ComfyUI Node

GNM Head Render

A real 3D head, plus ControlNet-ready depth and normal maps

By soylab-edu·Created 2 months ago·Updated 2 months ago· 10
GNM Head Render
  • gnm_model
  • identity
  • expression
  • image
  • normal_map
  • depth_map
  • mask
width512
height512
head_yaw0.0
head_pitch0.0
head_roll0.0
eyes_yaw0.0
eyes_pitch0.0
camera_azimuth0.0
camera_elevation0.0
zoom1.00
fov25
background0.95
surface
mesh_parts
antialias2

If you've ever wanted the exact geometry of a face before the diffusion model invents one, GNMHeadRender is the node you came for. It's the workhorse of ComfyUI-GNM: feed it an identity vector and an expression vector, pose the head any way you like, and out the other side come four things - the color image, a normal map, a depth map, and a mask. The normal and depth maps are the point, because they're exactly what ControlNet-style conditioning eats for breakfast.

The context matters here. ControlNet conditions generation on spatial structure - edges, depth, pose - so the prompt decides what appears and the condition decides where it goes. Most people extract that structure from a photograph with a preprocessor. GNM is the weirder, more powerful path: generate the structure yourself, from a head you can pose and sculpt, so the condition is exactly the face you designed instead of the face a preprocessor happened to find. It's the same impulse as the "consistent characters via geometry" crowd - you're not hoping the prompt holds, you're handing the sampler a map.

How it works, mechanically: the model runs a forward pass - gnm(identity, expression, rotations) - to produce the mesh vertices, then the pack's own renderer (it drives pyrender directly, deliberately bypassing GNM's osmesa-forcing wrapper that breaks on Windows) draws the color, normal, and depth passes plus a mask. The heavy hitters among the inputs:

  • gnm_model - from the loader. Required.
  • identity and expression - optional. Leave them unwired and you get the average/template face, which is a feature, not a bug.
  • head_yaw/pitch/roll - neck-joint rotation in degrees; eyes_yaw/pitch - eyeball rotation.
  • camera_azimuth/elevation - orbit the camera (0/0 is dead-on front), with zoom and fov for framing.
  • surface - plain (flat material, cleanest normal/depth) or edgeflow_texture (GNM's default texture for the color pass).
  • mesh_parts - face_default (eyelid skin excluded, the GNM default) or all.
  • width/height - up to 4096; antialias 1–4; background gray level 0–1.

Outputs: image, normal_map, depth_map, mask. Wire the maps into a depth or normal ControlNet Apply and render away. One caveat the ecosystem keeps rediscovering: the post-Flux union ControlNets trimmed their condition menu and normal maps were among the casualties - so this shines brightest on SD/SDXL, or wherever a normal ControlNet still exists.

Install

ComfyUI Manager is the easy path: Custom Nodes → search "ComfyUI-GNM" → Install, then restart. Or clone by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/soylab-edu/ComfyUI-GNM
cd ComfyUI-GNM
pip install -r requirements.txt

The model data ships in vendor/ (a 51MB npz) - no separate download. The renderer needs pyrender, pyglet<2, and the pack's pinned PyOpenGL==3.1.10 (pyrender's default 3.1.0 breaks on Python 3.13 / numpy 2).

Common issues

The render node is where this pack's environment quirks live. Headless Linux servers need PYOPENGL_PLATFORM=egl set before launch - the README calls it out explicitly; Windows should just work via WGL. If you hit a pyrender import error, the requirements didn't land, and mind the pyglet<2 pin because newer pyglet breaks pyrender's GL context. Expect the first render to be slow while the model loads and caches; everything after that is fast.

CategoryGNM

Inputs (18)

NameTypeDefaultDescription
gnm_modelGNM_MODEL
widthINT51264–4096
heightINT51264–4096
head_yawFLOAT0.0-90–90
head_pitchFLOAT0.0-90–90
head_rollFLOAT0.0-90–90
eyes_yawFLOAT0.0-40–40
eyes_pitchFLOAT0.0-30–30
camera_azimuthFLOAT0.0-180–180
camera_elevationFLOAT0.0-89–89
zoomFLOAT1.000.2–5
fovFLOAT255–90
backgroundFLOAT0.950–1
surfaceCOMBO2 options: plain, edgeflow_texture
mesh_partsCOMBO2 options: face_default, all
antialiasINT21–4
identityoptGNM_IDENTITY
expressionoptGNM_EXPRESSION

Outputs (4)

NameTypeDescription
imageIMAGE
normal_mapIMAGE
depth_mapIMAGE
maskMASK