FreeD Link

FreeD Link

FreeD Link is a Blender add-on that drives Blender cameras from live FreeD D1 camera tracking over UDP. It maps position, rotation, zoom and focus, records keyframes while the timeline plays, and has a built-in simulator so you can test without hardware. FreeD Out sends a Blender camera as FreeD the other way.

Requires Blender 4.2 or newer, including 5.x.

Supported sources

Any device or software that sends FreeD D1 packets over UDP, for example:

FreeD Link reads only the D1 message. It does not support proprietary tracking protocols.

Install

  1. In Blender, open Edit > Preferences > Get Extensions.
  2. Open the drop-down menu at the top right and choose Install from Disk.
  3. Select the FreeD Link .zip.

The panel is in the 3D Viewport sidebar (press N), on the FreeD tab.

Quick start

  1. Click Start. If the Cameras list is empty, FreeD Link adds a mapping from FreeD ID 1 to the scene camera.
  2. Open Test Signal and click Start Simulator. The scene camera orbits the origin at 4 m radius and 1.6 m height, looking at the origin.
  3. Click Stop Simulator, point your tracker at this computer's IP on port 20000, and check the status box for a line such as ID 1: 50 packets/s.
  4. In Cameras, set each row's ID to the FreeD ID your tracker sends and pick the Blender camera. Use + to add a row per tracked camera; with a camera selected in the viewport, + maps it.

The status box shows the listen address, one line per camera ID with its packets per second, and counts of bad checksums and non-D1 packets. A camera ID with no packets for Stale After seconds shows as lost, and its camera stops moving until packets return.

Changes to Interface and Port apply on the next Start.

Axes

Open Axes and move the real camera to check each direction.

SettingUse
Position ScaleBlender units per FreeD millimetre. Default 0.001 gives metres.
Pan 0 FacesThe Blender axis the camera looks along at pan 0. Default +Y.
-X, -Y, -ZInvert a position axis.
X/YSwap the X and Y position axes.
-Pan, -Tilt, -RollInvert a rotation.
Smoothing0 is raw. Higher values remove jitter and add lag. Maximum 0.95.
Delay (ms)Holds tracking back to match delayed video. Maximum 2000 ms.
Stale After (s)A camera ID with no packets for this long shows as lost. Default 1 s.
Ignore ChecksumOn by default. Applies packets with a wrong checksum byte; some devices send 0.
Raw Values as Custom PropertiesWrites freed_pan, freed_tilt, freed_roll (degrees) and freed_zoom, freed_focus (raw encoder) to the camera object for drivers.

Tracker origin

FreeD Link writes the tracker's pose into the camera's own location and rotation. An unparented camera therefore sits at the tracker's pose in world space. To move or rotate the tracking origin, parent the camera to an Empty: the Empty is the tracker origin and the camera follows it (the parent inverse is reset to identity when tracking starts).

PTZ cameras usually send position 0, so the camera sits at its parent Empty, or at the Blender origin without one. Place the Empty where the PTZ head is.

Lens calibration

Zoom and focus arrive as raw encoder values. Calibration tables convert them to focal length (mm) and focus distance (m), with linear interpolation between rows. Each camera in Cameras has its own tables, because each lens has its own encoder range. Rows are sorted by raw value automatically. Outside the table, the nearest row's value is used.

  1. Click Start and make sure tracking is arriving.
  2. Select the camera's row in Cameras. Lens shows that camera's tables and reads live values from its FreeD ID.
  3. Open Lens and enable Drive Focal Length.
  4. Zoom the real lens fully wide. Click + to add a row. It takes the live raw value. Type the focal length.
  5. Zoom fully tight. Click + and type the focal length.
  6. Repeat at 1 to 3 points in between, so you have 3 to 5 rows.

Repeat for each tracked camera.

To re-read the live encoder into the selected row, click the eyedropper (Capture Raw).

Type the focal length that makes the Blender view match the real picture, with the Blender camera's sensor size set to the real camera's sensor.

Focus works the same way: enable Drive Focus Distance, rack focus to marks at known distances, and type each distance in metres. Enable Enable Depth of Field to switch on depth of field on the camera.

Recording

  1. Click Start.
  2. Click Record. It changes to Recording.
  3. Press Play on the timeline.

