Nodes/ComfyUI-GNM/GNM Head Viewport
ComfyUI Node

GNM Head Viewport

GNM Head Viewport is the fun one

By soylab-edu·Created 2 months ago·Updated 2 months ago· 10
GNM Head Viewport
    • image
    • normal_map
    • depth_map
    • mask
    gender
    ethnicity
    identity_seed0
    identity_strength1.00
    expression
    expression_seed0
    expression_strength1.00
    head_yaw0.0
    head_pitch0.0
    head_roll0.0
    eyes_yaw0.0
    eyes_pitch0.0
    camera_azimuth0.0
    camera_elevation0.0
    zoom1.00
    fov25
    width512
    height512
    background0.95
    surface
    antialias2

    ComfyUI-GNM's GNMHeadViewport is the node that makes the whole pack feel like a toy, in the best way. Drop it on the canvas, wire image to a Preview node, and you have a live 3D head you can drag sliders on - no queueing, no waiting for a render. Drag on the preview itself to orbit the camera; scroll to zoom. It's the closest thing this pack has to a videogame.

    It's also a genuine all-in-one: everything the separate nodes do, in one box, with the model loaded internally - no GNM_MODEL wire required. Every face-relevant widget is right there: gender, ethnicity, identity_seed + identity_strength, the 20-class expression dropdown with its own expression_seed + expression_strength, plus head/eyes rotation, camera azimuth/elevation, zoom, fov, surface, and antialias. The outputs are the same four as the render node: image, normal_map, depth_map, mask.

    The trick that makes it feel instant: the frontend is a three.js viewport that POSTs the current widget values to a /gnm/viewport/preview endpoint on ComfyUI's own server, debounced so it doesn't spam. That endpoint runs the same pyrender pipeline as the final render, downscaled, and returns a preview - which is why what you see is exactly what you get. Drag the camera and the preview writes the new angles back into the camera_azimuth/camera_elevation widgets, so the queued render comes out in the exact composition you previewed.

    Two practical notes. First, the preview runs low-res while you're actively dragging so it stays smooth, then refines to a sharper image once you let go - but a queued render is always the full width/height you set, at full resolution. Second, this is the node for fast random faces: seeds, demographics, expression, done, and the same ControlNet-ready normal/depth/mask outputs come out the other side. If you want to sculpt individual facial components instead of rolling dice, that's what the Advanced and Pro variants are for.

    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
    

    Model data ships in vendor/; no separate download, no TensorFlow. The viewport needs the web extension plus the renderer deps (pyrender, pyglet<2, pinned PyOpenGL==3.1.10).

    Common issues

    If the live preview never appears, the server routes didn't register. The pack prints [ComfyUI-GNM] live viewport endpoints registered on startup - if you don't see that line, ComfyUI was probably already running when you installed, so restart it. And the same renderer notes as the render node apply: headless Linux needs PYOPENGL_PLATFORM=egl, and the pyglet<2 pin is there for a reason - newer pyglet breaks pyrender's GL context.

    CategoryGNM

    Inputs (21)

    NameTypeDefaultDescription
    genderCOMBO2 options: female, male
    ethnicityCOMBO4 options: middle_eastern, asian, white, black
    identity_seedINT00–18446744073709550000
    identity_strengthFLOAT1.000–3
    expressionCOMBO20 options: surprise, disgust, suck, compress_face, stretch_face, happy, +14
    expression_seedINT00–18446744073709550000
    expression_strengthFLOAT1.000–3
    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
    widthINT51264–4096
    heightINT51264–4096
    backgroundFLOAT0.950–1
    surfaceCOMBO2 options: plain, edgeflow_texture
    antialiasINT21–4

    Outputs (4)

    NameTypeDescription
    imageIMAGE
    normal_mapIMAGE
    depth_mapIMAGE
    maskMASK