Nuke ASCI Camera Export → ComfyUI Pose Pipeline
This document captures the end-to-end workflow we established for converting Nuke camera animations into RealEstate10k-compatible pose files that ComfyUI can ingest via the Koolook loader.
1. Source Data
- Nuke camera: standard
Cameranode with Translation / Rotation channels keyed over time. - Export step: use Nuke's Export Ascii tool with the column mapping shown in
ASCI_source_data/AnimationChannels_and_values_firstFrame_plus-ASCI-window.png.- Column order:
[translate.x, rotate.x, translate.y, rotate.y, rotate.z, translate.z]. - Rotations are exported in degrees using Nuke's ZXY rotation order (see
DataValidation-nuke.png).
- Column order:
- Raw file:
nuke_CAM_exporter/inputs/camTrack_v01.asci(162 lines covering frames 1001–1161 in this example).
Line 1 (frame 1001):
-1.0521379710 -0.7493053079 0.2045794427 -102.4243546000 4.2196946140 -0.2049491256
This line corresponds to the highlighted translation / rotation values keyed in Nuke (blue fields in the screenshot).
2. Conversion Script
File: nuke_CAM_exporter/nuke_ASCI-2-Pose_converter.py
Key behavior:
- Parses command-line arguments for input path, output path, fps, intrinsics, and placeholder pose width/height.
- Optionally ingests a JSON config (
--config) that stores lens data, render resolution, file paths, unit scale, and frame caps per shot. - Reads each ASCI row using the known column order and converts rotation degrees → radians.
- Builds a rotation matrix using Nuke's ZXY order (
euler_zxy_to_matrix). - Converts Nuke's camera-center translations into RealEstate10k-style world→camera translations via
t = -R * C; without this step ComfyUI interprets movement on the wrong axis. - Writes RealEstate10k-style rows:
- Columns 1–7: timestamp (µs), fx, fy, cx, cy, pose_width, pose_height.
- Columns 8–19:
[R|t]flattened row-major (each row’s three rotation entries followed by that row’s translation component).
- Header line records all parameters for traceability.
Usage example:
cd nuke_CAM_exporter
python nuke_ASCI-2-Pose_converter.py \
inputs/camTrack_v01.asci \
outputs/camTrack_v01_converted.txt \
--fps 25 --fx 0.5 --fy 0.5 --cx 0.5 --cy 0.5 --width 1280 --height 720
cd nuke_CAM_exporter
python nuke_ASCI-2-Pose_converter.py `
inputs/camTrack_v01.asci `
outputs/camTrack_v06_converted.txt `
--fps 25 --fx 0.5 --fy 0.5 --cx 0.5 --cy 0.5 `
--width 1248 --height 704 `
--start-frame 10 --end-frame 70 --max-frames 48
JSON-driven workflow
Use the template in configs/camera_config_template.json (copy + rename per shot):
{
"input": "../inputs/camTrack_v01.asci",
"output": "../outputs/camTrack_v06_converted.txt",
"fps": 25.0,
"unit_scale": 1.0,
"lens": {
"focal_length_mm": 33.5212349,
"sensor_width_mm": 36.0,
"sensor_height_mm": 24.0,
"principal_point_offset_x_mm": 0.0,
"principal_point_offset_y_mm": 0.0
},
"resolution": {
"width_px": 1248,
"height_px": 704
},
"frame_range": {
"start": 10,
"end": 170,
"max_frames": 60
}
}
Run:
cd nuke_CAM_exporter
python nuke_ASCI-2-Pose_converter.py --config configs/camera_config_v01.json
The script converts the physical lens info into RealEstate-style intrinsics:
fx = focal_length_mm / sensor_width_mmfy = focal_length_mm / sensor_height_mmcx = 0.5 + principal_offset_x_mm / sensor_width_mmcy = 0.5 + principal_offset_y_mm / sensor_height_mm
🔑 Getting the unit scale right (don’t skip!)
ComfyUI expects world→camera translations in meters. If your Nuke track uses a different scale, the pose will look correct in direction but wrong in amplitude. Use this checklist every time:
- Measure a real distance from the plate (dolly travel, two survey points, set dressing width). In Nuke you can:
- Use CameraTracker’s Set Reference Distance or a custom Axis/Card pair with a known separation.
- Enter the surveyed value (e.g. 6.3 m) directly into a distance expression.
- Read the raw ASCI delta for the same span. Example:
translate.zgoes from-0.215132to-0.105132⇒ raw delta =0.11. - Compute the multiplier:
unit_scale = real_distance_meters / asci_delta- If the real move is 3.5 m:
3.5 / 0.11 = 31.82⇒ set"unit_scale": 31.82. - If the scene is authored in centimeters (Nuke “World to Meters 100”), use
0.01.
- If the real move is 3.5 m:
- Store the measurement in your config so anyone regenerating the TXT knows where the number came from.
Tip: When the camera tracker already scaled the scene (you set a reference distance), the raw ASCI deltas are in meters and
unit_scalestays at1.0.
Once unit_scale is set, rerun the converter—the exported Z travel will match the original plate exactly.
Frame limiting options: Frame limiting options:
frame_range.start/--start-frame: zero-based index of the first ASCI row to keep.frame_range.end/--end-frame: exclusive stop index (omit or setnullto use all remaining frames).frame_range.max_frames/--max-frames: hard cap after slicing (useful when a loader needs a specific length) / Wan22 = 80 (for Wan's 81 frames recomended workflows)
Snippet (core formatting function):
def format_pose_rows(rotation, translation):
r = rotation
t = translation
return [
r[0][0], r[0][1], r[0][2], t[0],
r[1][0], r[1][1], r[1][2], t[1],
r[2][0], r[2][1], r[2][2], t[2],
]
3. Output
- Default target:
nuke_CAM_exporter/outputs/camTrack_v01_converted.txt - First rows look like:
source:inputs/camTrack_v01.asci fps:25.0 fx:0.5 fy:0.5 cx:0.5 cy:0.5 width:1280.0 height:720.0
0.000000000000 0.500000000000 ... 0.716894083480 0.478508303891 -0.507043071325 0.148742702111 ...
- Each row’s translation components (
... 0.1487427 ... -102.4243 ... -0.2049491) now match the camera values from Nuke frame 1.
4. Documentation
docs/camTrack_v01_converted_README.txtexplains:- Source file, fps, intrinsics, and placeholder dimensions.
- Column mapping
[Tx, Rx, Ty, Ry, Rz, Tz]and the ZXY rotation order. - Steps for regenerating the TXT and importing it into ComfyUI (
Koolook Load Camera Poses (Absolute Path)+CameraPoseVisualizer).
5. Validation Checklist
- In Nuke, verify the first keyframe values match the ASCI line (screenshot
DataValidation-nuke.png). - After running the converter, open the TXT and confirm the translation entries in row 1 match the screenshot.
- Load the TXT through the Koolook loader + CameraPoseVisualizer to visually confirm the path.
6. Using in ComfyUI:
- Copy
outputs/camTrack_v01_converted.txtinto ComfyUI's input folder (or reference the absolute path). - Use the
Koolook Load Camera Poses (Absolute Path)node to read it. - Preview with
CameraPoseVisualizerand feed into camera/motion encoder nodes.
Keep this document handy as a “resume” of the pipeline so future adjustments reference the same assumptions and file locations.