Anonymous CVPR 2027 submission

Reconstruct What You See, Generate What You Don't

Streaming 3D object reconstruction with an exact evidence state

Teaser

Input: posed RGB-D frame 0 / 79
Current input frame of the stream
Output after frame 0: mesh, drag to rotate

The idea. A camera circles an object, and after every frame we want a complete 3D model. FuseGen fuses every frame into an explicit 3D state that integrates every measurement: the surface the cameras have measured. It asks a generative model only about the space no camera has constrained yet: the part that is generated. As the cameras cover the object, generated surface gives way to measured surface, and generated content never replaces a measurement.

Abstract

A camera moving around an object should yield a complete 3D asset after every frame that only gets better as frames arrive. Recent methods condition a frozen image-to-3D generator on the stream and regenerate the asset, or refine its latent; either way every observation passes through the generator's coarse latent, which caps the fidelity of what has already been seen. We take the opposite route. FuseGen keeps an explicit persistent state that integrates every RGB-D frame exactly, a truncated signed distance field with free, surface and unknown labels plus Gaussians fitted online, and asks a generative model only about the space no camera has constrained yet. That completion comes from a test-time-trained view-synthesis model whose ring of novel-view silhouettes carves the unknown region; it is re-queried every few frames and confined to unknown voxels, so generated content never overrides an observation. On Stream3D's 30-object GSO benchmark, with the same cameras and depth for every method and the benchmark evaluator's mirrored ground-truth basis corrected, FuseGen ends the stream at 21.4 dB PSNR against 16.9–17.0 dB for Stream3D and multi-view regeneration, halves their Chamfer distance, leads in geometry and PSNR from the first scored frame, and costs 0.32 s per frame, a 47th of Stream3D's; with the benchmark's estimated depth, whose scale it recovers from the cameras, it still leads from mid-stream by 1.4–2.2 dB. On real captures of 14 objects (Stanford-ORB), with calibrated cameras and depth from the aligned scans, it again ends about 4.6 dB ahead. Ground-truth cameras and masks; one seed.

Why not keep the generator in the loop?

Image-to-3D generators turn one view into a complete asset in seconds. Streaming methods keep the generator in the loop: they regenerate the asset from a memory of frames, or refine its latent in place. Then every observation, even one that already pins the surface down exactly, is routed through the generator's coarse latent. Early in the stream that is the right call, because most of the object is unseen. Late in the stream it is a burden, because the generator re-draws what the cameras have already measured.

surface seen by the last scored frame
98 %
27 % at frame 7, 65 % at frame 31 (within 2 mm of a measured pixel)
lower registration-free Chamfer error at frame 79 from fusing the exact depth, with no prior
15×
than refining the generator's latent with the same inputs
CUT3R's points in unseen space within 2 cm of the surface, after frame 7
4.6 %
vs 40 % for a generative prior: recurrent reconstruction does not hallucinate well

Probes on the 10 development objects (depth rasterised from the ground-truth mesh).

So we separate the two jobs. Reconstruct what has been seen: fuse it exactly. Generate what has not: only there, and only until a camera gets to see it.

Method at a glance

FuseGen carries three things from frame to frame. An evidence grid and a set of observed Gaussians hold everything observed so far. A completion covers the space no camera has observed. Every new frame is fused into the first two. Every few frames, the completion is recomputed from a sample of the frames so far. Whenever an output is requested, the three are composed into a mesh and a set of Gaussians. Click a block to jump to its step.

Overview of FuseGen Each frame is fused into an evidence grid and observed Gaussians. Every few frames LaCT renders a ring of novel views whose silhouettes carve the unknown voxels into a completion. The output composes observed geometry from the grid with generated geometry in unknown space only. Reconstruct what you see · every frame Generate what you don't · every few frames frame t RGB, mask, depthand camera pose evidence grid TSDF + labels: free, surface, behind, unknown observed Gaussians fitted online to the frames LaCT a ring of novel views from ≤ 32 of frames 0..t carve silhouettes remove unmeasured voxels only compose by label measured: from the TSDF unknown: from the completion mesh + Gaussiansafter every frame ≥ 4 frames apart unknown space only labels

