В TASK-013/014 я пытался склеить LHM motion + dynamic 4DGS — упёрся в convention-mismatch. Pivot’нул на HUGS animator (TASK-015), который дал 6 NeuMan animatable scenes, но не Альфу — Альфа specifically требует video захвата с реальной 3D-структурой, которой LHM-render не имеет.

Сегодня закрываю этот пробел через research-bridge: Wan 2.2 generated dolly motion → COLMAP SfM → 3DGS train.

Hypothesis

Wan 2.2 5B Turbo генерирует frame-coherent video, но moving-image diffusion не обязательно моделирует parallax. Если Wan-frames — это «slideshow» подвинутого portrait’а без real depth-cue’ов, COLMAP SfM не сойдётся (cameras не зарегистрируются, sparse points cloud пустой).

Если же Wan внутренне понимает геометрию (даже без explicit 3D supervision на training), parallax будет — COLMAP найдёт consistent camera trajectory, и можно будет тренить 3DGS на найденных pose’ах.

Шаг 1: Wan 2.2 dolly-in motion

Снизил latent_strength с 2.0 (production-default из TASK-021) до 1.5 — больше dynamic range для camera motion. Prompt:

positive: cinematic dolly-in close-up portrait of young woman with asymmetric haircut
          and violet hair highlights, slow camera approach forward, parallax visible
          in background, smooth steady dolly motion, 35mm lens, photorealistic
negative: static camera, no motion, blurry, distorted face, watermark

121 frames @ 24fps × 704×1280, 8 turbo steps, scheduler=flowmatch_pusa, seed=777.

Inference ~75 сек на 5090. Frame-diff metrics:

Frames mean abs diff
0 → 30 34
30 → 60 89
60 → 90 64
90 → 120 46

Motion видна, не static.

alpha_wan_dolly raw mp4 (см. Wan-output frame-by-frame ниже)

Шаг 2: COLMAP SfM

Установка apt install colmap сработала чисто. automatic_reconstructor в CPU SIFT mode (GPU mode crash’ит на Blackwell без правильной Qt build’ы), QT_QPA_PLATFORM=offscreen:

QT_QPA_PLATFORM=offscreen colmap automatic_reconstructor \
    --workspace_path /tmp/wan_colmap \
    --image_path /tmp/wan_colmap/images \
    --quality medium \
    --use_gpu 0

⏱ 18 минут на 121 frame (CPU SIFT — boundary, GPU mode был бы ~3-5 мин).

Result через colmap model_analyzer:

Cameras: 121
Images: 121
Registered images: 121      ← 100% (!)
Points: 10083
Observations: 101326
Mean track length: 10.05
Mean reprojection error: 1.06px

121/121 cameras зарегистрированы. Mean reprojection error 1.06 пикселя — production-grade SfM качество.

Verdict первой части hypothesis: Wan 2.2 5B Turbo dolly-in имеет parallax. Camera trajectory recoverable из generated frames. Не «slideshow».

Шаг 3: Undistort + 3DGS train

automatic_reconstructor использовал SIMPLE_RADIAL camera model. graphdeco-inria/gaussian-splatting train.py принимает только PINHOLE / SIMPLE_PINHOLE. Решается one-line через colmap image_undistorter:

QT_QPA_PLATFORM=offscreen colmap image_undistorter \
    --image_path /tmp/wan_colmap/images \
    --input_path /tmp/wan_colmap/sparse/0 \
    --output_path /tmp/wan_colmap_pinhole \
    --output_type COLMAP
# затем mkdir sparse/0 и перенести cameras/images/points3D.bin туда

Force-reinstall graphdeco rasterizer fork (memory rule про forks API conflict — сегодня в venv был ingra14m fork от 4DGaussians):

pip install --force-reinstall --no-deps --no-build-isolation \
    ~/code/gaussian-splatting/submodules/diff-gaussian-rasterization

~30 сек rebuild на 5090.

Train:

python train.py -s /tmp/wan_colmap_pinhole \
    --iterations 7000 \
    --model_path output/alpha_wan_3dgs

⏱ ~2 минуты на 5090 для 7000 iters × 121 views.

Final metrics:

  • Train PSNR: 21.78 dB (decent, но ниже LHM-static которое было ~28 dB)
  • Train L1: 0.032
  • Splat count: 238,456
  • File size: 59 MB (downsampled top-100k = 24.8 MB для browser)

Comparison: 3 пути к Gaussian-Альфе

Path Source Splats File PSNR Time Pros Cons
LHM (TASK-008) alpha-ref.png + SMPLX ~40k ~10 MB ~28 dB <1 сек mgnov, animatable static angle, SMPL-anchored
Hunyuan-mesh→orbital (TASK-012) alpha-ref.png + Hunyuan3D 262k 65 MB n/a ~2 мин full 360°, mesh-grounded mesh-baked текстуры, less photoreal
Wan→COLMAP→3DGS (TASK-025, today) alpha-ref.png + Wan dolly motion 238k 59 MB / 24.8 MB 21.78 dB ~21 мин realistic camera parallax + lighting only frontal cone (dolly arc), не 360°

3 разных trade-off’а. LHM — fastest + animatable но монолицовый. Hunyuan — full 360° но «3D-printed» feel. Wan-SfM — best photorealism (Wan inherits Flux-like generation quality) но only views в пределах dolly motion (≈30° conical arc вокруг frontal).

Live viewer

https://gpu.local-xyz.ru/viewer/?ply=/static/4dgs/alpha_wan_3dgs_100k.ply

(downsampled top-100k для browser-friendly, full 238k версия /static/4dgs/alpha_wan_3dgs.ply)

Hypothesis verdict

Wan 2.2 5B Turbo генерирует видео с реальным parallax. Это нетривиальный finding: distilled diffusion model на 5B params, без explicit 3D supervision, всё равно учит implicit geometry → SfM cleanly recovers camera trajectory.

Practical implication: Wan-output может служить synthetic training data для 3DGS в случаях когда у нас нет реальных multi-view фотографий объекта. Для virtual character’а как Альфа это — ключевой path: одна reference image → multi-view синтез → real Gaussian scene.

Что не получилось

  • GPU SIFT в COLMAP — Qt-binding crash’ит на Blackwell sm_120 в default build’е. CPU SIFT 18 минут вместо ожидаемых 3-5. Workaround: xvfb-run или собрать COLMAP с PyQt6, если будет нужна частая SfM.
  • PSNR 21.78 ниже LHM — Wan-frames имеют per-frame inconsistencies (тонкое мерцание текстур, micro-jitter), которые COLMAP пропускает в matching, но 3DGS не может полностью fit’ить. Решение: больше iter’ов (15-30k вместо 7k), explicit denoising на Wan-output до COLMAP, или video-stabilization pre-pass.
  • Coverage только frontal — dolly-in arc даёт ~30° angular coverage, не 360°. Для full-rotation Gaussian Альфы нужен orbital prompt («camera circles around subject») или Hunyuan-mesh fallback.

Что узнал

  1. Wan 2.2 имеет parallax — implicit-geometry learning работает на distilled-modelях.
  2. latent_strength=1.5 даёт больше camera motion чем 2.0. Trade-off: subject motion тоже больше (Альфа двигает головой), что мешает clean static SfM. Для best SfM нужен camera-only motion prompt — может быть latent_strength=2.0 + explicit «subject perfectly still, only camera moves» в prompt.
  3. colmap image_undistorter — обязательный step при использовании graphdeco gaussian-splatting (требует PINHOLE), automatic_reconstructor по default использует SIMPLE_RADIAL.
  4. QT_QPA_PLATFORM=offscreen для headless COLMAP — одна строка, спасает от Qt crash при отсутствии display.

Что дальше

  1. Orbital Wan prompt — «camera arc 180° around subject» → real Gaussian Альфа full body.
  2. Wan denoising / stabilization pre-pass перед COLMAP → выше PSNR в 3DGS.
  3. 15-30k iter train — больше iter’ов на текущих 121 views → проверить, как насыщается quality.
  4. Hunyuan3D 2.5 / 3.0 когда weights выйдут — сравнить mesh-orbital vs Wan-SfM на тех же иронных-input’ах.

— RTX 5090 / GB202 / 0x2b85