# Generating HDR Videos with EXR Output and Color Space Options in LTX-2

> Generate HDR videos with EXR output in LTX-2 using SRGB_LINEAR, ACESCG, or ACESCCT color spaces. Leverage HDRICLoraPipeline or the --hdr flag for professional results.

- Repository: [Lightricks/LTX-2](https://github.com/Lightricks/LTX-2)
- Tags: how-to-guide
- Published: 2026-08-15

---

**LTX-2 supports HDR video generation via OpenEXR frame export with three color space options—SRGB_LINEAR, ACESCG, and ACESCCT—using either the dedicated `HDRICLoraPipeline` or the native `--hdr` CLI flag.**

The LTX-2 video generation model from Lightricks provides full high-dynamic-range (HDR) workflows that output scene-linear OpenEXR frames with precise color space metadata. This article explains how to generate HDR videos with EXR output and color space options using both the Python API and command-line interfaces, based on the actual implementation in the [Lightricks/LTX-2](https://github.com/Lightricks/LTX-2) repository.

## HDR Color Space Architecture

All HDR pipelines in LTX-2 revolve around the `HDRColorSpace` enum defined in [`ltx_pipelines/utils/media_io/color_config.py`](https://github.com/Lightricks/LTX-2/blob/main/ltx_pipelines/utils/media_io/color_config.py). This enum declares three supported source color spaces and provides the metadata required for correct EXR tagging.

### Supported Color Spaces

| Space | Description | Processing Path |
|-------|-------------|---------------|
| **SRGB_LINEAR** | Scene-linear Rec.709/sRGB EXR | Compressed to ACEScct before VAE encoding |
| **ACESCG** | Scene-linear ACEScg EXR | Compressed to ACEScct before VAE encoding |
| **ACESCCT** | Log-encoded ACEScct EXR | Passed through unchanged (pre-compressed) |

The property `HDRColorSpace.is_log_working` determines whether the loader must apply a transfer function, and `HDRColorSpace.exr_output_tags()` returns the correct primaries and color space label for EXR file headers.

## Core EXR I/O Implementation

The low-level OpenEXR handling lives in [`ltx_pipelines/utils/media_io/exr.py`](https://github.com/Lightricks/LTX-2/blob/main/ltx_pipelines/utils/media_io/exr.py). These utilities power both the native HDR path and the dedicated HDR-IC-LoRA pipeline.

### Key Functions in exr.py

- **`read_exr()`** — Reads a single scene-linear EXR frame into a `torch.Tensor` with shape `[H, W, 3]`
- **`load_exr_conditioning_hdr()`** — Streams multiple EXR frames, applies the color space transfer defined by `HDRColorSpace`, and resizes to VAE input resolution
- **`save_exr_tensor()`** — Writes a tensor to half-float or full-float EXR with proper primaries and color space tags
- **`encode_exr_sequence_to_mp4()`** — Converts linear EXR frames to sRGB and encodes H.264/MP4 for SDR-compatible preview

## HDR-IC-LoRA Pipeline: Full Implementation

The `HDRICLoraPipeline` class in [`ltx_pipelines/hdr_ic_lora.py`](https://github.com/Lightricks/LTX-2/blob/main/ltx_pipelines/hdr_ic_lora.py) provides the primary interface for HDR video generation with LoRA fine-tuning support.

### Pipeline Workflow

1. **Initialization** — Loads HDR LoRA weights, reads embedded metadata via `read_hdr_lora_config()`, and constructs the VAE conditioner, diffusion stages, spatial upsampler, and decoder
2. **Conditioning** — `_create_conditionings()` calls `load_video_conditioning_hdr()`, which wraps `load_exr_conditioning_hdr()` to produce HDR-ready latent tensors
3. **Generation** — Two-stage process: low-resolution generation (stage 1) followed by full-resolution refinement (stage 2). With `high_quality_hdr=True`, the pipeline generates 2× frames and discards every other frame to reduce temporal artifacts
4. **Decoding** — `_decode_video()` converts VAE latents to linear HDR float32 via `to_hdr_linear()` (using `HDRTransfer.LOGC3`), yielding a tensor of shape `[F, H, W, C]`
5. **Export** — Per-frame EXR export using `save_exr_tensor()` with correct metadata; optional HLG-encoded MP4 preview via `encode_exr_sequence_to_mp4()`

## Python API: Generating HDR Videos

The following complete example demonstrates HDR video generation with EXR output and color space options using the `HDRICLoraPipeline`:

```python
from pathlib import Path
import torch
from ltx_pipelines.hdr_ic_lora import HDRICLoraPipeline, HdrLoraConfig
from ltx_pipelines.utils.model_paths import ModelPaths
from ltx_pipelines.utils.media_io.color_config import HDRColorSpace
from ltx_pipelines.utils.media_io.exr import save_exr_tensor

# -------------------------------------------------

# 1. Configure model paths

# -------------------------------------------------

model_paths = ModelPaths.from_monolith(
    transformer_path="models/ltx-2.3-22b-distilled.safetensors",
    video_vae_path=None,  # Use transformer-integrated VAE

    gemma_root=None,
)

# -------------------------------------------------

# 2. Initialize HDR pipeline with LoRA

# -------------------------------------------------

pipeline = HDRICLoraPipeline(
    model_paths=model_paths,
    spatial_upsampler_path="models/ltx-2.3-spatial-upscaler-x2-1.0.safetensors",
    hdr_lora="path/to/hdr_lora.safetensors",
    text_embeddings_path="path/to/hdr_scene_emb.safetensors",
    hdr_lora_config=HdrLoraConfig(hdr_transform=None),  # Auto-detect from LoRA

)

# -------------------------------------------------

# 3. Generate HDR video

# -------------------------------------------------

hdr_frames = pipeline(
    seed=42,
    height=1080,
    width=1920,
    num_frames=121,  # Must satisfy (frames - 1) % 8 == 0

    frame_rate=30.0,
    video_conditioning=[("videos/source_exr_folder", 1.0)],  # EXR directory

    high_quality_hdr=True,  # Enable 2× frame generation for smoother motion

)

# -------------------------------------------------

# 4. Export as tagged EXR sequence

# -------------------------------------------------

out_dir = Path("hdr_output")
out_dir.mkdir(parents=True, exist_ok=True)

primaries, tag = HDRColorSpace.SRGB_LINEAR.exr_output_tags()

for i, frame in enumerate(hdr_frames):
    save_exr_tensor(
        tensor=frame.cpu(),
        file_path=out_dir / f"frame_{i:05d}.exr",
        half=True,  # Half-float 16-bit output

        primaries=primaries,
        color_space=tag,
    )

```

**Key implementation details:**

- `video_conditioning` accepts a directory path containing `*.exr` files; the pipeline automatically enables HDR processing
- `high_quality_hdr=True` doubles internal frame generation and drops every second frame, trading ~2× compute for reduced temporal artifacts
- `HDRColorSpace.SRGB_LINEAR.exr_output_tags()` provides the chromaticity primaries and string label required for compliant EXR headers

## CLI-Based HDR Generation

The [`hdr_ic_lora.py`](https://github.com/Lightricks/LTX-2/blob/main/hdr_ic_lora.py) module provides a command-line interface for batch HDR processing with automatic EXR export and MP4 preview generation.

### HDR-IC-LoRA CLI Command

```bash
uv run python -m ltx_pipelines.hdr_ic_lora \
    --input ./input_videos/ \
    --output-dir ./hdr_output/ \
    --hdr-lora ./weights/hdr_lora.safetensors \
    --text-embeddings ./weights/hdr_scene_emb.safetensors \
    --distilled-checkpoint-path ./weights/ltx-2.3-22b-distilled.safetensors \
    --spatial-upsampler-path ./weights/ltx-2.3-spatial-upscaler-x2-1.0.safetensors \
    --num-frames 121 \
    --high-quality \
    --seed 10

```

**CLI output structure:**

- `<video_name>_exr/` — Directory containing half-float EXR frames with embedded color space metadata
- `<video_name>.mp4` — H.264 preview encoded in BT.2020/HLG for SDR-compatible playback

The `_process_single_video()` helper orchestrates this pipeline: it invokes `HDRICLoraPipeline.__call__()`, saves frames via `save_exr_tensor()`, then runs `encode_exr_sequence_to_mp4()` for preview generation.

## Native HDR Flag: Non-LoRA Workflows

For pipelines without dedicated HDR LoRA weights, use the `--hdr` flag with standard conditioning:

```bash
uv run python -m ltx_pipelines.distilled \
    --transformer-path models/ltx-2.5/diffusion_models/ltx-2.5-22b-distilled-transformer-bf16.safetensors \
    --text-encoder-path models/ltx-2.5/text_encoders/gemma4-12b-with-proj-ltx-2.5-bf16.safetensors \
    --video-vae-path models/ltx-2.5/vae/ltx-2.5-video-vae-bf16.safetensors \
    --spatial-upsampler-path models/ltx-2.5/latent_upscale_models/ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors \
    --num-frames 121 \
    --prompt "Sunrise over a mountain lake" \
    --image path/to/scene.exr 0 1.0 \
    --hdr SRGB_LINEAR \
    --output-path output/mountain_rise.mp4

```

The `--hdr SRGB_LINEAR` argument triggers:
- Scene-linear EXR interpretation via `load_exr_conditioning_hdr()`
- ACEScct compression before VAE encoding
- Half-float EXR frame export with correct metadata
- Automatic BT.2020/HLG MP4 preview generation

## HDR Transfer Functions

The [`ltx_core/hdr.py`](https://github.com/Lightricks/LTX-2/blob/main/ltx_core/hdr.py) module defines `HDRTransfer.LOGC3`, which provides the `to_hdr_linear()` conversion used during decoding. This LogC3 transform is specific to the HDR-IC-LoRA path; native `--hdr` workflows use the ACEScct working space exclusively.

## Reference Implementation Files

| File Path | Purpose |
|-----------|---------|
| [`packages/ltx-pipelines/src/ltx_pipelines/utils/media_io/exr.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/src/ltx_pipelines/utils/media_io/exr.py) | OpenEXR read/write, HDR conditioning, EXR-to-MP4 conversion |
| [`packages/ltx-pipelines/src/ltx_pipelines/utils/media_io/color_config.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/src/ltx_pipelines/utils/media_io/color_config.py) | `HDRColorSpace` enum, color space transfers, EXR tag generation |
| [`packages/ltx-pipelines/src/ltx_pipelines/hdr_ic_lora.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/src/ltx_pipelines/hdr_ic_lora.py) | `HDRICLoraPipeline` class, generation workflow, CLI helpers |
| [`packages/ltx-pipelines/docs/hdr.md`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/docs/hdr.md) | Official documentation for HDR workflows and CLI flags |

## Summary

- **Three color spaces** are supported via `HDRColorSpace`: `SRGB_LINEAR`, `ACESCG`, and `ACESCCT`, each with appropriate transfer and tagging behavior
- **Two pipeline paths** exist: the dedicated `HDRICLoraPipeline` for LoRA-tuned generation, and the native `--hdr` flag for general conditioning workflows
- **EXR output** is produced via `save_exr_tensor()` with half-float precision and embedded primaries/color space metadata
- **Preview generation** automatically creates BT.2020/HLG MP4 files via `encode_exr_sequence_to_mp4()` for SDR-compatible playback
- **High-quality mode** (`high_quality_hdr=True`) reduces temporal artifacts by generating 2× frames and discarding every other frame

## Frequently Asked Questions

### What color space should I use for HDR video generation in LTX-2?

Use `SRGB_LINEAR` for standard scene-linear Rec.709/sRGB workflows, `ACESCG` for ACEScg linear pipelines, or `ACESCCT` if your input EXR files are already log-encoded in ACEScct. The `HDRColorSpace` enum in [`color_config.py`](https://github.com/Lightricks/LTX-2/blob/main/color_config.py) handles the appropriate transfer for each case.

### How do I export HDR frames as OpenEXR files?

Call `save_exr_tensor()` from [`ltx_pipelines/utils/media_io/exr.py`](https://github.com/Lightricks/LTX-2/blob/main/ltx_pipelines/utils/media_io/exr.py) with your tensor, output path, and color space tags from `HDRColorSpace.exr_output_tags()`. Set `half=True` for standard half-float 16-bit output that balances quality and file size.

### What is the difference between HDR-IC-LoRA and the native --hdr flag?

`HDRICLoraPipeline` loads dedicated HDR LoRA weights and applies a LogC3 inverse transform during decoding, enabling higher-fidelity HDR generation for specific scene types. The native `--hdr` flag works with any conditioning input but uses ACEScct as the exclusive working space and does not require LoRA weights.

### Can I generate an HLG preview alongside EXR output?

Yes. The HDR-IC-LoRA CLI automatically produces an H.264 MP4 preview in BT.2020/HLG color space via `encode_exr_sequence_to_mp4()`. For Python API usage, call this function manually on your saved EXR sequence.