Scroll sideways for the whole diagram →

Try it: FuseGen in 2D

The whole method fits in a flat world. Below, a camera (black dot) circles a 2D object, starting from above, and each frame gives a 1D depth image. The page runs the method's rules on a 96 × 96 grid while you watch: the TSDF update, the four labels, carving by a ring of virtual views, and composition by label. Scrub the frame, switch the stage, and hover a cell to read its state.

depth image of the current frame (dark = near, white = background)
The output contour takes measured surface from the TSDF and generated surface (dashed) only in unknown cells. Play the stream: the generated part shrinks as the cameras come round, and the error falls.
frame
7
unknown share of the hull
–
completion computed at
–
generated share of the output
–
output error (Chamfer ×100)
–

The toy's view-synthesis model is a stand-in: the true shape, inflated and warped by an error that shrinks as more of the surface has been observed. The real LaCT renders are shown in step 3 below. Try the cup: silhouettes cannot carve a concavity, so until a camera looks into the cup (from about frame 25) the completion closes it with a lid; the camera then measures the inside as free and the output opens. With completion: none, all unknown space is filled and the early output is a long shadow.

The setting

A camera moves around a single object. At time t it delivers an RGB image It, an object mask Mt, a depth map Dt and the camera parameters. After each frame the method must output a complete model of the object (3D Gaussians for rendering, a mesh for geometry) using only frames 0…t. The task has two regimes. Early, most of the object is unseen, and a good output needs a prior that can guess the rest. Late, most of the surface has been measured, and a good output must keep those measurements exactly.

1Reconstructing what has been seen: the evidence grid

The observed geometry lives in a truncated signed distance field (TSDF), a 256³ voxel grid around the object. Each voxel x stores its signed distance d(x) to the observed surface. When a frame arrives, every voxel is projected into the image. If it lands at a pixel with measured depth Dt(u) and lies at depth z, the measured distance is s = Dt(u) − z. Voxels inside a narrow band |s| ≤ τ update a running average:

d(x) ← W(x) d(x) + s/τW(x) + 1, W(x) ← W(x) + 1

Up to a cap of 64 observations per voxel, this average is the least-squares estimate of the truncated distance from all frames that saw the voxel (a voxel in front of the band that the band once reached is updated with the truncation value, +1). With measured depth, the grid therefore summarises the entire depth history in constant memory: the TSDF is never re-optimised, re-encoded or replayed (the observed Gaussians below, by contrast, revisit earlier frames). Pixels that see their surface at a grazing angle, more than 81° from the normal of the depth map, are not fused (their mask still counts): along such a ray s is many times the distance to the surface, and their sparse measurements would streak the side walls.

What is known, and what is not. Every voxel also collects evidence of being empty: a ray that passes through it before the measured surface, or a projection outside the object mask. From this evidence each voxel gets one of four labels: surface (on a measured surface), free (some camera has seen through it), behind (just behind a measured surface, inside the object), and unknown (no camera has constrained it). The unknown voxels are exactly the space the observations say nothing about, and they are the only space a completion may fill.

Evidence labels on a slice through the object
after frame
surfacebehind unknownfree

