Nodes/ComfyUI Web Viewer/XYZ OSC Control @ vrch.ai
ComfyUI Node

XYZ OSC Control @ vrch.ai

XYZ OSC Control for when XY isn't enough

By VrchStudio·Created 2 years ago·Updated 22 days ago· 356
XYZ OSC Control @ vrch.ai
    • X_INT
    • Y_INT
    • Z_INT
    • X_FLOAT
    • Y_FLOAT
    • Z_FLOAT
    • X_RAW
    • Y_RAW
    • Z_RAW
    server_ip172.17.0.2
    port8000
    path/xyz
    x_input_min0.00
    x_input_max1.00
    x_output_min0
    x_output_max100
    x_output_invertfalse
    x_output_default50
    y_input_min0.00
    y_input_max1.00
    y_output_min0
    y_output_max100
    y_output_invertfalse
    y_output_default50
    z_input_min0.00
    z_input_max1.00
    z_output_min0
    z_output_max100
    z_output_invertfalse
    z_output_default50
    debugfalse

    This is the same idea as the pack's XY OSC Control @ vrch.ai, just with a third axis bolted on. XYZ OSC Control @ vrch.ai listens for OSC messages and hands you three remapped values - X, Y, and Z - that you can wire into anything in your workflow. If you've got a joystick with twist, a phone's gyroscope, or a touch surface with three faders, this is the node that turns that hardware into a ComfyUI control surface.

    Honestly, for most people XY is enough. The Z axis earns its keep when you actually have a three-degree input: a flight stick where twist is Z, a TouchOSC fader bank of three, or a motion-sensing device where orientation gives you three continuous values. It's the same OSC machinery, extended - so if you've already used the XY node, the only new thing here is the third channel and its wiring.

    How it works

    Identical to XY OSC Control, one axis up. The node binds a UDP listener on server_ip + port (default 8000) and watches the path (default /xyz). It accepts an OSC message to /xyz carrying three float arguments, or separate /xyz/x, /xyz/y, and /xyz/z messages with one argument each. Every axis goes through the same remap pipeline: input min/max (default 0.01.0) mapped onto output min/max (default 0100), optional inversion, and an output_default fallback (50) used when no message has arrived yet.

    The inputs and outputs that matter

    The setup trio is the same as the XY node, and the defaults are again worth trusting:

    • server_ip - where the node listens. The baked-in default 172.17.0.2 is a Docker bridge address from the author's dev box; set your machine's LAN IP for phone control, 127.0.0.1 for same-machine testing.
    • port (default 8000) and path (default /xyz) - must match what your OSC client sends.
    • The per-axis remap fields - x/y/z_input_min/max, x/y/z_output_min/max, x/y/z_output_invert, x/y/z_output_default. Adjust the output range to fit whatever parameter you're driving (like 1–60 for steps or 0–10 for cfg).

    Outputs mirror the XY node, three versions per axis: X_INT / Y_INT / Z_INT (remapped integers - wire into seed, cfg, steps and friends), X_FLOAT / Y_FLOAT / Z_FLOAT (remapped floats for things like denoise), and X_RAW / Y_RAW / Z_RAW (raw received values, great for confirming your client is sending what you think it is). A natural first project: three continuous inputs driving a camera's pan, tilt, and roll, or joystick X/Y plus twist mapped to controlnet strength, denoise, and seed.

    How to install it

    Same as every node in the VrchStudio/comfyui-web-viewer pack - no model files, nothing OSC-specific beyond the pack's own requirements. In ComfyUI Manager search "ComfyUI Web Viewer", or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/VrchStudio/comfyui-web-viewer
    cd comfyui-web-viewer
    pip install -r requirements.txt
    

    Windows portable installs use python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\comfyui-web-viewer\requirements.txt. Restart ComfyUI and you're set.

    Common issues

    Everything that bites the XY node bites this one: OSC is UDP, so a silent failure means no handshake to tell you about it. If your faders do nothing, check the same checklist - same network, server_ip set to the machine's real LAN IP, path and port matching on both ends, firewall not dropping UDP - and flip debug on to see exactly what the node is receiving. One listener per ip:port still applies, so give the XYZ node its own port or path if you're also running the XY version. One genuinely XYZ-flavored gotcha: if your client sends only two of the three values, the third axis just sits at its output_default - which is exactly why that default exists.

    Categoryvrch.ai/control/osc

    Inputs (22)

    NameTypeDefaultDescription
    server_ipSTRING172.17.0.2
    portINT80000–65535
    pathSTRING/xyz
    x_input_minFLOAT0.00-9999–9999
    x_input_maxFLOAT1.00-9999–9999
    x_output_minINT0-9999–9999
    x_output_maxINT100-9999–9999
    x_output_invertBOOLEANfalse
    x_output_defaultINT50-9999–9999
    y_input_minFLOAT0.00-9999–9999
    y_input_maxFLOAT1.00-9999–9999
    y_output_minINT0-9999–9999
    y_output_maxINT100-9999–9999
    y_output_invertBOOLEANfalse
    y_output_defaultINT50-9999–9999
    z_input_minFLOAT0.00-9999–9999
    z_input_maxFLOAT1.00-9999–9999
    z_output_minINT0-9999–9999
    z_output_maxINT100-9999–9999
    z_output_invertBOOLEANfalse
    z_output_defaultINT50-9999–9999
    debugBOOLEANfalse

    Outputs (9)

    NameTypeDescription
    X_INTINT
    Y_INTINT
    Z_INTINT
    X_FLOATFLOAT
    Y_FLOATFLOAT
    Z_FLOATFLOAT
    X_RAWFLOAT
    Y_RAWFLOAT
    Z_RAWFLOAT