Portrait Video Relighting with Dynamic Lighting
NeurIPS 2026
Jiahui Sheng1,*, Le Li2,†, Limin Lin2, Jiahao Li2, Wansen Feng2, Hong Gu2, Shuhan Chen1, Xiaorun Li1,‡, Rui Hu2,‡
1 Zhejiang University, China · 2 vivo BlueImage Lab, vivo Mobile Communication Co., Ltd., China
* Work done during an internship at vivo. † Project leader. ‡ Corresponding authors.
FlashRelight relights portrait videos with an HDR environment map or transfers lighting from a reference video. Its first stage, FlashDelight, can also run on its own to suppress the original lighting.
FlashDelight estimates a neutrally lit portrait video. FlashRelight uses that estimate and a frame from the input video to preserve the subject’s appearance while applying the target lighting.
We render 24,000 video pairs from static one-light-at-a-time (OLAT) captures using known lighting sequences. Over 10,000 generated video pairs show subjects moving under changing light.
How the training pairs differ between the two stages
For FlashDelight, we add synthetic lighting changes to generated, neutrally lit clips. For FlashRelight, we generate clips under changing light and use FlashDelight to produce their neutral counterparts.
Each pair shows the original video on the left and the FlashDelight output on the right.
Each comparison below shows the input portrait, lighting control, delighted portrait, and relit result, from left to right.
| Lighting control | Watch the comparison |
|---|---|
| HDR sequence | Light moving around the portrait |
| Single HDR panorama (fixed or rotating) | Meadow 2 rotating at 60°/s |
| Reference video | Studio light sweeping across the face |
| Text prompt | Dappled light moving across the face |
Compare reference lighting across portraits
The top row shows the reference lights. Each row below shows an input portrait on the left and its relit results under each reference.
Use Linux, Conda, and an NVIDIA GPU. The default environment uses Python 3.10 and PyTorch 2.1.0 with CUDA 12.1, as tested on the H20.
git clone https://github.com/vivoCameraResearch/FlashRelight.git
cd FlashRelight
bash install.sh
conda activate flashrelightFor the RTX 5090 D examples, we used Python 3.11 and PyTorch 2.14.0+cu132. If you already have a PyTorch environment for your GPU, install the remaining packages with pip install -r requirements.txt.
Download the FlashDelight and FlashRelight checkpoints together with the shared Wan2.1 files. Hugging Face weights
python scripts/download_weights.py --dest weights --skip_matting_modelThe bundled portraits already have black backgrounds. For footage that needs background removal, omit --skip_matting_model during setup and use --matting birefnet at inference. Offline setup and weight layout
python scripts/infer.py --source assets/sources/generated_gesture.mp4 --matting none \
--mode env --env_map assets/envmaps/04_random_great_circleOpen outputs/generated_gesture_env_relit.mp4 for the relit portrait (49 frames, 480 × 832 pixels, 16 fps). The same folder contains the delighted portrait (*_delit.mp4) and the comparison (*_compare.mp4).
For your own input, pass a portrait video or still image to --source. All six bundled environment maps retain their original HDR values. FlashRelight applies the 0.1 scale automatically during inference.
Run all four examples with python scripts/infer.py --samples assets/samples.json. Sample configurations
Use a single panorama, a reference video, or a text prompt
Single HDR panorama. A panorama stays fixed for all 49 frames by default. Set --env_rotation_speed in degrees per second to rotate it. Positive values move the light to the right in the panorama preview.
python scripts/infer.py --source assets/sources/generated_portrait.mp4 --matting none \
--mode env --env_map assets/envmaps/meadow_2_4k.exr --env_rotation_speed 60The --env_map flag accepts a single EXR/HDR panorama, a directory of ordered EXR/HDR frames, or a NumPy array such as [T,3,H,W]. The model resizes each map to 128 × 64 pixels.
Reference video. Transfer the lighting from the studio clip to a different portrait.
python scripts/infer.py --source assets/sources/generated_gesture.mp4 --matting none \
--mode light_ref --light_ref assets/light_refs/studio_sweep.mp4Text prompt. Text control works best with lighting descriptions close to the training captions. Example prompts
python scripts/infer.py --source assets/sources/generated_portrait.mp4 --matting none \
--mode text --prompt "Across the face, irregular dappled light patches wander with an organic motion."To run delighting alone, use the FlashDelight checkpoint and the shared Wan2.1 files. If you already prepared both stages, go straight to the inference command.
python scripts/download_weights.py --dest weights --delight_only --skip_matting_model
python scripts/infer.py --delight_only --source assets/sources/generated_portrait.mp4 --matting noneThis writes outputs/generated_portrait_delit.mp4. For the portrait with glasses, use --source assets/sources/generated_gesture.mp4. See both delighting results
Use FlashDelight from Python
from flashrelight import FlashRelightPipeline
from flashrelight.utils import video_io
pipe = FlashRelightPipeline("weights", delight_only=True)
frames = pipe.preprocess("assets/sources/generated_portrait.mp4", matting="none")
video_io.save_mp4(pipe.delight_frames(frames), "delighted.mp4", fps=16)Gradio lets you run FlashRelight from a browser. After preparing the weights, start the web interface on your GPU machine.
python app.py --matting noneOpen the local URL printed in the terminal. Choose a bundled portrait or upload your own, select a lighting control, and click Relight. For a delighting-only interface, run python app.py --delight_only --matting none.
FlashRelight uses the DiT, 3D VAE, and umT5 text encoder from Wan2.1. We use BiRefNet for optional portrait matting. The examples include HDR maps from Poly Haven (CC0).
Example asset credits · Third-party software
@misc{sheng2026flashrelightportraitvideorelighting,
title={FlashRelight: Portrait Video Relighting with Dynamic Lighting},
author={Jiahui Sheng and Le Li and Limin Lin and Jiahao Li and Wansen Feng and Hong Gu and Shuhan Chen and Xiaorun Li and Rui Hu},
year={2026},
eprint={2611.06355},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2611.06355},
}





