Overview
GimbalDiffusion enables precise camera control in text-to-video generation by using gravity as a global reference point. The absolute coordinate system eliminates the need for relative frame references while null-pitch conditioning prevents conflicting text instructions.
When to Use
- Text-to-video with precise camera control
- Panoramic video generation from 360-degree data
- Scenarios requiring wide camera pitch variation
- Need for interpretable camera motion
- Avoiding relative trajectory ambiguity
When NOT to Use
- Simple camera-static videos
- Scenarios without camera control requirements
- Applications with limited training data
Core Technique
Gravity-aware camera coordinate system:
# GimbalDiffusion: Gravity-aware camera control
class GravityAwareCameraControl:
def __init__(self):
self.diffusion = DiffusionModel()
def condition_on_camera_trajectory(self, camera_params):
"""
Camera parameters in gravity-aligned coordinate system.
pitch, yaw, roll relative to gravity vector (down).
"""
# Extract camera parameters
pitch = camera_params['pitch'] # Up/down (-90 to 90)
yaw = camera_params['yaw'] # Left/right (0-360)
roll = camera_params['roll'] # Rotation (0-360)
# Gravity-aligned embedding
gravity_vector = torch.tensor([0, -1, 0]) # Down
# Create camera embedding from angles
camera_embedding = self.encode_camera_angles(
pitch, yaw, roll, gravity_vector
)
return camera_embedding
def apply_nullpitch_conditioning(self, text_instruction, camera_pitch):
"""
Null-pitch conditioning: prevent model from conflicting
with text when camera pitch contradicts content.
E.g., sky-pointing camera shouldn't generate grass.
"""
# Analyze text semantics
scene_orientation = self.analyze_text(text_instruction)
# Check camera-text conflict
if self.is_conflicting(camera_pitch, scene_orientation):
# Apply null-pitch: mask camera pitch contribution
# Model focuses on text, ignores conflicting pitch
camera_embedding = self.apply_null_pitch_mask(
camera_pitch
)
else:
camera_embedding = self.condition_on_camera_trajectory(
{'pitch': camera_pitch, 'yaw': 0, 'roll': 0}
)
return camera_embedding
def generate_video_with_camera(self, prompt, camera_trajectory):
"""Generate video with camera motion control."""
# Camera trajectory: list of (pitch, yaw, roll) over frames
frames = []
for frame_idx, camera_params in enumerate(camera_trajectory):
# Get camera conditioning
camera_cond = self.apply_nullpitch_conditioning(
prompt, camera_params['pitch']
)
# Generate frame with camera control
frame = self.diffusion.sample(
prompt=prompt,
camera_conditioning=camera_cond
)
frames.append(frame)
return torch.stack(frames)
def encode_camera_angles(self, pitch, yaw, roll, gravity):
"""Encode camera angles relative to gravity."""
# Build rotation matrix from angles
rotation_matrix = self.euler_to_rotation(pitch, yaw, roll)
# Embed rotation relative to gravity
embedding = self.rotate_embedding(gravity, rotation_matrix)
return embedding
Key Results
- Precise camera control from diverse 360-video data
- Null-pitch conditioning resolves text conflicts
- SpatialVID-HQ benchmark rebalancing
References
- Original paper: https://arxiv.org/abs/2512.09112
- Focus: Camera-controlled video generation
- Domain: Video synthesis, spatial control