On every frame, FreeD Link applies the newest packet and writes keyframes for each camera that received packets. Transform keys location and rotation. Lens keys focal length and focus distance, when they are driven. Click Recording again, or Stop, to end the take.

With Stop at Frame End on (the default), the take ends and playback stops at the scene's end frame, or at the preview range end when a preview range is set. A take also ends whenever the frame moves backwards, so a looping timeline never overwrites the keys it just wrote. Turn the option off only to record past the end frame on an extended timeline.

Ending a take pauses live tracking, so you can play back and review the recorded keys. FreeD Link keeps listening. Click Go Live to drive the cameras again.

While recording, any frame change writes keys, including scrubbing. Turn recording off before scrubbing.

FreeD Out

FreeD Out sends a Blender camera's pose as FreeD D1 packets over UDP, so an animated or hand-moved Blender camera can drive Unreal Engine, Aximmetry, Vizrt or another FreeD Link.

SettingUse
Host, PortDestination IP or host name and UDP port. Default 127.0.0.1:20001.
Rate (Hz)Packets per second. Default 50.
FreeD IDCamera id byte in each packet.
CameraCamera to send. Empty sends the scene camera.
Zoom/Focus From Lens TablesConverts focal length and focus distance back to raw values through that camera's tables in Lens. Without a table, or with this off, it sends the camera's freed_zoom and freed_focus custom properties, or 0.

Click Start Sending. The status box shows Sending to host:port and Sent 50/s. A background thread sends at the set rate even while the viewport is busy, repeating the latest pose when the camera is still, as trackers do. The pose is updated on every frame change, so playback and scrubbing reach the receiver at once.

Packets use the Axes settings in reverse, so a receiver with the same settings reproduces the camera exactly. A parented camera is sent relative to its parent, the tracker origin. Changes to Host and Port apply on the next Start Sending.

FreeD Link refuses to send to 127.0.0.1 on the port its own receiver listens on, to avoid a feedback loop.

To test with the built-in receiver, open a second Blender, set Port to 20001 and click Start. In the first Blender, open FreeD Out, keep 127.0.0.1:20001 and click Start Sending. The second Blender shows ID 1: 50 packets/s and its camera follows the first one's.

Networking

Command-line test sender

freed_sender.py in the extension folder sends test packets from any computer with Python 3, without Blender. Copy the whole freed_link folder to use it elsewhere:

python3 -I freed_link/freed_sender.py --host 192.168.1.20 --port 20000 --rate 50 --id 1 --seconds 30
python3 -I freed_link/freed_sender.py --static --pan 45 --tilt -10 --z 1600 --zoom 524288

Without --static it sends the orbiting camera. --seconds 0 runs until Ctrl+C. Static pose units are degrees, millimetres and raw encoder values.

Troubleshooting

SymptomFix
No packets yet or lostCheck the tracker's destination IP and port, the firewall, and Interface.
Cannot listen on ... when startingThe port is in use, or Interface is not an address of this computer.
Packets arrive but the camera does not moveIf the button reads Go Live, click it. In Cameras, check the row is enabled, its ID has a line in the status box, and a camera is set.
Bad checksum rises and the camera does not moveEnable Ignore Checksum.
Ignored non-D1 risesSet the device to output FreeD D1.
Simulator does not move the cameraClick Start as well, and set Interface to 0.0.0.0.
Camera pans the wrong wayToggle -Pan.
Camera faces the wrong way at pan 0Change Pan 0 Faces.
Camera moves along the wrong axisUse X/Y, -X, -Y, -Z.
Movement is 1000 times too big or smallSet Position Scale to 0.001 (FreeD millimetres to metres).
JitterRaise Smoothing, starting at 0.3.
Graphics move before the videoRaise Delay (ms) until they line up.
Focal length does not changeSelect the camera's row in Cameras, then in Lens enable Drive Focal Length and add at least one row.
Recording writes no keysCheck the button reads Recording, the camera's ID is receiving packets, then press Play.
Recording stops at the last frameStop at Frame End is on. Extend the frame range or turn it off.
Gaps between recorded keysPlayback dropped frames. Those frames are interpolated.

License

GPL-3.0-or-later. See LICENSE. The extension zip includes the license text.

Copyright 2026 Bjorn Schobben.