Evidence labels on a slice through the centre of a benchmark stream (GSO renders; a held-out object, the paper's configuration). The stream starts above the object, so after the first frames the unknown region is the long shadow under the top surface. By frame 79 only the interior is still unknown, because no camera can see inside a solid object.

2Appearance: observed Gaussians, fitted online

The appearance of the observed surface is held by 3D Gaussians: small, coloured, semi-transparent ellipsoids that render quickly from any camera. We grow and fit them online, as Gaussian SLAM systems do, except that our cameras are given. For each new frame, Gaussians are added at the pixels the current set does not explain (missing coverage, wrong depth or wrong colour) and are placed in 3D with the measured depth. A few optimisation steps then fit all Gaussians to the new frame and to randomly chosen earlier frames:

ℒ = ‖Î − I‖1 + ‖Â − M‖1 + λD ‖D̂ − D‖1 + λh ℒhalo

Î, Â and D̂ are the rendered colour, opacity and depth. The halo term penalises rendered opacity outside the object, which keeps the Gaussians from spilling beyond its silhouette. Gaussians that end up in free space or outside a seen silhouette are removed. No network is trained or fine-tuned: LaCT below is used as released (its test-time update of the fast weights is part of the released model). With measured depth and the LaCT completion, this per-stream fit of the observed Gaussians, with a least-squares refit of their colours at output, is the only optimisation FuseGen adds.

3Generating what has not been seen

The unknown voxels need a prior. We take it from LaCT, a novel-view synthesis model: given posed images of an object, it renders the object from any new camera. LaCT builds no explicit 3D model. It writes the input images into its fast weights, a large part of the network, with a single test-time gradient update, and renders a new view by querying them with the new camera. Because it is trained on a large collection of 3D objects, it renders plausible images even of sides no input image shows. We use the released model as is.

From novel views to shape. A rendered view tells us where the object is not. If a pixel shows background, the ray through it crosses only empty space. At each completion step, LaCT encodes up to 32 frames sampled uniformly from those seen so far and renders a ring of 24 views around the object. Space not measured as surface (unknown or behind) that projects onto background in any of these views, or in any input frame, is removed, except right next to a measured surface. This is classical space carving, except that most of the images are synthesised rather than captured. We compute it as a continuous field rather than voxel by voxel: every point gets, in each view, the distance from its projection to the silhouette edge, taken in 3D, and the views are combined with a soft minimum. The field's zero level is the completed surface, smooth rather than a staircase of voxels. Its colours come from the rendered views.

LaCT's ring of 24 novel views

LaCT's ring of 24 novel views at each completion of a benchmark stream. Early (frame 4, five input frames, all from above) the unseen underside is a blurry guess, but the silhouettes are already good enough to carve most of the unknown shadow away. By about frame 30 the views are sharp.

Why this completion fits the state.

Refreshing the completion. As frames arrive, LaCT sees more of the object and the unknown region shrinks. We recompute the completion when enough new information has arrived, at least four frames apart: every four to six frames early in the stream and less often later, 14 times per 80-frame stream on average. Each time LaCT re-encodes up to 32 frames sampled from all frames so far, and the new completion replaces the old one. Between two refreshes, newly observed space simply takes precedence.

Unknown voxels over the stream, school bus
millions of voxels in the 256³ grid; a completion refresh

4Composing the output

When an output is requested, observed and generated geometry are merged voxel by voxel, according to the labels:

D(x) =
+1freefree space stays empty
w d(x) + (1 − w) dgen(x)surfacemeasured surface from the TSDF (w = ½ after one measurement, 1 after two)
min(dgen(x), −ε)behindjust behind a measured surface is inside
dgen(x) + r(x)unknownthe generated shape, shifted to join the measured surface without a step

The unknown voxels then take a one-voxel Gaussian blur of D, so the completion meets the measurements without voxel steps, and unknown space enclosed by the object is set inside: no camera sees into a solid object, and a completion thinner than the measured shell would otherwise leave a hidden inner wall. The output mesh is the zero level set of D, extracted with marching cubes. The output Gaussians are the observed Gaussians plus generated ones laid densely on the unknown part of that surface, flat along it and coloured from LaCT's views, so mesh and Gaussians describe the same shape. By construction, no output surface lies in space a camera has seen to be empty: none of the 120 outputs of our benchmark run has any surface more than one voxel inside observed free space.

drag any view: all three turn together

Observed only: every unknown voxel filled (orange)

Completion: LaCT's carved hull

Composite: measured + generated

The three parts of an output on a benchmark stream. Without a completion (Observed only), filling every unknown voxel leaves the long shadow of the seen surface. LaCT's carved hull (Completion) has the right overall shape but no detail. The Composite keeps every measured surface and uses the hull only where nothing has been measured.

Predicted depth

When a network predicts the depth from the images instead of it being given exactly (as in the main comparison), it is right only up to a scale factor, which is unknown and changes from frame to frame. The cameras resolve this. Only at the correct scale does a frame's depth agree with the depth and silhouettes of the other frames, and the known distances between camera positions fix the absolute scale. After every frame FuseGen estimates one scale per frame with a scale-only bundle adjustment, rebuilds the evidence grid when the scales change, and lets frames or pixels that still disagree contribute only their silhouettes and colours. With the benchmark's own predicted depth (19 objects), FuseGen leads Stream3D from mid-stream on: at frame 79, median Chamfer 0.032 vs 0.044 and 19.0 vs 17.5 dB PSNR. At frame 7 its geometry and PSNR are ahead but its LPIPS and SSIM behind, and one of the 19 objects fails.

Results

This is Stream3D's 30-object GSO benchmark: 80 frames per stream, scored after frames 7, 31, 55 and 79 on held-out views. Every method gets the same ground-truth cameras, masks and depth (latent refinement is also registered once to the ground-truth mesh, which favours it). The evaluator's mirrored ground-truth basis is corrected, and the paper reports the released evaluator too. Baselines run on the same frozen generator, SAM 3D.

PSNR at frame 79
21.4 dB
Stream3D 16.9, eight-view regeneration 17.0
median Chamfer at frame 79
0.0235
regenerating baselines 0.039–0.054, latent refinement 0.033
objects with a lower Chamfer at frame 79
30 / 30
against each baseline, paired
time per new frame
0.32 s
a 47th of Stream3D's 15.1 s
Over the stream
30 objects, corrected evaluator. Median Chamfer distance, mean PSNR and mean LPIPS at the four scored frames. FuseGen leads in geometry from the first scored frame. In appearance it is about 0.7 dB ahead in PSNR at frame 7 (better on 20–22 of the 30 objects against each baseline), with a lower LPIPS but a slightly lower SSIM, and pulls further ahead from frame 31, as measured surface replaces generated surface. Click a legend entry to hide a method.
Final frame (frame 79)
MethodCD mean ↓CD median ↓IoU ↑PSNR ↑SSIM ↑LPIPS ↓s / frame ↓
SAM 3D, single view0.06520.05370.79716.470.8660.1474.99
MVSAM3D, 8 random views0.05500.03880.82817.020.8670.13514.39
Stream3D (released code)0.05660.04240.80116.890.8710.13415.12
Latent refinement0.05160.03270.84416.950.8660.1380.45
FuseGen, LaCT completion0.02420.02350.93421.430.9290.0790.32
FuseGen, SAM 3D completion0.02700.02560.93321.290.9270.0810.79
30 objects, corrected evaluator, one seed. CD: unsquared L2 Chamfer distance. The regenerating methods update once per 6 new frames; FuseGen and latent refinement after every frame. With the baselines' own generator as the completion (last row), FuseGen still beats every baseline at every scored frame, on every quality metric except SSIM at frame 7, where it is level.
Time per new frame
seconds per new frame on one RTX 5000 Ada. FuseGen: mean step time over frames 0–79, including every completion call. Latent refinement: mean over frames 1–79 (its frame-0 generation, about 4 s, excluded). Regenerating methods: steady-state time per chunk divided by its 6 new frames.
Four held-out objects
Each method at frames 7, 31 and 79, rendered at one held-out view after the evaluator's registration (corrected evaluator), on white. At frame 7 only the top of each object has been seen: FuseGen's unseen side comes from LaCT's carved hull and is blurry. From frame 31 on, measured surface dominates and FuseGen matches the ground truth, where latent refinement and Stream3D re-draw it.

Real captures

Synthetic renders leave out what real photos bring: real lighting, specular highlights, imperfect masks and calibration. We therefore also run every method on Stanford-ORB, real DSLR captures of 14 objects in 3 environments each (42 scenes), with calibrated cameras, object masks and a 3D scan aligned to the cameras. A stream is the first 56 photos of a scene in capture order, a handheld path at 0–40° elevation, so the top and the underside of the object are never seen; the scene's 9–10 test photos are held out. As on the synthetic benchmark, every method receives the masks, the cameras and depth, here rendered from the aligned scan, which stands in for an ideal depth sensor; every setting is unchanged. Because of their cost, the regenerating methods run on one scene per object.

FuseGen leads on every metric from the first scored frame (PSNR 21.6 against 18.6–19.4 dB at frame 7), and the lead grows: at frame 55, PSNR 24.1 against 18.4–19.4 dB and a median Chamfer distance of 0.018 against 0.031–0.038, with a higher PSNR than each regenerating method on 11–12 of the 14 scenes. The regenerating methods stay near 19 dB from the first chunk on: they draw plausible objects, but with the colours, labels and proportions of their prior rather than those of the photographed object.

Stanford-ORB, 14 scenes (one per object)
MethodCD 7 ↓PSNR 7 ↑LPIPS 7 ↓CD 31 ↓PSNR 31 ↑LPIPS 31 ↓CD 55 ↓PSNR 55 ↑LPIPS 55 ↓
SAM 3D, single view0.03618.550.1040.03018.890.0930.03818.410.101
MVSAM3D, 8 random views0.03419.420.0900.02919.740.0850.03119.420.088
Stream3D (released code)0.03118.940.0900.03119.100.0920.03219.340.089
FuseGen, LaCT completion0.02721.560.0720.01924.110.0520.01824.060.053
Real photos, calibrated cameras and masks, depth rendered from the aligned scan for every method; scored on the held-out real photos with the corrected evaluator. Median Chamfer distance, mean PSNR and mean LPIPS at frames 7, 31 and 55. On all 42 scenes FuseGen scores 22.0, 24.0 and 23.9 dB.
Held-out real photos of seven Stanford-ORB objects and the renders of FuseGen, Stream3D and MVSAM3D at the same cameras
Frame 55. Top: a held-out real photo; below: the renders of FuseGen, Stream3D and MVSAM3D at that camera after the evaluator's registration, all with the same inputs. Seven of the 14 scenes, each at the held-out view with FuseGen's median PSNR. FuseGen reproduces the photographed object, its labels and colours included; the regenerating methods draw a plausible but different one.

What each part does

Ablations on the 10 development objects: registration-free Chamfer-L1 (×100) and PSNR at frames 7, 31 and 79.

VariantCD 7CD 31CD 79PSNR 7PSNR 31PSNR 79s / frame
FuseGen (full)2.840.720.0916.1019.8121.160.32
no completion (fill all unknown)13.244.110.0911.1015.2221.010.10‡
SAM 3D completion instead of LaCT4.031.320.3515.7819.5821.360.78
fusion only (point splats + TSDF)5.571.650.0914.8018.6119.250.01
fusion + post-hoc Stream3D fill5.201.220.4515.6518.3118.40> 15

‡ Timed on a GPU shared with other jobs.

Without a completion, the Chamfer error at frames 7 and 31 is 4.7 and 5.7× higher: the prior is what makes the early stream work. A 3D generator as the completion gives less accurate geometry on these objects (42 %, 83 % and 3.9× higher registration-free Chamfer error at frames 7, 31 and 79; it must be registered to the stream) and sharper colours only at the end (−0.3, −0.2 and +0.2 dB PSNR at frames 7, 31 and 79), at 2.4× the cost; on all 30 objects, scored after the evaluator's fitted similarity, the two completions are close at frame 79 (21.4 against 21.3 dB). Plain fusion is exact late, but cannot complete the object early.

Limitations

Citation

@inproceedings{fusegen2027,
  title     = {Reconstruct What You See, Generate What You Don't:
               Streaming 3D Object Reconstruction with an Exact Evidence State},
  author    = {Anonymous},
  booktitle = {CVPR (under review)},
  year      = {2027}
}