Jakkanna Pose Studio + OpenPose
A 3D posing studio inside a node, with OpenPose that actually matches the render
- pose_image
- images
- lighting_prompt
- keypoints
Here's the problem the pose-to-ControlNet crowd keeps hitting: you render a pose and then run OpenPose detection on it, and the keypoints don't quite match the pixels - because the detector saw a slightly different thing than your renderer drew. Jakkanna Pose Studio + OpenPose (legacy node ID VNCCS_PoseStudioOpenPose) is the flagship node of the Jakkanna pack and the answer to that: an interactive 3D posing studio where the OpenPose keypoints are exported from the same pose state that rendered the image, not detected afterward. The render and the skeleton are born aligned.
This is the character-posing engine from VNCCS - AHEKOT's Visual Novel Character Creation Suite, the tool that made consistent character sprites practical - rebuilt with the alignment bugs fixed. It runs entirely in a ComfyUI node: you drag the mannequin's joints in the embedded 3D viewport, frame the camera, tune lighting, and get pose images, lighting prompts, and keypoints out the other side.
How it works
The 3D viewport is browser-side (Three.js + MakeHuman model), and the capture is done by the node's viewport - not a server-side renderer. That's the crucial detail. The backend and frontend synchronize an execution state; the JS UI renders and captures, then the backend resolves it exactly once and produces all three outputs from that single state. This is the thing Jakkanna fixed vs. upstream: one effective state, rendered once, captures/keypoints/lighting all consistent.
The whole interface state lives in the pose_data input - a hidden multiline JSON widget, default "{}" - which is how pose tabs, camera, lighting, and export mode persist in the graph. The optional pose_image input is the interesting one: connect an image and the backend runs SAM 3D Body to infer a pose from the photo and applies it to the mannequin - image-to-pose import, so you can match a reference photo or a tracing background.
What comes out
Three outputs, and the wiring tells you what this node is for:
- images - a list, one rendered pose per pose tab, or a single grid image if export mode is GRID.
- lighting_prompt - a list of prompt strings, aligned index-for-index with
images. The node generates descriptive lighting from your scene lights; combine it with your main prompt (the node has template tags like<lighting>for this). - keypoints -
POSE_KEYPOINTbody/hand/face data, exported straight from the pose state and aligned toimages. This is what feeds a ControlNet OpenPose preprocessor input - no separate detection pass, no drift.
Install
Install the teenu/ComfyUI-Jakkanna pack once and this node is there. ComfyUI Manager: search Jakkanna → Install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/teenu/ComfyUI-Jakkanna.git
cd ComfyUI-Jakkanna
pip install -r requirements.txt
Restart. Two pack-level rules: don't install the upstream vnccs-utils alongside it (same node IDs), and the heavy deps - torch, opencv, trimesh - come via requirements.txt. This node itself needs no model downloads unless you use pose_image, which pulls SAM 3D Body on first use.
Gotchas
The big one is in the README for a reason: captures happen in the browser viewport, not on the server. Run Pose Studio workflows from a browser session where the node is open and the 3D viewer has finished loading. Headless or API-only execution without synchronized captures stops with a clear error - by design. Jakkanna removed the upstream Python fallback renderer rather than produce geometry that doesn't match the viewport. So if you're scripting from the API, this is the wrong node.
Second: if you only need a rendered pose image, the plain VNCCS_PoseStudio node is the same studio minus the keypoints - use that and skip the extra work. And remember this is a pose control source: pair it with a ControlNet that has an OpenPose condition, or with SCAIL-2 in the animation workflows. On its own it just draws mannequins.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| pose_data | STRING | {} | — |
| pose_imageopt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| lighting_prompt | STRING | — |
| keypoints | POSE_KEYPOINT | — |