# Follow, Birdeye, Static, and Pivot Camera Modes in LingBot-Map: Technical Differences Explained

> Explore LingBot-Map's follow, birdeye, static, and pivot camera modes. Understand technical differences in viewpoint calculation for trajectories and discover their unique applications for visualization.

- Repository: [Robbyant/lingbot-map](https://github.com/Robbyant/lingbot-map)
- Tags: deep-dive
- Published: 2026-07-04

---

**LingBot-Map's offline renderer supports four distinct camera modes—follow, birdeye, static, and pivot—that determine how the virtual eye-position and look-at target are calculated from input trajectories, ranging from chase cameras to fixed viewpoints and orbital sweeps.**

The LingBot-Map repository provides an offline rendering pipeline for cinematic trajectory visualization. Configured through YAML `camera:` blocks parsed by [`demo_render/batch_demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo_render/batch_demo.py), the renderer implements these four modes to control how the virtual camera tracks, reveals, or fixes upon the scene according to the implementation in the repository's camera-path construction code.

## How Camera Modes Work

Each camera mode defines a specific algorithm for computing the `eye` (camera position) and `lookat` (view target) vectors during rendering. All four modes share the same underlying data structures—a list of timestamps and poses—but differ in **when** and **how** these vectors are updated per frame.

### Follow Mode

**Follow** mode implements a chase camera that trails the input trajectory, keeping the vehicle or subject near the center of the view.

The renderer calculates the eye position relative to the current pose using directional offsets expressed as fractions of the scene's scale:

```python

# pseudo-code from the renderer's camera module

def follow_eye(pose, back_offset, up_offset, scene_scale):
    forward = pose[:, :3] @ np.array([0, 0, 1])
    up = pose[:, :3] @ np.array([0, 1, 0])
    eye = (pose[:3, 3] 
           - back_offset * scene_scale * forward 
           + up_offset * scene_scale * up)
    return eye

```

The look-at target is computed as `pose + look_offset·forward`. The mode supports a `smooth_window` parameter that applies low-pass filtering to the trajectory before offset calculation, reducing jitter in walk-throughs or drone footage.

### Birdeye Mode

**Birdeye** mode creates a top-down reveal by lifting the camera straight up to view the entire scene from above.

The eye height is set to `reveal_height_mult × scene_scale`, while the look-at point remains fixed at the trajectory's center. Unlike follow mode, the camera does not move laterally; it only elevates vertically to provide an overview map effect, typically used for hero shots or final reveal sequences.

### Static Mode

**Static** mode locks both the eye position and look-at target to their values from the segment's first frame.

The engine samples the input pose at the initial frame of the segment and maintains constant `eye` and `lookat` vectors throughout the entire duration. This creates fixed cut-scenes where the camera viewpoint never changes, regardless of trajectory movement.

### Pivot Mode

**Pivot** mode fixes the eye position to the segment's starting frame while continuously updating the look-at target to track the current trajectory pose.

This creates an orbital effect where the camera appears to pivot around a stationary point of interest, with the view sweeping along the subject's path while the observer remains stationary.

## Configuring Camera Modes in YAML

Camera modes are specified in the `camera:` block of configuration files located in `demo_render/config/*.yaml` (such as [`default.yaml`](https://github.com/Robbyant/lingbot-map/blob/main/default.yaml), [`indoor.yaml`](https://github.com/Robbyant/lingbot-map/blob/main/indoor.yaml), or [`outdoor_drive.yaml`](https://github.com/Robbyant/lingbot-map/blob/main/outdoor_drive.yaml)). Each segment in the `segments` list declares a `mode` and its specific parameters.

```yaml
camera:
  fov: 60.0
  transition: 30
  segments:
    - mode: follow
      frames: [0, 1500]
      back_offset: 0.3
      up_offset: 0.08
      look_offset: 0.4
      smooth_window: 30

    - mode: birdeye
      frames: [1500, 1800]
      reveal_height_mult: 2.5

    - mode: static
      frames: [1800, 2100]

    - mode: pivot
      frames: [2100, -1]

```

The `frames` parameter defines the start and end indices for each segment, where `-1` indicates the final frame of the trajectory.

## Command-Line Overrides

You can override the YAML configuration and force a specific mode for the entire video using the `--camera_mode` argument:

```bash
python demo_render/batch_demo.py \
  --video_path demo.mp4 \
  --output_folder out/ \
  --config demo_render/config/default.yaml \
  --camera_mode pivot

```

This command forces pivot mode for all frames, bypassing the segment definitions in the YAML file.

## Key Implementation Files

| File | Role |
|------|------|
| [`README.md`](https://github.com/Robbyant/lingbot-map/blob/main/README.md) | Documents the four camera modes and their tunable fields (lines 503-509) |
| `demo_render/config/*.yaml` | YAML presets containing `camera:` block definitions |
| [`demo_render/batch_demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo_render/batch_demo.py) | Entry point that parses YAML and initiates rendering |
| Renderer camera module | Implements the mathematical calculations for eye/look-at vectors |

## Summary

- **Follow** mode creates a chase camera using relative offsets (`back_offset`, `up_offset`, `look_offset`) and optional smoothing via `smooth_window`.
- **Birdeye** mode generates a top-down view using `reveal_height_mult` to scale the camera height above the scene.
- **Static** mode locks both eye and look-at positions to the first frame of the segment.
- **Pivot** mode maintains a fixed eye position while sweeping the look-at target along the trajectory.
- All modes are configured via YAML in `demo_render/config/*.yaml` and can be overridden via command-line arguments.

## Frequently Asked Questions

### What is the difference between follow and pivot camera modes in LingBot-Map?

**Follow** mode moves both the camera position and view target along the trajectory, creating a chase effect with configurable offsets relative to the current pose. **Pivot** mode keeps the camera eye stationary at the segment's starting position while only the look-at target moves with the trajectory, creating a fixed-camera sweep effect where the camera appears to orbit around the subject.

### How do I configure smooth camera movements in LingBot-Map to reduce jitter?

For smooth motion, use **follow** mode with the `smooth_window` parameter, which applies a low-pass filter to the trajectory before calculating camera offsets. According to the source code, this smoothing window "optionally low-passes the trajectory before applying the offsets," making it ideal for drone footage or handheld capture data.

### Can I combine multiple camera modes in a single LingBot-Map video?

Yes. The YAML configuration supports multiple segments in the `camera:` block, each with its own `mode` and `frames` range. The renderer transitions between segments over the specified `transition` frame count, allowing you to sequence follow, birdeye, static, and pivot modes within one output video to create complex cinematic camera paths.

### Where are the camera mode parameters documented in the LingBot-Map repository?

The official documentation for camera modes and their parameters is located in [`README.md`](https://github.com/Robbyant/lingbot-map/blob/main/README.md) at lines 503-509, which describes the available fields for each mode such as `back_offset`, `reveal_height_mult`, and `smooth_window`. The implementation itself resides in the renderer's camera-path construction code that parses the YAML and builds per-frame eye/look-at vectors.