COMFY PAL embeds the full LensCowboy PAL viewport inside ComfyUI as a custom node. Use it for spatial layout (where things go in 3D), camera setup (position, lens, DOF, animation), and multipass render output that feeds directly into your AI graph.
The node exposes five image passes ready to drop into KSampler, ControlNet (depth/normal), Video Combine, compositing nodes, and more:
- Beauty — rendered colour pass (available on all tiers, including Free)
- Depth — z-depth, perfect for depth ControlNet (COMFY PAL or any SaaS tier)
- Normal — surface normals, for normal ControlNet (COMFY PAL or any SaaS tier)
- Alpha — matte for compositing (COMFY PAL or any SaaS tier)
- ID matte — per-object masks (COMFY PAL or any SaaS tier)
Free tier: beauty pass only, capped at 512px. Depth / normal / alpha / ID matte return blank tensors — unlock the full set with COMFY PAL ($7/mo) or any LensCowboy SaaS subscription.
Rendering happens locally on your machine via wgpu (Metal / Vulkan / DirectX 12). No cloud infrastructure, no 15MB base64 caps, no LensCowboy compute charges. Your GPU, your render.
Via git clone
cd ~/ComfyUI/custom_nodes git clone https://github.com/Lenscowboy/comfyui-lenscowboy-pal.git pip install -r comfyui-lenscowboy-pal/requirements.txt # restart ComfyUI, then search "PAL" in the node picker
Via ComfyUI Manager
Once published to the Comfy Registry: search comfy_pal in Manager, click install, restart. (Registry publish pending — use git clone for now.)
Local renderer (optional but recommended)
If you want direct Python rendering (bypasses the iframe round-trip, no 15MB cap, runs on your GPU), install the renderer deps:
pip install -r comfyui-lenscowboy-pal/pal_renderer/requirements.txt
Dependencies: pygfx, rendercanvas, gltflib, trimesh, assimp-py (for FBX), imageio, numpy.
Free tier (no account needed)
- Place the PAL Layout node in your graph
- Click Open Viewport — a full-screen modal with the PAL scene editor opens
- Drag a model in, or connect Load3D / Hunyuan3D / Tripo to the
model_3dinput - Position the camera, hit Render
- Queue Prompt — the
beauty_passoutput flows to your next node
Subscriber tier
After subscribing, paste your API key into the node's lc_api_key input. All passes unlock; resolution goes up to 2048px; local renderer works end-to-end.
Inputs
| Input | Type | Purpose |
|---|---|---|
| lc_api_key | STRING | Your LensCowboy platform token (optional — free tier works without) |
| lc_project_id | STRING | SaaS project to load (subscribers only) |
| lc_shot_id | STRING | Specific shot to load |
| GLB / OBJ | various | 3D model inputs — accepts file paths, base64, or upstream 3D-gen node outputs |
| model_3d | FILE_3D | Matches native ComfyUI Load3D model_3d output exactly |
| prompt | STRING | Scene description (used for proxy generation if no model connected) |
| camera_preset | STRING | eye_level, low_angle, high_angle, etc. |
| frame_start / frame_end | INT | Animation range |
| render_width / render_height | INT | 64 – 2048 (free tier capped at 512) |
| use_local_renderer | BOOLEAN | Render via pygfx on your GPU instead of iframe round-trip |
Outputs
| Output | Type | Purpose |
|---|---|---|
| beauty_pass | IMAGE | Rendered colour pass → KSampler, depth-aware nodes, compositing |
| depth_pass | IMAGE | Single-channel depth → Depth ControlNet |
| normal_pass | IMAGE | RGB surface normals → Normal ControlNet |
| alpha_pass | IMAGE | Matte for comping the result over a background |
| id_matte_pass | IMAGE | Per-object masks for selective processing |
| scene_json | STRING | Scene state (object positions, rotations, scales) |
| camera_json | STRING | Camera position, rotation, FOV, DOF |
| frame_start / frame_end | INT | Resolved animation range |
| sequence_json | STRING | Multi-shot sequence (Enterprise only) |
Beauty
Standard lit render. Feeds cleanly into KSampler as an img2img starting point, or into edit-style image models as a structural reference. Default materials are neutral grey — AI restyling downstream replaces the look anyway, which is the point.
Depth
Z-depth from the camera. Drop straight into a Depth ControlNet conditioning chain for shot-accurate spatial control. Normalised [0, 1]; near objects darker, far objects lighter by default.
Normal
RGB-encoded surface normals. Perfect for Normal ControlNet — preserves surface detail and lighting direction across AI restyles.
Alpha
Single-channel matte of rendered geometry vs background. Use it to composite the AI-restyled beauty pass over a different background, or to mask out specific regions before passing to downstream nodes.
ID matte
Per-object colour-coded mask. Each object in the scene gets a unique flat colour; use Image Mask by Color or similar to isolate individual objects for per-element processing.
beauty_pass is produced (depth/normal/alpha/ID matte return blank tensors). Multipass unlocks on a paid COMFY PAL plan or any LensCowboy SaaS plan — subscriptions paused; mailing-list signal welcome.
Set use_local_renderer=True on the node to bypass the iframe and render directly in Python via pygfx on your GPU.
Benefits
- No iframe round-trip — skip the postMessage dance; queue and go
- No 15MB base64 cap — direct numpy tensor handoff
- Runs on your GPU — Metal (macOS), Vulkan (Linux), DirectX 12 (Windows)
- Zero cloud cost — nothing hits LensCowboy infra
Tradeoffs
- Requires the optional
pal_renderer/requirements.txtdeps installed - Beauty, alpha, and normal passes are available now. Depth and ID matte are on the active roadmap — use the iframe render path for those in the meantime
- Uses the camera from your PAL viewport session (open viewport once to set camera, then local renderer uses it)
| Format | Iframe viewport | Local renderer (pygfx) |
|---|---|---|
| GLB | ✓ GLTFLoader | ✓ pygfx native |
| GLTF | ✓ GLTFLoader | ✓ pygfx native |
| OBJ | ✓ OBJLoader (+ MTL) | ✓ via trimesh |
| FBX | ✓ FBXLoader | ✓ via assimp-py |
| STL | ✓ STLLoader | ✓ via trimesh |
| USDZ | ✓ | — |
Upstream ComfyUI 3D generators connect cleanly: Hunyuan3D, Tripo, Meshy, Rodin, Load3D, Load3DAnimation, TripoSR. The node walks the graph on viewport open to auto-load any upstream model, so you don't need to queue once before seeing your geometry.
Depth-guided img2img
Drop the beauty into KSampler as init image, run depth pass into Depth ControlNet for spatial faithfulness. Result: AI-generated image that respects your layout.
PAL → beauty_pass → KSampler (init)
PAL → depth_pass → ControlNet (depth_strict)
→ KSampler (conditioning)
Multi-angle generation
Same scene, multiple camera positions, batched through your image model. Each camera preset renders a fresh beauty + depth, AI samples stay consistent via seed and pose conditioning.
Animated video via Video Combine
Render a frame sequence, feed into Animatediff or your video restyle chain, terminate in Video Combine for an mp4.
Per-object control
Use id_matte_pass to isolate an object, process differently (inpaint, colour-swap, relight), then recombine with the original beauty.
| Feature | Free | COMFY PAL | SaaS Creator+ | Enterprise |
|---|---|---|---|---|
| Viewport, camera, imports | ✓ | ✓ | ✓ | ✓ |
| Beauty ≤ 512 | ✓ | ✓ | ✓ | ✓ |
| Beauty up to 2048 | — | ✓ | ✓ | ✓ |
| Depth / Normal / Alpha / ID matte | — | ✓ | ✓ | ✓ |
| Local renderer | ✓ | ✓ | ✓ | ✓ |
| Save to Drive | — | — | ✓ | ✓ |
| Project load from SaaS | — | — | ✓ | ✓ |
| Sequence export (multi-shot) | — | — | — | ✓ |
| Breakdown integration | — | — | — | ✓ |
| Pipeline writeback | — | — | — | ✓ |
COMFY PAL at $7/mo or $49/yr unlocks everything you need for solo ComfyUI work: all passes, full resolution, no caps.
SaaS Creator+ (see tiers) adds the Daily pipeline, cloud renders, project/shot libraries, and Drive output.
COMFY PAL is a node. Enterprise is a factory.
If you're doing one-off shots in ComfyUI, COMFY PAL is probably all you need. But if your workflow looks more like "I need to generate a 48-shot music video from a script by Friday" — that's Enterprise territory.
Enterprise unlocks the whole LensCowboy production pipeline on top of everything in this doc:
- Script breakdown parser — reads a screenplay, extracts CAM / LIGHT / VFX tags, auto-generates shot list
- Multi-shot batching — run dozens of shots overnight from one config sheet
- Consistency tooling — character and location consistency across shots, colour grading propagation, reference-frame chaining
- LCBE bidding — client quoting, cost estimation, revision tracking. See LCBE docs
- Delivery automation — watermarked previews, color-graded finals, music + voice + SFX merged, auto Drive-upload
- Pipeline writeback from PAL — lay out a scene in PAL, trigger the full production pipeline on it
- Breakdown integration — "Load from Breakdown" button in PAL loads an entire scene from your LCBE breakdown
None of that lives inside ComfyUI. Different tool for a different job. See LensCowboy →
Docs for the SaaS side:
- Full PAL documentation — the SaaS-side PAL viewport in detail
- Pipeline documentation — how Daily / Weekly / PAL runs work
- LCBE documentation — script → breakdown → bid workflow
- Platform overview — how all the modules fit together
"Upload failed: 401" in the render dialog
Your current plan doesn't include the feature you just tried to use (typically Save to Drive or Export to Pipeline). The dialog should now lock these options up front and show an upgrade modal. If you're seeing this error, hard-refresh the browser (⌘⇧R / Ctrl+Shift+R) to pick up the latest iframe build.
Model doesn't appear in the viewport object list
The node auto-loads 3D models from upstream nodes (Load3D / Hunyuan3D / Tripo etc.) when the viewport opens. If nothing appears, check:
- Is the model connected to
model_3d,GLB, orOBJ? - Hard refresh the browser so the latest JS loads.
FBX loads but renders black
Embedded FBX textures sometimes fail to decode (common with proprietary image types). The viewport auto-swaps broken materials for neutral gray so geometry stays visible. For textured FBX, re-export as GLB from your DCC — much more portable.
Local renderer: "ImportError: gltflib required"
Install the renderer deps: pip install -r pal_renderer/requirements.txt inside the node directory.
Local renderer depth + ID matte show as black
Those two passes are on the active roadmap for the local renderer. Use the iframe render path for depth and ID matte for now — those work end-to-end today.