Lackluster-Camera
Steer a 3D camera without leaving your prompt
- image
- prompt
- camera_info
If you've watched the Qwen-Image-Edit scene at all, you've seen the "multiangle camera" trick: turn a camera angle into an optimized prompt phrase, and the model re-shoots your subject from that direction. That pattern is where this node comes from - the community's Multiple-Angles LoRA turned camera framing into a slider, and a purpose-built ComfyUI camera node followed within weeks. This is that node, in this pack's clothing. And because it just writes text, it's not even stuck on Qwen - people run these prompts through Flux and other models too.
How it works
Three sliders in, one natural-language prompt out. horizontal_angle (0–360°) becomes the azimuth - front view, right side view, back, the quarter views. vertical_angle (-30° to 60°) becomes the elevation - low-angle, eye-level, elevated, high-angle. zoom (0 = wide, 10 = close-up) becomes the shot size. The node assembles them into something like <sks> front-right quarter view eye-level shot medium shot, which is exactly the phrasing those models were trained on - naming a physical camera angle is genuinely high-leverage on modern encoders.
It also emits camera_info (LOAD_3D_CAMERA), a dict with the camera's position, target and type for the bundled three.js preview. Flip camera_view on and you get a draggable 3D scene showing where the virtual camera sits; image (optional) displays your actual image in that scene as context. That part is a gimmick until it isn't - it's surprisingly nice for planning a re-shoot.
The inputs that matter
- horizontal_angle / vertical_angle / zoom - the whole point. Set them and the prompt writes itself.
- default_prompts - present in the schema, but as of the current source it's a no-op: the node always prefixes
<sks>. Don't go hunting for what it does. - camera_view and image - the preview widgets, optional.
Outputs: prompt (STRING) - wire it into your text encoder; camera_info (LOAD_3D_CAMERA) - feeds the preview.
One confusion to head off
This exact node is registered twice. LacklusterCameraNode and LacklusterQwenMultiangleCameraNode are the same class with the same Lackluster-Camera display name - the "Qwen" version is the original name, the shorter one an alias. If you see two "Lackluster-Camera" entries in your node menu, they're duplicates, not siblings. Install the pack, not two copies of the node.
Installing and gotchas
Manager (search "ComfyUI Lackluster Nodes") or clone the repo - the pack needs only requests and numpy, so no model downloads for this. One real caveat: the 3D preview widget is a Vue/three.js app built from qwen_src, and the repo gitignores the compiled js/ output - so if you clone and the preview doesn't render, the prompt generation still works perfectly; the widget is the fragile part, not the node.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| horizontal_angle | INT | 00–360 | Camera azimuth angle (0-360°) |
| vertical_angle | INT | 0-30–60 | Camera elevation angle (-30° to 60°) |
| zoom | FLOAT | 5.00–10 | Camera distance (0=wide, 10=close-up) |
| default_prompts | BOOLEAN | true | — |
| camera_view | BOOLEAN | false | Toggle camera perspective preview |
| imageopt | IMAGE | Optional input image to display in 3D scene |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | — |
| camera_info | LOAD_3D_CAMERA | — |