Panda3dTest
The node that turns your 3D scene into frames
- base
- model0
- model1
- model2
- model3
- model4
- model5
- model6
- model7
- model8
- model9
- model10
- textures
- image
Every node in the chaojie/ComfyUI-Panda3d pack up to this point is scene-building. Panda3dBase boots the engine, Panda3dLoadModel drops in geometry, the texture and light nodes dress it up. None of that matters until something renders - and Panda3dTest is the renderer. It's the node that walks the scene graph, captures the offscreen camera, and hands you a real ComfyUI IMAGE tensor you can preview, save, or feed into VHS_VideoCombine for an mp4. Despite the name, it's not a test; it's the output stage.
How it works
The node loops for frame_length frames. Each iteration does three things: advances the engine (renderFrame()), applies any animation keyframes for that frame number, then grabs the color image from the base's camera and appends it to a growing batch. At the end you get a single batched tensor - [1, frames, H, W, C] - which is exactly the shape video tools like VHS_VideoCombine expect.
That's also where the "animation" story lives. Each of the 11 optional model slots (model0 through model10) has a paired modelNAnimation JSON string. The format is simple arrays keyed by frame index:
{"x": [0, 1, 2, 3], "y": [0, 0, 0, 0], "texture": [0, 1, 0, 1]}
For each frame f, the node reads key[f] and calls the matching setX / setY / setZ / setH / setP / setR / setSx / setSy / setSz on the model. The texture array is special: it indexes into the textures input, so frame 0 can show texture A and frame 1 can show texture B - that's exactly how the demo makes the carousel's light rings blink on and off.
The inputs that matter
- base - the engine, from
Panda3dBase. Required, as everywhere in this pack. - frame_length - number of frames to render. Default 14. This is your real "how long is the clip" control; at the engine's fixed pacing you're looking at roughly a second per handful of frames.
- model0…model10 - the model handles to render and animate. Leave the ones you don't use unconnected.
- modelNAnimation - the JSON keyframe string described above.
{}(the default) means "don't animate me." - textures - a merged texture list (from
Panda3dTextureMerge) used for per-frame texture swaps.
Output is a single image output of type IMAGE. Pipe it into VHS_VideoCombine to encode, or PreviewImage to eyeball frames.
Installing it
Same as every node in the pack - one install covers all of them. ComfyUI Manager, search ComfyUI-Panda3d, or:
cd ComfyUI/custom_nodes
git clone https://github.com/chaojie/ComfyUI-Panda3d
cd ComfyUI-Panda3d
pip install -r requirements.txt
Restart ComfyUI. The demo models come with the repo.
Gotchas
- The camera is fixed. There's no camera node in the pack; the view is whatever
Panda3dBaseset up at startup. If you want a different angle, you're editing the source or positioning everything around the default camera. - Renders are single-pass and slow-ish. The code renders the scene once per frame with a
Wait(1)between iterations, so longer clips are genuinely slow. For quick checks, keepframe_lengthlow. - Unlit by default. The base's
setupLights()is commented out in the shipped source, so unless the lighting nodes are fixed and wired up, models render flat. It still looks fine for the demo carousel, but don't expect shaded realism yet.
It's the last node in basically every Panda3d workflow. Get geometry in, wire it here, and you have frames coming out the other side.
Inputs (25)
| Name | Type | Default | Description |
|---|---|---|---|
| base | Panda3dBase | — | |
| frame_length | INT | 14 | — |
| model0opt | Panda3dModel | — | |
| model0Animationopt | STRING | {} | — |
| model1opt | Panda3dModel | — | |
| model1Animationopt | STRING | {} | — |
| model2opt | Panda3dModel | — | |
| model2Animationopt | STRING | {} | — |
| model3opt | Panda3dModel | — | |
| model3Animationopt | STRING | {} | — |
| model4opt | Panda3dModel | — | |
| model4Animationopt | STRING | {} | — |
| model5opt | Panda3dModel | — | |
| model5Animationopt | STRING | {} | — |
| model6opt | Panda3dModel | — | |
| model6Animationopt | STRING | {} | — |
| model7opt | Panda3dModel | — | |
| model7Animationopt | STRING | {} | — |
| model8opt | Panda3dModel | — | |
| model8Animationopt | STRING | {} | — |
| model9opt | Panda3dModel | — | |
| model9Animationopt | STRING | {} | — |
| model10opt | Panda3dModel | — | |
| model10Animationopt | STRING | {} | — |
| texturesopt | Panda3dTexture | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |