Nodes/ComfyUI-KSTR-Nodes/KR 카메라 컨트롤
ComfyUI Node

KR 카메라 컨트롤

Point a Virtual Camera, Get a Weighted Shot Prompt

By Ye0l·Created 2 months ago·Updated about a month ago· 0
KR 카메라 컨트롤
    • 카메라 프롬프트
    pos_x0.00
    pos_y0.00
    pos_z0.00
    roll0.00
    config{"weight_min": 0.1, "weight_max": 10.0, "no_weight": false, "no_weight_threshold": 0.5, "active_user_prompt": "", "camera_presets": [{"name": "정면", "pos_x": 0.0, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}, {"name": "왼쪽", "pos_x": 0.5, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}, {"name": "오른쪽", "pos_x": -0.5, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}, {"name": "후면", "pos_x": 1.0, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}], "azimuth": {"enabled": true, "weight": 5.0, "deadzone_ratio": 0.2, "directions": {"front": {"tag": "from front", "enabled": true}, "back": {"tag": "from behind", "enabled": true}, "left": {"tag": "from right", "enabled": true}, "right": {"tag": "from left", "enabled": true}}}, "elevation": {"enabled": true, "weight": 5.0, "categories": {"bird": {"tag": "directly above, from above, aerial view", "enabled": true}, "high": {"tag": "high angle, from above", "enabled": true}, "eye": {"tag": "eye-level", "enabled": true}, "low": {"tag": "low angle, from below", "enabled": true}, "worm": {"tag": "directly below", "enabled": true}}}, "distance": {"enabled": true, "weight": 5.0, "categories": {"ecu": {"tag": "extreme close-up", "enabled": true}, "cu": {"tag": "close-up", "enabled": true}, "medium": {"tag": "medium shot", "enabled": true}, "full": {"tag": "full body", "enabled": true}, "wide": {"tag": "wide shot", "enabled": true}}}, "tilt": {"enabled": true, "deadzone": 0.15, "extra": 0.0, "dutch_tag": "dutch angle"}, "wheel_step": 0.0003, "extras": {"lens": {"enabled": false, "value": "85mm lens"}, "dof": {"enabled": false, "value": "shallow depth of field", "weight": 1.3}, "movement": {"enabled": false, "value": "handheld camera"}, "composition": {"enabled": false, "value": "rule of thirds"}, "style": {"enabled": false, "value": "cinematic"}}}
    preset_index0

    Some prompts read like a director's storyboard: "low angle, from behind, close-up, dutch angle." This node lets you dial all of that in with a mouse instead of your vocabulary. KR 카메라 컨트롤 (search for it as "KR Camera Control") gives you a little 3D viewport, you drag a virtual camera around the subject, and it hands you back a prompt string made of the right camera tags - with weights baked in so the direction you care about actually lands.

    It's a port of the camera-prompt algorithm and interaction design from ComfyUI-KR-Camera-Control, which itself grew out of ComfyUI_bsk_UI. The source files keep the original attribution and are licensed AGPL-3.0-or-later, which matters only if you fork the code and redistribute it - keep the license notice and it's fine.

    How it works

    Four of the inputs are a compact 3D camera position, each in the range −1.0 to 1.0:

    • pos_x - left/right. Mapped to azimuth, blended between "from front", "from behind", "from left" and "from right" with cosine interpolation so you get smooth mixtures, not hard snaps.
    • pos_y - up/down. Picks an elevation band: bird's-eye, high angle, eye-level, low angle, or worm's-eye.
    • pos_z - distance. Picks a shot size: extreme close-up, close-up, medium shot, full body, or wide shot, and the weight ramps up the closer you get.
    • roll - rotation around the camera axis. Past a small deadzone it adds the "dutch angle" tag.

    By default the node runs in weighted mode, so the output looks like (from front:5.00), (high angle:3.24), (close-up:2.10), (dutch angle:1.00). Each tag's weight comes from a per-axis strength in the config JSON (azimuth, elevation and distance each default to 5.0), which you can edit. If you'd rather have plain tags with no parentheses, set no_weight: true in the config and it emits a clean comma list instead.

    The two remaining inputs: config is a big JSON blob that controls everything - the tag vocabulary, the presets, the weights, even optional extras like "85mm lens" or "shallow depth of field" you can toggle on. And preset_index is the sleeper feature: it picks a preset from the list (front, left, right, back) by number. Wire a Random Int into it with a range of 0 to (preset count − 1) and every run rolls a different camera angle.

    The single output is the camera prompt STRING. Wire it into a prompt builder or a text-concatenate node and prepend it to your normal prompt.

    The viewport controls

    The 3D preview isn't decoration - it's the whole point. Left-drag moves the camera (the thing being composed), right-drag orbits your view, the scroll wheel changes distance, and Shift+wheel rolls the camera. There are also numeric fields if you'd rather type exact values. The prompt updates live as you drag, so you can scrub until the shot looks right before you queue anything.

    Install

    It ships in Ye0l/ComfyUI-KSTR-Nodes. Easiest is ComfyUI Manager - search "ComfyUI-KSTR-Nodes", install, restart. By hand:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Ye0l/ComfyUI-KSTR-Nodes
    

    Restart ComfyUI, and it appears under KR Tools/카메라. No extra Python dependencies for this node.

    Where people get burned

    The weighted output (from front:5.00) only means something to models whose text encoder still honors A1111-style weight syntax - SD 1.5, SDXL, Illustrious, Pony and friends. On LLM-encoded models (Flux, Z-Image, Anima) those weights are discarded and the parentheses become literal punctuation, which is worse than nothing. If you're on that side of the fence, flip no_weight to true and use the tags plain. Also worth knowing: this is a young pack (single commit, zero community footprint yet), so the config JSON is your best manual when something behaves oddly.

    CategoryKR Tools/카메라

    Inputs (6)

    NameTypeDefaultDescription
    pos_xFLOAT0.00-1–1
    pos_yFLOAT0.00-1–1
    pos_zFLOAT0.00-1–1
    rollFLOAT0.00-1–1
    configSTRING{"weight_min": 0.1, "weight_max": 10.0, "no_weight": false, "no_weight_threshold": 0.5, "active_user_prompt": "", "camera_presets": [{"name": "정면", "pos_x": 0.0, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}, {"name": "왼쪽", "pos_x": 0.5, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}, {"name": "오른쪽", "pos_x": -0.5, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}, {"name": "후면", "pos_x": 1.0, "pos_y": 0.0, "pos_z": 0.0, "user_prompt": ""}], "azimuth": {"enabled": true, "weight": 5.0, "deadzone_ratio": 0.2, "directions": {"front": {"tag": "from front", "enabled": true}, "back": {"tag": "from behind", "enabled": true}, "left": {"tag": "from right", "enabled": true}, "right": {"tag": "from left", "enabled": true}}}, "elevation": {"enabled": true, "weight": 5.0, "categories": {"bird": {"tag": "directly above, from above, aerial view", "enabled": true}, "high": {"tag": "high angle, from above", "enabled": true}, "eye": {"tag": "eye-level", "enabled": true}, "low": {"tag": "low angle, from below", "enabled": true}, "worm": {"tag": "directly below", "enabled": true}}}, "distance": {"enabled": true, "weight": 5.0, "categories": {"ecu": {"tag": "extreme close-up", "enabled": true}, "cu": {"tag": "close-up", "enabled": true}, "medium": {"tag": "medium shot", "enabled": true}, "full": {"tag": "full body", "enabled": true}, "wide": {"tag": "wide shot", "enabled": true}}}, "tilt": {"enabled": true, "deadzone": 0.15, "extra": 0.0, "dutch_tag": "dutch angle"}, "wheel_step": 0.0003, "extras": {"lens": {"enabled": false, "value": "85mm lens"}, "dof": {"enabled": false, "value": "shallow depth of field", "weight": 1.3}, "movement": {"enabled": false, "value": "handheld camera"}, "composition": {"enabled": false, "value": "rule of thirds"}, "style": {"enabled": false, "value": "cinematic"}}}
    preset_indexoptINT0-2147483648–2147483647현재 프리셋 목록의 번호를 선택합니다. 범위를 0~(프리셋 수-1)로 둔 Random Int를 연결하면 전체 목록에서 랜덤 선택합니다.

    Outputs (1)

    NameTypeDescription
    카메라 프롬프트STRING