VMem: Consistent Interactive Video Scene Generation with Surfel-Indexed View Memory
Paper: arXiv:2506.18903 Code: runjiali-rl/vmem Code reference:
main@39291e4f(2025-07-25)
1. Motivation(研究动机)
VMem 研究的是一种比普通 camera-conditioned video generation 更接近“可交互世界模拟”的问题:给定一张初始图像和用户接下来指定的一小段相机轨迹,模型需要沿着这条轨迹自回归地产生新视角;用户看完当前生成结果后又可以继续指定下一段轨迹。这个设定不是一次性生成固定长度视频,而是像在游戏或 VR 场景里探索一个被想象出来的空间:先从客厅走到厨房,再转向走廊,之后又回到厨房时,厨房的结构、物体位置、纹理和遮挡关系都应该与第一次看到时一致。论文的具体目标是让 video scene generator 在长时段、可回访、用户可控相机路径下保持 scene coherence,而不是只在短窗口内生成局部合理的帧。
现有路线主要有两类失败模式。第一类是 outpainting / explicit geometry 方案:模型先估计已有视图的 3D 几何,把已有图像渲染到新视角,再用图像补全模型填补未观察区域。它的优点是显式使用几何,缺点是几何估计、outpainting 和 stitching 的误差会随着探索步数累积;一旦早期深度或几何拓扑出错,后续视角会把这些错误不断放大,产生破碎墙面、漂浮结构或不连贯纹理。第二类是 multi-view / video-based 方案:使用视频或 image-set generator,以过去若干帧作为上下文生成下一批视角。它避免把粗糙几何当作最终场景表示,但上下文窗口通常固定且很短,因为把所有历史帧都喂给生成器代价太高;当用户回到很久以前看过的区域时,相关旧帧已经被滑动窗口丢掉,模型只能依赖最近几帧,容易“忘记”先前的场景外观。
这篇论文的动机不是追求一个更强的单步 novel view generator,而是解决自回归探索中“历史视图如何被长期记住并按需取回”的问题。作者的核心判断是:长时一致性失败并不一定来自底层生成器无法画出新视角,而是来自上下文选择机制太弱。对下一个目标视角最有用的历史帧,不一定是时间上最近的帧,而是那些曾经观察过当前可见表面区域的帧。比如用户绕过一个墙角后回头看门框,最相关的上下文可能是几十步之前从相似方向看到过门框的帧,而不是刚刚在走廊另一端看到的帧。由此,模型需要一个可以把“过去哪些视图看过哪些 3D 表面”存起来的 memory index。
VMem 的研究价值在于把 geometry 用作 retrieval index,而不是把 geometry 当作最终渲染结果。它仍然承认 point map / surfel reconstruction 可能很粗糙,但只要粗几何足够帮助检索相关旧视图,生成器就可以从真实 RGB 历史帧中取回外观细节,再由 image-set generator 合成目标视角。这个定位介于显式 3D reconstruction 和纯视频上下文之间:比 outpainting 少依赖精确几何,比短上下文视频模型更能跨长时间记忆。对于 World Model / 3D & Multi-View Simulation 方向,这种设计直接对应“scene permanence”:生成世界中的区域被离开后不应消失或重写,而应在相机回访时保持可识别的状态。
2. Idea(核心思想)
VMem 的核心思想是 Surfel-Indexed View Memory:把过去生成过的视图按它们观察到的 3D surface elements(surfels)建立索引;当要生成下一批目标视角时,从目标相机附近可见的 surfels 出发,让这些 surfels 中记录的历史 view indices 投票,选出 top- 最相关的旧视图作为 generator context。这样,生成器不再固定使用最近 帧,也不需要使用全部历史帧,而是使用与目标视角空间相关的历史证据。
这个想法有三个关键点。第一,memory 的基本单元不是完整 mesh 或 point cloud,而是 surfel。每个 surfel 存储 3D 位置、法线、半径,以及观察过它的历史帧索引集合。相比 mesh,surfel 对粗糙点图更鲁棒;相比无半径点云,surfel 可以更自然地处理遮挡和投影覆盖。第二,memory 的 read 操作是 geometry-aware voting:将 surfels 从目标相机的平均 pose 渲染到图像平面,被目标视角看到的 surfels 会把其历史 view indices 投射出来;出现频率越高的历史视图,说明它覆盖了目标视角中更多表面,因此更适合作为 reference。第三,memory 的 write 操作是自回归更新:生成新帧后,用 CUT3R 这类 point map estimator 估计新帧与检索旧帧的联合点图,把新帧转成新的 surfels,与已有 surfels 合并或追加,然后把新帧本身也加入 RGB/camera/latent memory。
这种设计的直接收益是把“长历史”变成“可查询历史”。如果天真把所有历史帧作为上下文,计算量会随探索长度增长;如果只用最近帧,回访场景会遗忘早期外观。VMem 用 surfel index 在二者之间折中:memory 可以长期增长,但每次生成只取 top- 相关帧。论文报告它在 的上下文设置下就能取得接近 原始 SEVA 的性能,并带来约 推理加速。这里的加速不是因为底层 diffusion generator 本身更快,而是因为 fine-tuned efficient SEVA 只需要 4 个 reference views 和 4 个 target views,而不是 SEVA 固定的 。
与传统 retrieval-augmented generation 的差异在于,VMem 的检索键不是文本 embedding 或全图视觉 embedding,而是被 surfels 组织起来的空间可见性关系。它检索的不是“语义最相似”的帧,而是“几何上最可能看过当前目标可见表面”的帧。因此,即使两个房间语义相似,只有真正观察过当前门框、墙角或家具表面的视图才会被优先取回。这个机制使 memory 更贴近交互式场景探索的需求:用户可以任意改变下一步相机路径,系统只需要用目标相机查询 surfel memory,而不必预先知道完整轨迹。
3. Method(方法)
3.1 Overall framework
Figure 1 解读:teaser 对比了带 VMem 与不带 memory 的自回归探索。绿色区域表示使用 surfel-indexed memory 后,在相机回到曾经看过的区域时,墙面、建筑结构和局部纹理仍能保持稳定;红色区域表示没有 memory 或只依赖最近上下文时,场景会在回访处发生明显重写。这个图强调论文关注的不是单帧视觉质量,而是长轨迹中“之前看过的地方再看时是否还是同一个地方”。
形式化地,输入是一张初始 RGB 图像 和用户指定的相机参数序列 。模型要生成图像序列 ,其中 是给定初始帧,后续帧需要与历史帧一致并遵循相机轨迹。为了保持交互性,模型不是一次生成全部 帧,而是在 generation step 处,每次生成 个新视图。若已生成 帧,已有 view memory 为 下一步目标是根据目标相机 生成 ,并在生成后更新 。挑战在于 随时间无限增长,而 image-set / video generator 通常只能接受固定长度上下文。VMem 的做法是从全部历史视图中动态检索一个相关子集 ,再把它交给 generator 。
Figure 2 解读:方法图展示完整闭环。给定下一批 target camera viewpoints,Reading Module 用目标相机查询 Surfel-based Memory Index,检索 个相关旧视图;这些旧视图的 RGB、reference camera Plücker embedding、target camera Plücker embedding 和噪声一起送入 generator ,合成 个新视图;Writing Module 再估计新视图几何,把新 view index 写回 surfel memory。图中最重要的箭头是“retrieve → generate → write back”,它使生成过程从短窗口视频采样变成带长期空间记忆的自回归模拟。
3.2 Surfel-indexed view memory:memory representation
VMem 使用 surfel 表示 scene memory 的几何索引。第 个 surfel 定义为: 其中 是 3D 位置, 是单位法线, 是 surfel 半径, 是观察过该 surfel 的历史视图索引集合。第 步的 memory index 是 同时代码里还维护 octree 以便基于空间位置快速寻找相邻 surfels。这个表示的关键不是要得到 photorealistic 3D reconstruction,而是给每个局部表面附加“谁看过我”的历史索引。只要这些索引大致正确,检索就能把相关 RGB reference views 找回来,后续生成由强 image-set generator 完成。
Figure 3 解读:surfel demo 把不同视图贡献的 surfels 用颜色编码。每个 surfel 不只是一个几何点,而携带观察它的 frame indices;当新视角看到某些 surfels 时,系统即可知道哪些历史帧曾覆盖同一区域。图的重点是“空间索引 + view index 属性”的组合:它让遮挡后的表面不会被无关历史帧污染,也让回访区域能找到更早的有效 reference。
3.3 Reading from memory:用目标相机查询历史视图
在 read 阶段,VMem 先把下一批目标相机 求一个平均 pose 。附录说明,平移用简单均值,旋转先转成四元数、对齐到同一 hemisphere,再做归一化平均: 最终平均位姿为 随后系统从 渲染 中的 surfels。每个 surfel 以 splat 方式投影到图像平面,并考虑 relative depth 与 occlusion;渲染得到的每个像素携带该像素对应 surfel 的历史 frame indices。VMem 统计所有可见像素中各历史 view index 的出现频率,取出现最频繁的 top- 索引集合 ,并据此从 中取出 reference views: 这个 read 过程的直觉是:如果某个历史帧观察过大量当前目标视角可见的 surfels,它就应该提供更多可复用的外观和结构信息。论文还加入 non-maximum suppression,以避免重复访问区域中的多个近似相机位姿垄断 top-;检索时保留相似 pose 中被引用最频繁的视图,写入时如果两个 pose 很接近则丢弃旧的重复关联,从而让 memory 覆盖更广的场景区域。
Figure 4 解读:spatial memory 图把 read/write 拆开。Reading 侧把 surfels 渲染到目标视角,并用 surfel 中的 frame indices 投票;Writing 侧把新生成视图估计成 point maps,再转成 surfels 并与已有 surfels 合并。这个图说明 VMem 的 memory 不是简单帧缓存,而是一个带几何投影、遮挡判断和索引投票的 active memory。
3.4 Writing to memory:把新帧转成 surfels 并合并
生成新视图后,VMem 把 加入 view memory,并更新 surfel index。论文使用 off-the-shelf point map estimator ,例如 CUT3R,对新生成视图和检索到的旧视图 做联合 point map estimation,得到 。联合估计的目的在于让新 point maps 与已有场景坐标系对齐,而不是每个新帧各自形成孤立坐标系。
对每个新帧 ,VMem 将 point map 下采样为 。对每个 downsampled pixel ,其 3D 点为 ,新 surfel 的法线由邻域差分叉积估计: surfel 半径根据深度、焦距和视线与法线夹角计算: 其中 是深度, 是相机中心, 是焦距, 用来避免接近 grazing angle 时半径过大。最后,VMem 检查已有 中是否存在与 相似的 surfel:中心距离小于阈值 且法线余弦相似度大于阈值 。若匹配成功,将当前帧索引 加入旧 surfel 的 ;否则创建新 surfel,令 。这一过程把 更新为 。
3.5 Novel view generator:SEVA backbone + Plücker camera conditioning
VMem 本身是 plug-and-play memory module,论文实现中使用 SEVA 作为 camera-conditioned image-set generator 。给定检索到的 reference views 和目标相机 ,生成分布写为:
代码实现中,modeling/pipeline.py 的 get_cond 会把 reference 与 target 相机转成 Plücker coordinates;reference images 先经 VAE 和 CLIP/image encoder 得到 latents 与 embeddings,target positions 用零 latent 但带 camera Plücker conditioning。条件字典包含 crossattn、replace、concat 和 dense_vector:replace 用 context latents 填 reference slots、用 padded zero latents 填 target slots,concat 拼接 input mask 和 Plücker map,dense_vector 直接传 Plücker geometry。之后 _generate_frames_for_trajectory 调用 do_sample 进行 diffusion sampling,并把新生成帧的 latents、encoder embeddings、camera intrinsics/extrinsics 和 PIL frames 追加到 pipeline state。
论文的训练/推理细节来自附录:为了降低 SEVA 的 固定输入成本,作者 fine-tune 一个更小的版本,使用 reference views 和 target views;LoRA rank 为 256;训练 600,000 iterations,使用 8 张 A40 GPU,每 GPU batch size 24;优化器为 AdamW,learning rate ,weight decay ,cosine annealing schedule;推理时 classifier-free guidance scale 设为 3,surfel radius 的 。
论文公式与 released code 实现差异:当前 GitHub configs/inference/inference.yaml 的 demo/inference 默认值与附录数值不完全相同。代码配置为 context_num_frames=4、target_num_frames=4、num_frames=8,与高效版本 一致;但配置中 cfg=2.0、cfg_min=1.2,而附录写 classifier-free guidance scale 为 3。附录写 point map scaling factor ,released code 的 surfel.shrink_factor=0.05 用于 F.interpolate 下采样 pointcloud/depth/confidence。半径公式则基本对齐:代码在 pointmap_to_surfels 中用 radius_scale=0.5 与 0.2+0.8*abs(dot),对应论文公式里的 和 。因此笔记中的训练超参以论文附录为准,代码 mapping 只锚定当前 released inference/demo implementation。
3.6 Pseudocode(按关键组件拆分)
def read_surfel_memory(surfels, surfel_to_timestep, target_c2ws, intrinsics, K, nms=True):
avg_c2w = average_camera_pose(target_c2ws)
rendered = render_surfels_to_image(
surfels=surfels,
camera_pose=avg_c2w,
intrinsics=intrinsics,
image_width=512,
image_height=288,
)
frame_votes = count_visible_surfel_timestamps(
rendered["surfel_index_map"],
rendered["depth"],
surfel_to_timestep,
)
candidates = sort_by_vote_count_then_pose_distance(frame_votes, avg_c2w)
selected = []
for frame_id in candidates:
if not nms or is_pose_diverse(frame_id, selected):
selected.append(frame_id)
if len(selected) == K:
break
return selecteddef write_surfel_memory(pipeline, all_frames, retrieved_indices, target_count):
scene = run_inference_from_pil(
all_frames,
pipeline.surfel_model,
poses=pipeline.get_transformed_c2ws(),
depths=pipeline.surfel_depths if pipeline.surfel_depths else None,
lr=pipeline.config.surfel.lr,
niter=pipeline.config.surfel.niter,
)
pointcloud, depths, confs = downsample_scene_outputs(
scene,
shrink_factor=pipeline.config.surfel.shrink_factor,
)
for frame_idx in last_target_frame_indices(pointcloud, target_count):
new_surfels = pipeline.pointmap_to_surfels(
pointmap=pointcloud[frame_idx],
focal_lengths=scene["camera_info"]["focal"][frame_idx],
depths=depths[frame_idx],
confs=confs[frame_idx],
poses=pipeline.get_transformed_c2ws()[frame_idx],
radius_scale=pipeline.config.surfel.radius_scale,
)
if pipeline.surfels:
new_surfels, pipeline.surfel_to_timestep = pipeline.merge_surfels(
new_surfels,
current_timestep=frame_idx,
existing_surfels=pipeline.surfels,
existing_surfel_to_timestep=pipeline.surfel_to_timestep,
normal_threshold=pipeline.config.surfel.merge_normal_threshold,
)
pipeline.append_new_surfels(new_surfels, frame_idx)def autoregressive_generate(pipeline, init_image, camera_path, intrinsics):
pipeline.initialize(init_image, c2w=camera_path[0], K=intrinsics[0])
for target_c2ws, target_Ks in chunk_path(camera_path[1:], intrinsics[1:], size=4):
context = pipeline.get_context_info(target_c2ws)
all_c2ws = cat(context["context_c2ws"], target_c2ws)
all_Ks = cat(context["context_Ks"], target_Ks)
scaling, normalized_c2ws = pipeline.get_translation_scaling_factor(all_c2ws)
cond = pipeline.get_cond(
context_latents=context["context_latents"],
all_c2ws=normalized_c2ws,
all_Ks=all_Ks,
translation_scaling_factor=scaling,
encoder_embeddings=context["context_encoder_embeddings"],
input_masks=make_reference_target_mask(context, target_c2ws),
)
samples, latents = do_sample(pipeline.model_wrapper, pipeline.vae, cond)
pipeline.store_generated_frames(samples, latents, target_c2ws, target_Ks)
pipeline.construct_and_store_scene(
pipeline.pil_frames,
time_indices=context["context_time_indices"],
niter=pipeline.config.surfel.niter,
lr=pipeline.config.surfel.lr,
)
return pipeline.pil_framesCode reference:
main@39291e4f(2025-07-25) — pseudocode and mapping based on this commit
| Paper concept | Released code location | Mapping / interpretation |
|---|---|---|
| VMem pipeline state | modeling/pipeline.py::VMemPipeline | Maintains RGB/PIL frames, VAE latents, image encoder embeddings, camera intrinsics/extrinsics, surfels, surfel depths, and surfel_to_timestep. |
| Surfel rendering for retrieval | modeling/pipeline.py::render_surfels_to_image | Projects surfels into target/average camera, uses z-buffer-like depth handling, returns surfel_index_map and depth/cosine maps. |
| Vote aggregation | modeling/pipeline.py::process_retrieved_spatial_information | Converts visible surfel indices into weighted frame counts via surfel_to_timestep. |
| Context selection | modeling/pipeline.py::get_context_info | Uses rendered surfel votes, geodesic/camera distance sorting and optional NMS to produce context frame indices and tensors. |
| Point-map-to-surfel conversion | modeling/pipeline.py::pointmap_to_surfels | Filters by confidence/depth, estimates normals from point map, computes radius from depth/focal/normal-view dot product, creates Surfel objects. |
| Surfel merge/update | modeling/pipeline.py::merge_surfels and construct_and_store_scene | Uses octree neighbor query plus normal threshold to append timestep to existing surfel or add new surfels. |
| Plücker camera conditioning | modeling/pipeline.py::get_cond, utils/util.py::get_plucker_coordinates | Builds camera geometry channels for reference and target frames; packs them into concat and dense_vector. |
| Interactive navigation UI | app.py, navigation.py::Navigator | Gradio app wraps pipeline, user actions change camera path and call generation; undo_latest_move removes latest generated segment. |
| Released inference config | configs/inference/inference.yaml | Demo defaults: 576×576 model resolution, context_num_frames=4, target_num_frames=4, inference_num_steps=50, cfg=2.0, surfel.shrink_factor=0.05, surfel.niter=400. |
3.7 关键直觉与失败模式
VMem 成功的前提是 retrieval geometry 足够好,而不是 geometry reconstruction 完美。如果 surfel index 粗略但能把“当前目标视角看到了哪些旧区域”判断对,generator 就能使用旧 RGB reference 修复外观一致性;如果 point map estimator 在透明物体、动态物体、大遮挡或室外大尺度场景上严重错误,memory 可能把错误的历史视图检索回来,导致不相关纹理被强行用于目标视角。论文的局限也承认,当前 cyclic benchmark 只是长时一致性的 proxy,无法完全评估复杂 occlusion 下的能力。
Figure 5 解读:OOD / long revisitation 图展示了在野外图像或非标准轨迹上,VMem 与只依赖最后 帧的 baseline 的差异。上排 VMem 在回访时更能保持建筑轮廓、门洞、墙面和物体布局;下排 baseline 因为没有长期 memory,常在长序列中把同一区域重新想象成不同结构。这个图说明 surfel memory 的实际价值主要出现在“离开后再回来”的场景,而不是只向前飞行的新视角外推。
4. Experimental Setup(实验设置)
作者评估的是从单张图像出发的 camera-conditioned autoregressive novel view generation。主要数据集包括 RealEstate10K 和 Tanks-and-Temples。RealEstate10K 主要包含 indoor real-estate video clips,适合评估室内场景长轨迹;Tanks-and-Temples 包含室内外场景和更大相机运动,用来检查泛化。定性评估还使用来自互联网或手机拍摄的 in-the-wild images 作为初始视图。
模型方面,生成器 使用预训练 SEVA。原始 SEVA 固定总帧数 ;论文在实验中设 target views,原始配置对应 context views。为了降低计算量,作者在 RealEstate10K training split 上 fine-tune 了一个更高效版本,使用 。附录中的训练设置为 LoRA rank 256、600k iterations、8×A40、每 GPU batch size 24、AdamW、学习率 、weight decay 、cosine annealing。推理方面,论文附录写 CFG scale 3、;released demo config 则如 §3.5 所述使用 cfg=2.0 和 surfel.shrink_factor=0.05。
评估协议分三组。第一组是已有 short-term / long-term NVS benchmark:从 test sequence 第一帧开始,模型沿 ground-truth camera trajectory 每隔 10 帧自回归生成;short-term 评估第 5 个生成图像,即距离初始帧 50 frames;long-term 评估最终图像,即距离初始帧至少 200 frames。第二组是作者提出的 cycle-trajectory protocol:相机先沿原路径从初始 pose 到终点,再沿同一路径反向回到起点,并在 return trajectory 上每 10 帧评估一次。这个 protocol 专门测试 revisitation,因为普通 RealEstate10K 轨迹很少回到曾经观察过的区域,难以体现 memory 的核心优势。第三组是 ablation:比较 temporal retrieval、camera-distance retrieval(SEVA 风格)、field-of-view overlap retrieval 和 VMem surfel retrieval,同时比较 与 的效率/性能权衡。
指标包括三类。图像分布质量用 FID;跨视图细节保持用 PSNR、LPIPS 和 SSIM;相机控制/几何 alignment 用 DUSt3R 从生成视图估计相机 pose,再与 ground truth 相机比较旋转距离和位移距离。旋转距离定义为: 平移距离为: 这个指标组合有一个重要 caveat:LPIPS/PSNR/SSIM/FID 更偏向低层纹理或分布相似性,未必直接度量多视角物理一致性;cycle trajectory 是作者为了更贴近 revisitation 而提出的 proxy,但仍然比真实交互式探索简单。
5. Experimental Results(实验结果)
5.1 RealEstate10K short-term / long-term benchmark
在 RealEstate10K 单视图 NVS benchmark 上,VMem 在多数关键指标上超过开源 baselines。短期第 50 帧设置中,VMem() 达到 LPIPS 0.287、PSNR 18.49、SSIM 0.406、FID 17.12、 0.219、 0.039,是表中短期最优;相比 SEVA() / VMem() 的 LPIPS 0.293、PSNR 18.33、SSIM 0.382、FID 17.29、 0.223、 0.118, fine-tuned 版本在短期上甚至更好。长期 帧设置中,VMem() 达到 LPIPS 0.452、PSNR 14.09、SSIM 0.227、FID 23.56,是 LPIPS/PSNR/SSIM/FID 最优;VMem() 的长期结果为 LPIPS 0.493、PSNR 13.12、SSIM 0.183、FID 27.15、 0.811、 0.499,仍然优于大多数 baselines,并显著降低上下文成本。
但作者明确指出,RealEstate10K 的标准轨迹很少 revisit previously observed areas,因此这个 benchmark 不能完全体现 VMem 的核心优势。换言之,Table 1 更能说明 VMem 不会损害常规 NVS 质量,并能在 下保持强性能;真正验证 memory 的实验是 cycle trajectory。
5.2 Cycle trajectory:回访场景的一致性
在 RealEstate10K cycle trajectories 上,VMem() 取得 LPIPS 0.304、PSNR 18.15、SSIM 0.377、FID 24.18、 0.892、 0.165;VMem() 取得 LPIPS 0.397、PSNR 15.72、SSIM 0.297、FID 24.97、 0.821、 0.392。对比 baselines:Look-out 为 LPIPS 0.809、PSNR 8.41、SSIM 0.069、FID 38.34;GenWarp 为 0.507 / 11.13 / 0.134 / 32.94;MotionCtrl 为 0.589 / 9.07 / 0.096 / 26.86;ViewCrafter 和 SEVA() 为 LPIPS 0.401、PSNR 11.82、SSIM 0.217、FID 24.72、 0.902、 0.492。VMem() 在 LPIPS、PSNR、SSIM、FID 和 上最优,VMem() 在 上最优。
这个结果说明 surfel memory 尤其改善“回到原处”时的图像一致性:PSNR/SSIM 大幅提升代表同一返回视角与 ground truth 的像素/结构对齐更好,LPIPS 降低代表感知差异更小, 降低说明估计相机轨迹更稳定。值得注意的是,ViewCrafter 与 SEVA 在某些表格行中数值相同,因为 SEVA 是被用于 backbone 或对比的 image-set generator,而 VMem 的增益主要来自 spatial retrieval,而非完全不同的渲染 backbone。
在 Tanks-and-Temples cycle trajectories 上,VMem() 取得 LPIPS 0.472、PSNR 14.11、SSIM 0.121、 1.204、 0.387。它在 LPIPS 和 PSNR 上优于所有 baselines;SSIM 低于 GenWarp/ViewCrafter 的 0.129; 不如 Look-out 的 0.727 和 GenWarp 的 0.785; 不如 MotionCtrl 的 0.129。这个表明 VMem 的泛化并非所有指标全胜,但在外域大运动场景中仍改善了感知一致性和重建质量;相机控制误差则可能受 DUSt3R 估计、轨迹尺度和 outdoor geometry 影响。
Figure 6 解读:长时 cycle qualitative comparison 展示 帧回访时的视觉差异。VMem 的结果在返回先前区域时能复现墙、门、窗和局部纹理;对比方法常出现结构漂移、墙面重排或物体消失。这个定性图弥补了指标的不足,因为 LPIPS/PSNR 只能在有 ground truth 的测试集上度量,而交互式 world generation 的关键体验是“用户眼中的同一空间是否持续存在”。
5.3 Retrieval ablation:为什么 surfel-indexed memory 有效
Ablation 在 RealEstate10K cycle trajectories 上比较四种 retrieval strategy。对于 ,Temporal retrieval 的 LPIPS/PSNR/SSIM// 为 0.477 / 13.92 / 0.188 / 0.976 / 0.254;Camera Distance 为 0.397 / 15.72 / 0.297 / 0.821 / 0.392;Field of View 为 0.374 / 15.75 / 0.292 / 0.911 / 0.382;VMem 为 0.304 / 18.15 / 0.377 / 0.892 / 0.165。除 被 Camera Distance 略优外,VMem 在感知、像素和 translation consistency 上最强。
对于更困难的 ,差距更明显。Temporal retrieval 只有 LPIPS 0.794、PSNR 7.52、SSIM 0.018、 1.942、 0.458,说明只取最近帧在短上下文下几乎无法处理 revisitation。Camera Distance 为 0.422 / 13.27 / 0.187 / 1.787 / 0.319;Field of View 为 0.424 / 13.11 / 0.192 / 1.782 / 0.285;VMem 达到 0.381 / 14.82 / 0.275 / 0.793 / 0.124,在所有五项指标上最优。这个 ablation 是论文最能支持核心方法的证据:只看相机距离或 FOV overlap 不足以判断“哪些历史帧真正观察过目标可见表面”,而 surfel index 利用了局部 3D surface visibility,因此在小上下文预算下尤其有效。
5.4 Efficiency and limitations
效率方面,作者报告 VMem() 相比原始 SEVA() 约快 :在 RTX 4090 上每帧生成约 4.2 秒,而 SEVA 约 50 秒。这个速度仍未达到 VR 或游戏所需的实时交互,但已经说明 surfel-indexed retrieval 可以在较小 context 下保留大部分长时一致性。附录进一步指出,当前 diffusion multi-step sampling 仍是主要瓶颈,未来 single-step image-set models 或更强基础模型可能进一步加速。
局限包括三点。第一,cycle trajectory 只是长时一致性的 proxy,轨迹相对简单且遮挡有限,不能完全代表真实探索中的复杂回环、动态物体、透明/反光表面和长距离大视角变化。第二,高效 generator 只在 RealEstate10K 上 fine-tune,训练数据主要是室内和少量室外 real-estate scenes;在自然风景、移动物体或更开放世界场景中,性能可能下降。第三,VMem 依赖底层 image-set generator 和 point map predictor;如果 SEVA 生成能力或 CUT3R point map 在某些场景中失败,surfel memory 也会继承这些错误。作者认为随着底层 generator 与 point map predictor 进步,VMem 这类 memory module 会自然受益。
总体结论是,VMem 的主要贡献不是提出新的 diffusion architecture,而是给交互式视频世界生成加入一个几何索引的长期记忆层。它把“所有历史帧太贵、最近帧会遗忘”的矛盾转化为“用粗 surfel geometry 查最相关历史帧”的检索问题,在 revisitation 场景中获得清晰收益。对后续工作而言,值得关注的方向是把 surfel memory 与更快的 generator、更强的 dynamic object handling、更严格的 3D consistency benchmark 结合起来,并研究 memory index 在长时间开放世界交互中的容量、错误恢复和可编辑性。