How to Create a Tilt-Shift Effect in FFmpeg
This article provides a straightforward guide on how to simulate a tilt-shift depth-of-field effect on Standard Dynamic Range (SDR) video using FFmpeg. You will learn how to use a combination of splitting, blurring, and mathematical blending filters to keep the center of your footage sharp while smoothly blurring the top and bottom edges to create a miniature toy-like perspective.
The Tilt-Shift FFmpeg Command
To achieve a tilt-shift effect, you must split your video into two paths: one that remains sharp and one that is heavily blurred. You then blend them back together using a linear gradient mask that targets the vertical Y-coordinates of the frame.
Run the following command in your terminal:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]split[sharp][temp]; \
[temp]boxblur=luma_radius=15:luma_power=3[blurred]; \
[blurred][sharp]blend=all_expr='A*(abs(Y-H/2)/(H/2)) + B*(1-(abs(Y-H/2)/(H/2)))'[out]" \
-map "[out]" -c:a copy output.mp4How the Filter Chain Works
split[sharp][temp]: This splits the input video stream into two identical streams. The first stream ([sharp]) is kept pristine, while the second stream ([temp]) is sent to the blur filter.boxblur=luma_radius=15:luma_power=3: This applies a heavy blur to the temporary stream, turning it into the background blur ([blurred]). You can increase theluma_radiusfor a stronger blur.blend=all_expr='...': This filter merges the blurred video (A) and the sharp video (B) using a mathematical expression based on the vertical pixel position (Y) and the total height of the video (H).- At the exact vertical center (
Y = H/2), the expression evaluates to output 100% of the sharp video (B). - At the very top (
Y = 0) and very bottom (Y = H), the expression evaluates to output 100% of the blurred video (A). - The transition between the sharp center and the blurred edges is perfectly linear and smooth.
- At the exact vertical center (
Adjusting the Focus Width
If you want to widen the sharp area in the center of the screen before the blur begins to fade in, you can modify the algebraic expression using a power factor.
For a wider, sharper center focus band, use this modified blend expression:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]split[sharp][temp]; \
[temp]boxblur=20:5[blurred]; \
[blurred][sharp]blend=all_expr='A*pow(abs(Y-H/2)/(H/2), 2) + B*(1-pow(abs(Y-H/2)/(H/2), 2))'[out]" \
-map "[out]" -c:a copy output.mp4Using pow(..., 2) squaring the ratio compresses the
transition curve, keeping a larger portion of the center of your SDR
video in sharp focus before quickly transitioning to the blur at the top
and bottom margins.
Alternative: Did you mean the “tile” filter?
If you arrived here looking to tile multiple sequential video frames
into a single grid layout rather than applying a vertical tilt blur,
FFmpeg uses the tile filter for this purpose:
ffmpeg -i input.mp4 -vf "tile=3x2" -frames:v 1 grid_output.pngThis command takes the first 6 frames of the video and arranges them into a 3-column, 2-row grid image.