ComfyUI Node

A3D Listener

The node with zero inputs that listens for your 3D scene

By n0neye·Created about a year ago·Updated about a year ago· 7
A3D Listener
    • color_image
    • depth_image
    • openpose_image
    • prompt
    • negative_prompt
    • seed

    A3D Listener is the receiving end of a bridge, and on its own it does almost nothing. No inputs, no settings, no model to download - you drop it into a workflow and it just sits there until something on the other end talks to it. That something is A3D, a lightweight 3D scene composer and character poser by the same author (n0neye). You pose dummy characters, drop in camera angles and imported models, hit Send to ComfyUI, and the Listener hands your graph a rendered color image and depth map as plain IMAGE tensors.

    Why would you care? Because this is the missing link for "pose the scene in 3D, render it in AI" workflows. The old community standby, ComfyUI_3dPoseEditor, has been abandoned, and people noticed - the A3D launch thread on r/comfyui explicitly got asked to be its replacement. Instead of fighting a 3D app or hand-drawing skeletons, you compose the scene visually, then wire the Listener's images into a ControlNet and get anatomically-plausible output that matches your pose. The shipped example workflow pairs it with a Flux depth LoRA and InstructPixToPixConditioning, so the depth map acts as the edit reference for the sampler.

    How it actually works

    The node doesn't poll anything. It registers two routes on ComfyUI's own aiohttp server (PromptServer): POST /a3d_data receives the base64-encoded payload from the A3D app, and GET /a3d_events is a Server-Sent Events stream that pushes live previews into the node's custom JS widgets. Incoming data lands in a global dict stamped with a timestamp, and the node's IS_CHANGED method returns that timestamp - so ComfyUI only re-executes when fresh data actually arrives. When it runs, it decodes the base64 into float32 [B,H,W,C] tensors; anything the app didn't send becomes a 64×64 black frame, and a missing seed defaults to 0.

    One thing to internalize: the send is the app posting to your ComfyUI. The author's README is blunt about the implication - ComfyUI has to be running on the default port 8188, because that's what A3D targets. Run ComfyUI behind --port 1234 and the button quietly goes nowhere.

    The outputs that matter

    The input list is empty - the only thing you configure is nothing. The six outputs are:

    • color_image, depth_image, openpose_image - IMAGE, the rendered frames
    • prompt, negative_prompt - STRING, whatever A3D's render panel is holding
    • seed - INT, driven from the app

    color_image and depth_image are the workhorses. Feed the color image into a ControlNet (like the community user who screen-capped A3D and ran Union Canny at 0.5 strength and got "10 fingers and toes"), or push depth_image into a depth ControlNet. And here's a trap: openpose_image is wired up but OpenPose is still on the README's TODO list - it ships as a black empty frame. Don't build your pose workflow on it yet.

    Installing it

    Either way is a one-liner:

    # ComfyUI Manager: search "A3D ComfyUI Integration"
    cd ComfyUI/custom_nodes
    git clone https://github.com/n0neye/A3D-comfyui-integration
    

    Then restart ComfyUI. There's no requirements.txt and nothing to download - the code only uses numpy, torch, PIL and aiohttp, all already in ComfyUI. But remember the Listener is half of a pair: you also need the A3D app itself from github.com/n0neye/A3D (the 3D-gen parts there can want a Fal.ai key, but posing, composing, and sending to ComfyUI are local).

    Where people get burned

    • Port 8188. Already covered. If nothing arrives when you click Send, check the port first.
    • The depth map is "contour-y." It's rendered from real geometry, so it's clean - but users compared it against ComfyUI's usual depth output and found it "still more like a contour than a depth map." If you want a soft, Depth-Anything-style map for depth ControlNet, run the color image through a proper depth preprocessor first.
    • A reported JS bug. One user couldn't delete the node or edit the workflow after adding it, getting Cannot read properties of undefined (reading 'id') - and a restart didn't fix it. It's a quirk of the preview widget; if you hit it, surgically remove the node from the workflow JSON, or disable the custom node folder temporarily.

    License-wise you're clear: the integration is MIT, so commercial work is fine and nothing forces you to open-source your workflow. Only the main A3D app is AGPL-3.0, and that only bites if you modify it. Early beta, one node, but if you compose scenes in 3D and want them in your graph, this is the cleanest bridge around right now.

    CategoryUtils/Listeners

    Inputs (0)

    No inputs

    Outputs (6)

    NameTypeDescription
    color_imageIMAGE
    depth_imageIMAGE
    openpose_imageIMAGE
    promptSTRING
    negative_promptSTRING
    seedINT