RS Camera Control
Camera tags plus masks that actually move with them
- building_pipe
- context
- building_pipe
- prompt
- camera_prompt
What it's for
The moment you put characters at explicit coordinates, framing stops being a prompt problem and becomes a layout problem. You ask for a wide shot, the caption lands, and now both characters are floating mid-canvas in masks sized for a medium shot.
RS Camera Control does both halves. It writes the view captions from four axes, and on request it also zooms, rotates or flat-plane-projects the character regions in the pipe so boxes and masks follow the framing you asked for. It's the local-side twin of NAI Camera Control - same engine, same editor, registered separately under RS/Camera, and it defaults to prompt_syntax=ComfyUI, which is the syntax the local side actually uses.
Reach for it when you're driving RS Multi-Character Sampler or an NAI context and want the camera moved. No diffusion model, no ControlNet, no extra sampler pass.
How it works
Captions first. Each axis becomes tag weights via a raised-cosine blend, s(t) = (1 − cos(πt)) / 2, so you get two neighbouring tags at complementary weights between knots instead of snapping between them. Azimuth maps from front / viewed from the left side or viewed from the right side / from behind at 0/90/180°, the horizontal weight scaled by 0.85 × cos(elevation)² - at ±90° elevation the horizontal caption disappears, because yaw means nothing at the pole. Elevation maps from above/from below at 60° and overhead view/worm's-eye view at 90°. Distance blends across five framing tags. Roll adds dutch angle. Everything is multiplied by strength, formatted as (from behind:1.02) or 1.02::from behind::, and bare tags in plain mode.
Then layout. layout_sync=fixed leaves coordinates alone. distance_and_roll zooms and spins every character region around the canvas centre - distance 0.5 is original size, 0 doubles it, 1 halves it, and positive roll rotates clockwise in image coordinates. Set canvas_aspect to your generation width ÷ height (1216/832 = 1.461538) or rotation comes out stretched. perspective goes further and applies a pinhole projection to the whole flat mask plane using azimuth and elevation, so the near side grows and the far side shrinks.
That last one is a flat-plane trick, not a 3D reconstruction. It doesn't invent the person's back silhouette or handle occlusion. At ±90° yaw or elevation the plane goes edge-on and the node stops with a readable error telling you to reduce the angle or use distance_and_roll.
The inputs that matter
azimuth/elevation/distance/roll- the four axes, all draggable in the in-node diagram: click or drag in the left circle for direction, the right semicircle for height, wheel for distance, shift+wheel for tilt.strength(default 1.2) - just start at 0.8–1.4. Cranking it produces distortion, not obedience.layout_sync- the one people miss.fixedwrites captions only; the mask transforms are opt-in.canvas_aspect- only matters with layout sync on, and it's the most common cause of mangled rotation.scope-scene_and_characters(default) appends the caption to character prompts too. Keep it; a view caption that lives only in the common prompt can get swallowed by regional conditioning.
Connect a building_pipe (draft or final character pipe, or an NAI_CONTEXT) and you get building_pipe back out for the sampler, plus prompt (scene + camera merged) and camera_prompt (captions only). base_prompt is where the scene goes if your pipe doesn't carry one - without it the node errors out rather than overwriting your scene with camera words.
random_mode=balanced keeps views inside −90…90 azimuth and −35…35 elevation; full uses everything. random_seed is a separate 32-bit camera seed, so randomising framing doesn't reshuffle your image seed. One execution draws one view; a batch downstream shares it.
Install
Manager → search ComfyUI_RS_NAI_API_Request → Install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/raspie10032/ComfyUI_RS_NAI_API_Request.git
cd ComfyUI_RS_NAI_API_Request
python -m pip install -r requirements.txt
The requirements file drags in torch, segment-anything and scipy for the pack's detailer and tagger nodes; the camera node uses none of it and needs no weights, no token. Camera processing is entirely local - only the sampler downstream can spend money.
Where people get burned
Mask transforms need the partner pack. Silhouettes, boxes and body-part masks in a local pipe are decoded by RS Multi-Character Sampler, so if you're editing local mask records you want both extensions updated together. A plain native NAI context is fine without it - it just shows character points instead of silhouettes.
Ten characters, max. The local mask round trip is capped at 10 characters; beyond that the node tells you so.
Edge cases are errors, by design. Zoom or rotate until a character's whole mask falls off-canvas and you get "reduce zoom/tilt or adjust Position" instead of a character silently turning into global conditioning.
Chained sync compounds. Two layout nodes back to back multiply their transforms.
Don't expect a rear view just because you asked. Text-based framing loses to looking at viewer and front-facing descriptions. The author's own validation got a side-facing face on a rear-view attempt and mismatched character sizes on a wide shot. Treat it as a strong nudge; the layout transforms are the part you can rely on.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| azimuth | FLOAT | 0-180–180 | Horizontal view: 0 front, ±90 side, ±180 rear. / 좌우 시점: 0 정면, ±90 측면, ±180 뒤. |
| elevation | FLOAT | 0-90–90 | Positive looks down; negative looks up. This adds captions, not a 3D camera. / 양수는 내려다보기, 음수는 올려다보기입니다. 시점 태그를 추가합니다. |
| distance | FLOAT | 0.500–1 | 0 extreme close-up, 0.5 medium shot, 1 wide shot. / 0 극근접, 0.5 중간 거리, 1 원경. |
| roll | FLOAT | 0-45–45 | Tilt amount adds dutch angle. Text alone cannot guarantee tilt direction. / 기울기 양을 태그로 유도하며 방향까지 보장하지 않습니다. |
| strength | FLOAT | 1.200–5 | Caption weight scale. Start at 0.8–1.4; high values may distort or split the image. / 0.8~1.4부터 시작하세요. 높이면 왜곡·분할이 생길 수 있습니다. |
| weighting | COMBO | Plain omits numerical weights for models without weighted prompt parsing. / 가중치 문법을 지원하지 않는 경로에는 plain을 사용하세요. | |
| prompt_syntax | COMBO | Used without context. Connected context keeps its own syntax. / 컨텍스트가 없을 때 사용합니다. 연결 시 원본 문법을 따릅니다. | |
| enabled | BOOLEAN | true | Off passes the scene through without camera captions. / 끄면 시점 태그를 추가하지 않습니다. |
| scope | COMBO | Share the view with character regions, or affect only the common caption. Existing text regions and placements stay fixed. / 캐릭터 영역에도 같은 시점을 전달하거나 공통 문장에만 적용합니다. 글자 영역·배치는 유지됩니다. | |
| building_pipeopt | RS_MC_BUILD_PIPE,RS_MC_CHARACTER_PIPE,NAI_CONTEXT | Draft or final character pipe, or NAI context. In a builder, camera settings apply at Finalize regardless of role order. / 조립·최종 파이프 또는 NAI 컨텍스트. 조립 중 카메라는 순서와 관계없이 Finalize에서 적용됩니다. | |
| contextopt | RS_MC_BUILD_PIPE,RS_MC_CHARACTER_PIPE,NAI_CONTEXT | Legacy alias for building_pipe. / building_pipe의 이전 연결 이름입니다. | |
| base_promptopt | STRING | Optional scene caption, in the context's syntax. Required when a connected pipe has no scene. / 연결 파이프에 공통 프롬프트가 없으면 장면 문장을 연결하세요. | |
| random_modeopt | COMBO | off | Random view overrides the four manual axes. Balanced avoids rear/pole/extreme framing; full uses all ranges. / 랜덤 구도는 수동 각도·거리·기울기를 대신합니다. balanced는 극단 시점을 피하고 full은 전체 범위입니다. |
| random_seedopt | INT | 00–4294967295 | Camera seed only. Fixed reproduces the view; randomize changes it after each queued generation. / 카메라 전용 시드. fixed는 구도 유지, randomize는 생성마다 변경합니다. 이미지 생성 시드는 바꾸지 않습니다. |
| layout_syncopt | COMBO | fixed | perspective tilts the flat mask plane with view angles; distance_and_roll only zooms/rotates. Text stays fixed. / perspective는 좌우·상하 각도로 평면 마스크를 원근 변형합니다. distance_and_roll은 거리·회전만 연동. 글자는 고정. |
| canvas_aspectopt | FLOAT | 1.0000.1–10 | Output width divided by height. Use the sampler's ratio to avoid stretched mask rotation. / 생성 너비÷높이. 샘플러와 같은 비율로 맞추세요. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| building_pipe | RS_MC_BUILD_PIPE,RS_MC_CHARACTER_PIPE,NAI_CONTEXT | — |
| prompt | STRING | — |
| camera_prompt | STRING | — |