Zero123: Image Rotate in 3D
One photo in, new camera angles out — no 3D model involved
- image
- IMAGE
The name is a lie, in the best way: Zero123: Image Rotate in 3D doesn't build a 3D model at all. It's a ComfyUI port of Zero-1-to-3 (Columbia's CV Lab, 2023) - a model that takes a single 2D photo of an object and imagines the same object from a different camera angle. No mesh, no point cloud, no API, no key. You hand it a picture of a fire hydrant, tell it "turn 90° right and tilt up 15°", and it renders what that hydrant would probably look like from over there.
It's a view-conditioned diffusion model, fine-tuned from Stable Diffusion on 10M+ 3D objects from Objaverse-XL, where the conditioning is your input image plus a requested camera pose. That's why it's still kicking around in 2026: people use it to synthesize multi-angle views of an object they can't photograph from every side, mostly as training data for LoRAs. That's a real, documented use - this exact pack got recommended in r/StableDiffusion for generating extra views of a shoe for a LoRA dataset.
How it actually works. Reading the pack's zero123.py, it's ~200 lines and refreshingly honest. Your polar and azimuth angles become a camera vector - [radians(polar), sin(radians(azimuth)), cos(radians(azimuth)), 0] - which gets appended to the CLIP embedding of your image and pushed through a small projection network. The image is encoded into latent space, a DDIM sampler denoises at a fixed 256×256 with classifier-free guidance, and the VAE decodes back to pixels. Diffusions don't rotate; they convincingly guess.
Inputs that matter:
image- must be square, white background, subject centered. The pack'sZero123: Image Preprocessnode exists to produce exactly that; skip it and pay for it in garbage output.polar_angle(INT, −180..180) - tilt up or down. Negative looks up, positive looks down.azimuth_angle(INT, −180..180) - turn left or right. Negative is left, positive right.steps(default 75) - the original repo's default, and the README says don't go below 75. It's right; low step counts turn to mush fast.batch_size- how many candidates to generate at the same angle. Set it to 3–4 and pick the best; the renders are stochastic and half will come out warped.fp16(default on) - half precision. Keep it on; saves VRAM with barely any quality cost.scale(FLOAT, 0.1–10) - a genuine trap. The README describes it as a z-axis zoom ("far away or near"), but read the shipped code andscaleis actually fed in as the classifier-free-guidance scale - with 1.0 (the default) disabling guidance entirely. The sample workflow uses 2.5, which is a sane place to start. Trust the code, not the docs, here.checkpoint- a dropdown that lists checkpoints withzero123in the filename, so it stays empty until you've dropped a model into the right folder.
The height, width, sampler, and scheduler widgets exist purely as information - fixed at 256, ddim, ddim-uniform. You can't change them, so don't fight the UI.
Output: one IMAGE per sample, always 256×256. Upscale afterward; that resolution is the model's era showing.
Models. The node is dead until you download weights into ComfyUI/models/checkpoints/zero123/. ComfyUI Manager can fetch them (search zero123), or grab the URLs from the pack's model-list.json. zero123-xl.ckpt is the default; stable_zero123.ckpt (Stability AI) claims better results but is noncommercial - fine for tinkering, a licensing problem if you plan to sell anything made with it. The original zero123-105000 / zero123-165000 checkpoints are the classic ones.
Installing. Via ComfyUI Manager, search zero123, install the pack, then install a model. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/kealiu/ComfyUI-Zero123-Porting.git
cd ComfyUI-Zero123-Porting
pip install -r requirements.txt
Restart and refresh. The requirements pull in the original research stack (pytorch-lightning, omegaconf, einops, opencv, CLIP and taming-transformers from git), so installation is heavier than most modern packs and can fight other nodes over pinned versions. First load is slow too - the code runs torch.compile and loads the full checkpoint before you see anything, though the model is cached after that.
The honest verdict. In 2023 this was magic; by 2026, SV3D and Hunyuan3D have left it behind, and at 256×256 this is a tool for mockups and synthetic training data, not portfolio pieces. But it's free, offline, a single node, and for augmenting a product-photo dataset with new angles it's still the cheapest trick in the box.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| polar_angle | INT | 0-180–180 | — |
| azimuth_angle | INT | 0-180–180 | — |
| scale | FLOAT | 1.00.1–10 | — |
| steps | INT | 75 | — |
| batch_size | INT | 1 | — |
| fp16 | BOOLEAN | true | — |
| checkpoint | COMBO | 0 options: | |
| heightopt | COMBO | 1 options: height=256 | |
| widthopt | COMBO | 1 options: width=256 | |
| sampleropt | COMBO | 1 options: ddim | |
| scheduleropt | COMBO | 1 options: ddim-uniform |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |