File size: 10,209 Bytes
9f57754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ab7f251
9f57754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ab7f251
 
9f57754
 
ab7f251
 
 
9f57754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# Method

[← Meridian](../README.md) Β· [Inference](inference.md) Β· [Studio](studio.md)

Meridian synthesizes a new observation of an existing event. It separates **which source moment is
shown** from **which camera observes it**, then uses geometry to make that choice visible to a video
model. The geometry supplies a spatial constraint; the model supplies the appearance of the completed
shot, including regions the source camera did not see.

This is geometry-guided video re-camera, not a persistent 4D reconstruction or an action-conditioned
simulator. A new view is a generated interpretation of the recorded event, not evidence of what an
unobserved camera would actually have captured.

[![Meridian method overview with actual source, geometric-reference and generated flower frames](assets/research/meridian_method.png)](assets/research/meridian_method.svg)

**Overview.** Source time selects both appearance and geometry; the authored camera makes a
projected reference. Both references condition the video model. Real example: *Spring* (2019),
Β© Blender Foundation, CC BY 4.0; input retimed, view projected and generated.
[Full figure, attribution and provenance](assets/research/README.md).

## 1. Choose a source timeline

For each output frame `t`, a source-frame map `s(t)` selects the image and geometry to use:

| Timeline | Source-frame selection |
|---|---|
| Preserve the input's pace | Advance one source frame per output frame. |
| Hold a moment | Repeat one source frame while the target camera can keep moving. |
| Slow motion or accelerated action | Retime the input to a constant 24 fps **before** reconstruction, then advance through that export normally. |

Both video references follow the same selected timeline. Meridian is not asked to invent a different
action speed from an unchanged reference. See [Timing](inference.md#timing) for frame-index semantics,
freeze windows, and FFmpeg recipes.

The CLI constructs `s(t)` from `--start`, `--frames`, and optionally `--freeze`. The studio constructs it
from keyframes: source indices interpolate linearly and are rounded to integers. Studio source keys
must be non-decreasing; easing affects the camera path, not the source-frame mapping.

## 2. Reconstruct the source span

The input is resized and letterboxed into a 1280 Γ— 1280 square, then downsampled to 512 Γ— 512 for
VGGT-Omega. **One model call processes the selected source span jointly**, returning per-frame depth,
confidence, camera extrinsics, and intrinsics. Per-frame outputs do not mean independent single-frame
inference. Changing the reconstruction span can change estimates for frames shared by both spans.

Before unprojection, the implementation removes:

- Non-finite depth or confidence, and confidence values at or below `1e-5`.
- Depth discontinuities whose 3 Γ— 3 local range exceeds 30% of the depth magnitude.
- The lowest-confidence 2% of the remaining candidates in each frame.

Depth and validity are upsampled to the letterboxed input resolution. A pixel is retained only when
the interpolated validity exceeds `0.999`, limiting points introduced across rejected boundaries.
Source RGB supplies the point colors. There is no fused mesh, persistent scene optimization, or
cross-frame point-cloud accumulation in this stage.

### Coordinates and scale

Geometry has a reconstruction-relative scale, not calibrated meters. Camera translations use `zm`,
a median scene depth. Choosing a distant background as the depth reference makes the same numerical
move much larger than choosing the subject.

- **CLI:** a camera offset is applied in each selected source camera's local coordinates:
  `C_target(t) = C_source(s(t)) @ delta(t)`. By default, `zm` comes from valid depths in the first
  selected frame; for `--freeze`, it comes from the held frame. `--pivot fx,fy` restricts the depth
  measurement to a neighborhood of a pixel in the **cropped image**. `--pivot-lock` also places the
  orbit center at the corresponding 3D point.
- **Studio:** all keys share the coordinate frame of the source camera at `start`: **x right,
  y down, z forward**. Positions and look-at points are expressed in units of `zm`. The API measures
  `zm` around a chosen pixel at `pivot_frame`, falling back to valid picture depths when too few
  local points remain. The current page uses the picture center at `start` as this scale reference;
  a key's **aims at** control changes its look-at point, not the scale reference.

The CLI's source-relative trajectory and the studio's shared-frame trajectory are different ways of
authoring a camera. Similar-looking controls need not produce identical paths on a moving-camera clip.

## 3. Render a geometric reference

At each output time, the selected source frame's colored point cloud is projected through the target
camera and its lens. A z-buffer resolves visibility; each point splats onto a 3 Γ— 3 pixel neighborhood.
Uncovered pixels are filled with RGB `(128, 128, 128)`.

The current implementation rasterizes at the **output canvas**, then downsamples the result to the
**480-class conditioning canvas**. There is no geometric inpainting before generation. Coverage is
computed for diagnostics, but **no coverage mask is fed to the transformer**.

The studio's *what the model sees* preview and the saved `render.mp4` show this downsampled reference.
They are encoded video previews, not lossless copies of the in-memory conditioning pixels. The
magenta-hole view is a diagnostic visualization only; the model receives the grey-hole version.

## 4. Condition the video transformer

MiniMax-H3's VAE encodes two references:

1. **`<Video 1>` β€” source:** the selected source images, at the 480 class.
2. **`<Video 2>` β€” geometry:** the rendered target view, at the same conditioning class.

The target is generated at the 768 class. Here β€œclass” means an aspect-ratio bucket, not a fixed
width or height. For a 16:9 input, the reference canvas is 832 Γ— 480 and the output is 1344 Γ— 768;
square inputs use 640 Γ— 640 and 1024 Γ— 1024 respectively. The nearest bucket is chosen by log aspect
ratio, with a centered crop inside the letterbox.

```text
source span ──► joint VGGT-Omega reconstruction ──► per-frame geometry
      β”‚                                                   β”‚
      β”‚                     source-frame map + camera pathβ”‚
      β”‚                                                   β–Ό
      β”‚                                       z-buffered point splat
      β”‚                                                   β”‚
      β–Ό                                                   β–Ό
source reference, 480 class                    view reference, 480 class
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β–Ό
              VAE β†’ packed reference tokens + fixed text
                               β–Ό
        stock H3 + re-camera and turbo adapters β†’ VAE decode
                               β–Ό
                     new shot, 768 class, 24 fps
```

**The references are concatenated as tokens, not added as channels.** `recam/h3.py` uses Diffusers'
`MiniMaxH3Ref2VAPrepareLayoutStep.build_ref2va_packed_sequence` to create the reference layout,
position IDs, and modality tags. The transformer architecture is unchanged.

Reference video rows receive the upstream conditioning-noise convention
`0.999 Γ— latent + 0.001 Γ— noise` and stay fixed during denoising. Target video rows begin as random
noise. The source is also VAE-encoded at target resolution to establish the target latent shape;
its values are **not** used to initialize the target rows.

### Fixed text and the audio branch

[`assets/prompt.txt`](../assets/prompt.txt) describes the two-reference editing task: retain the source
event and complete the geometry reference's grey holes. Its embeddings are precomputed for each
supported output length, so inference does not load Qwen3-VL. Editing the text file alone does not
change inference; the shipped embeddings are what the model reads. An embedding-generation script
is not included in this release.

The packed layout retains H3's audio branch. Cached silence latents supply its shape and length;
the current code initializes audio rows with noise, denoises them, and discards the result. Meridian
does not generate or preserve a soundtrack through that branch. The CLI's optional audio file is
instead made by muxing the source soundtrack after video generation.

## 5. Sample the new shot

| Mode | CLI settings | Transformer evaluations |
|---|---|---|
| Fast adapter, default | `--steps 4 --flow-shift 3` with both adapters loaded | 3 |
| Teacher | `--lora teacher_lora --steps 50 --flow-shift 12` | 49 |

The H3 scheduler counts the terminal zero-noise point in `--steps`; that endpoint does not require
another model evaluation. The turbo adapter must be loaded alongside the re-camera teacher, which is
what it was distilled against; neither works on the unmodified transformer alone, and neither should
be merged into it. Forward counts do not equal end-to-end speedups: geometry,
VAE work, and file writing still take time.

## Training overview

Training provenance, augmentations, and distillation design have moved to [Training and distillation](training.md).

## Implementation map

| Source | What to read |
|---|---|
| [`recam/geometry.py`](../recam/geometry.py) | `reconstruct`, `warp`, and `render_hw`: geometry filtering, projection, and visibility. |
| [`recam/path.py`](../recam/path.py) | `plan_path` and `hermite`: keyframe interpolation, time mapping, and zero-roll look-at cameras. |
| [`recam/h3.py`](../recam/h3.py) | `bucket`, `pack`, and `denoise`: canvases, reference conditioning, and the scheduler. |
| [`inference/sample.py`](../inference/sample.py) | CLI time windows, parametric camera moves, diagnostics, and output files. |
| [`service/app.py`](../service/app.py) | `prepare`, `geo`, and `do_render`: cached reconstruction and resident inference. |

For weight provenance and modification notices, see [`MODIFICATIONS.md`](../MODIFICATIONS.md).