Paper · 2025-08-21 · cs.CV
DriveSplat: Unified Neural Gaussian Reconstruction for Dynamic Driving Scenes
DriveSplat models a driving scene as neural Gaussians: a hashed multi-scale background with near, mid and far detail levels, and tracked actors with a rigid pose plus anchor-level MLP deformation. Depth and normal priors supervise training. Author-reported: best novel-view PSNR on Waymo (33.83) and KITTI (24.53).
Gaussian splattingNovel view synthesisMonocular depth estimationSurface normal estimationdriving-scenesgaussian-splattingnovel-view-synthesisdynamic-scenesdepth-priorslevel-of-detail
arXivPDFCodeMarkdown16 min read
AI-compiled by claude-haiku-5-5 on 2026-10-24, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
DriveSplat rebuilds a recorded driving scene so it can be viewed from places the car never drove. It does this with a large cloud of small soft 3D blobs (Gaussians), fitted to the recorded camera images. The method treats the road, buildings and other fixed things as one background. Blobs far from the camera are kept coarser and blobs near the camera are kept finer, so nearby detail stays sharp without wasting effort on distant areas.
Moving actors are handled separately. Each one is tracked as an object with a rigid motion, and extra learned deformation is added for non-rigid actors such as pedestrians. Pretrained models supply dense depth and surface-direction maps of each frame, and the fit is nudged to agree with them. The result is judged on the Waymo and KITTI driving datasets, where it renders new viewpoints better than the methods it is compared with.
TL;DR
- DriveSplat reconstructs large dynamic driving scenes with neural Gaussians, one unified representation for background and actors §1.
- Background uses a hashed multi-scale table with a near, mid and far split and view-dependent level selection §3.2.
- Actors use a tracked rigid pose plus an anchor-level MLP deformation, which is cheaper than per-Gaussian 4D deformation §3.3.
- Depth and normal priors from pretrained models supervise training §3.4.
- Author-reported best novel-view synthesis on Waymo and KITTI. The paper's own text overstates two reconstruction claims (see Pitfalls).
Problem
Large driving scenes mix very near and very distant structure, and dynamic actors move non-rigidly. Single-scale Gaussian densification adds redundant primitives in distant regions and hurts novel-view quality §1. LiDAR depth is sparse and uneven, so it constrains distant facades weakly §1. Per-object or object-centric methods do not cover the scale and geometry of driving scenes §1§2. The paper's aim is one representation that handles both static background and dynamic actors §1§3.
Method
Inputs. RGB images, an initial 3D point cloud and bounding boxes of dynamic actors, all from the dataset §3. Depth and normal priors come from pretrained models and are used only in the supervised stage §3.
Step 1. Point-cloud initialization §3.1
- Support SfM, LiDAR and dense DUSt3R points §3.1.
- For each tracked actor, estimate pose from its box, build a transform matrix, move each frame's points into actor-local coordinates and keep the points inside an axis-aligned box §3.1eq. 1.
- The remaining points are static background §3.1eq. 2.
- Without LiDAR, actor points are sampled at random inside their boxes; the background uses COLMAP points §3.1.
Step 2. Background: multi-scale neural Gaussians §3.2
- Each anchor carries one resolution level
l, chosen by the LOD rule of step 4 §3.2. - The level's grid resolution grows geometrically from a base value to a finest value §3.2eq. 3.
- Position is quantized into integer cells at that resolution §3.2eq. 4.
- Cells map to a feature index with a spatial hash (XOR of cell times primes, modulo table size) §3.2eq. 5.
- The anchor reads one table entry at its own level. Features are not summed across levels §3.2eq. 6.
Step 3. Background: geometry-guided partition §3.2
- Estimate the dominant direction of background points by PCA §3.2eq. 7.
- Project each point onto that direction to get depth
z§3.2eq. 8. - Cut depth at its 33rd and 67th percentiles into near, mid and far §3.2eq. 8.
- Give each region a voxel size
s_base / alpha_r, withalpha_near > alpha_mid > alpha_far§3.2eq. 9. The values ofalpha_rare not stated.
Step 4. Background: learnable LOD allocation §3.2
- Target level from camera distance
d§3.2eq. 10:floor(log_s(d_max / d)), wheresis a LOD scale andd_maxa scene-dependent constant (neither value is stated). - An anchor is rendered only if its assigned level is at most its target §3.2.
- The two cut depths and the soft-region sharpness are treated as learnable and are optimized with the rest of the model §3.2eq. 11.
- Soft membership of an anchor in a region uses sigmoids of depth minus each cut §3.2eq. 11.
Step 5. Dynamic actors §3.3
- Global motion: a tracked rotation and translation per frame move each actor from its canonical frame to the world §3.3eq. 12. This applies to rigid and non-rigid actors alike §3.3.
- Non-rigid actors add AnchorFlow, an N-layer MLP (N not stated). It takes
the anchor position, anchor feature and encoded time and predicts updated
anchor positions
P_a(t)§3.3. - A geometry update head moves each neural Gaussian with its anchor §3.3.
- Appearance heads then update opacity and colour per Gaussian at time t §3.3.
- Compose all actors with the background and splat them to RGB, depth and normal §3.3eq. 13eq. 14.
Step 6. Geometry priors and loss §3.4
- Priors: DepthAnything-V2 for relative depth, ZoeDepth for absolute depth, Omnidata for normals §3.4§4.2.
- Colour loss: L1 plus a weighted SSIM term, weight 0.2 §3.4eq. 16§4.2.
- Depth loss: the paper uses an absolute value of a correlation between the rendered depth and the relative prior §3.4eq. 17. See Pitfalls.
- Normal loss: an L1 term plus a cosine-similarity term against the normal prior §3.4eq. 18.
- Mask loss: a cross-entropy term on dynamic-actor masks, weight 0.01 in the paper §3.4§4.2eq. 15. See Paper vs code.
- Total loss is the sum with weights
lambda_d,lambda_n,lambda_m§3.4eq. 15.
Pseudocode for the partition and LOD rules (steps 3 and 4):
# Partition background points by depth along the main axis [§3.2] [eq. 7-8]
def partition_by_depth(points):
# Main direction: top principal component of the centred points [eq. 7]
direction = principal_axis(points - mean(points))
# Scalar depth of each point along that direction [eq. 8]
depth = (points - mean(points)) @ direction
# Cuts at the 33rd and 67th percentiles [§3.2]
tau_1 = percentile(depth, 33)
tau_2 = percentile(depth, 67)
# Near, mid and far masks from the two cuts [eq. 8]
near = depth <= tau_1
mid = (depth > tau_1) & (depth <= tau_2)
far = depth > tau_2
return near, mid, far# Soft membership of an anchor in one region [§3.2] [eq. 11]
def soft_region_weight(z, tau_low, tau_high, ell):
# Sigmoid step up at tau_low, step down at tau_high [eq. 11]
# tau_low is minus infinity for near and tau_high is plus infinity for far
up = sigmoid((z - tau_low) / ell)
down = sigmoid((z - tau_high) / ell)
return up - down# Visibility of an anchor from its LOD and camera distance [§3.2] [eq. 10]
def anchor_visible(level, distance, d_max, s):
# Target level from log base s of the distance ratio, rounded down [eq. 10]
target = floor(log(d_max / distance) / log(s))
# Render only if the anchor's level does not exceed the target [§3.2]
return level <= targetPseudocode for the dynamic actor and loss (steps 5 and 6):
# Place an actor's canonical Gaussians into the world [§3.3] [eq. 12]
def to_world(mu_obj, rot_obj, rot_track, trans_track):
# Position: rotate the canonical centre, then translate [eq. 12]
mu = rot_track @ mu_obj + trans_track
# Rotation: canonical rotation times the transposed track rotation [eq. 12]
rot = rot_obj @ transpose(rot_track)
return mu, rot# Anchor flow at time t [§3.3]
def anchor_flow(anchor_pos, anchor_feat, t):
# Encode position and time, then concatenate with the anchor feature [§3.3]
encoded = concat(encode(anchor_pos), anchor_feat, encode(t))
# The N-layer MLP outputs the updated anchor positions P_a(t) [§3.3]
return mlp(encoded)# Total training loss [§3.4] [eq. 15]
def total_loss(render, prior):
# Colour term: L1 plus SSIM term [eq. 16]
loss = l1(render.rgb, gt.rgb) + 0.2 * ssim_loss(render.rgb, gt.rgb)
# Depth prior term, weighted by lambda_d = 0.01 [eq. 17]
loss = loss + 0.01 * depth_term(render.depth, prior.depth)
# Normal prior term, weighted by lambda_n = 0.01 [eq. 18]
loss = loss + 0.01 * normal_term(render.normal, prior.normal)
return lossHyperparameters
Values marked "paper" come from the card's source paper; "code" values come
from raw/code/2508.15376 at the commit in the frontmatter. Where the paper
gives no value, the table says so.
| Name | Value | Where | Notes |
|---|---|---|---|
| Training iterations | 30,000 | §4.2 waymo_default.py | Same in code, Waymo and KITTI |
| Gradient statistics start | after 500 iterations | §4.2 waymo_default.py | Paper: "after 500 iterations" |
| Anchor refinement start | after 1500 iterations | §4.2 waymo_default.py | Pruning, addition and opacity updates |
| SSIM weight lambda | 0.2 | §4.2 eq. 16 [code: arguments/init.py#L264] | Code combines as (1 - 0.2) L1 + 0.2 (1 - SSIM); see Paper vs code |
| lambda_d (depth) | 0.01 | §4.2 waymo_default.py | |
| lambda_n (normal) | 0.01 | §4.2 waymo_default.py | |
| lambda_m (mask) | 0.01 (paper) | §4.2 waymo_default.py | Code default is 0.000 and no mask term is read in train.py |
| phi_1, phi_2 | 10, 4 | §4.2 | Meaning not stated in the paper. No occurrence in the code |
| Partition cuts | 33rd and 67th percentile | §3.2 | Code uses a 3-component Gaussian mixture by default, with a 10th/90th percentile fallback hash_lod_partitioner.py |
| Region voxel-scale ratio alpha_r | not stated | §3.2 eq. 9 | Code: voxel size divided by 10 (near), 5 (mid), 1 (far) gaussian_model_bkgd.py. A second set (0.8, 1.0, 1.5) sits in the partitioner hash_lod_partitioner.py |
| Resolution range r_base, r_finest | not stated | §3.2 eq. 3 | Code background: base 256, finest 16384 [code: arguments/init.py#L170-L172] |
| Hash levels L | not stated | §3.2 | Code background: 10 [code: arguments/init.py#L171] |
| Table size H (log2) | not stated | §3.2 eq. 5 | Code background: 2^21 [code: arguments/init.py#L173] |
| Feature dimension F | not stated | §3.2 | Code: 32 [code: arguments/init.py#L161] |
| Hash primes pi_1, pi_2, pi_3 | "fixed large primes", values not stated | §3.2 eq. 5 | Code: 73856093, 19349663, 83492791 hash_encoding.py |
| Anchor-flow MLP depth N | not stated | §3.3 | Code: 8 layers, width 256, skip at the middle layer, 10 frequencies for position and time anchor_deformation.py |
| LOD scale s, d_max | not stated | §3.2 eq. 10 | Code fork default 2.0 hash_lod_partitioner.py |
| Non-rigid start and warm-up | not stated | §3.3 | Code: start 0, warm-up 2000 [code: arguments/init.py#L138-L139]; the renderer's fallback is 3000 generate_neural_gaussian.py |
| Depth/normal loss gate | not stated | §3.4 | Code applies both only after iteration 100 train.py train.py |
| Optimizer and learning rates | not stated | - | Not traced in the code |
| Held-out views | every fourth frame | §4.2 | Code split_test = 4 waymo_default.py |
| Waymo sequences | 12 (8 from StreetGS, 4 from OmniRe) | §4.1 | Mix chosen for background and actor coverage |
| KITTI sequences | 3 | §4.1 | Chosen for dynamic actors and challenging backgrounds |
| Render resolution | Waymo 1066 x 1600; KITTI 370 x 1226 | tab. 1 tab. 2 | |
| Hardware and time | one NVIDIA L20 GPU, 68 min for 30K iterations | §4.2 | Author-reported |
Results
Author-reported. Setup: Waymo at 1066 x 1600 and KITTI at 370 x 1226, with novel views every fourth frame held out §4.1§4.2. Baselines are the methods listed in each table. Bold and underline are as printed in the paper.
Waymo, reconstruction and novel-view synthesis tab. 1
| Model | Type | D_opt | N_opt | Recon PSNR | Recon SSIM | Recon LPIPS | NVS PSNR | NVS SSIM | NVS LPIPS |
|---|---|---|---|---|---|---|---|---|---|
| 3D-GS | S | no | no | 33.15 | 0.929 | 0.108 | 30.57 | 0.923 | 0.113 |
| GaussianPro | S | yes | yes | 32.79 | 0.928 | 0.113 | 31.28 | 0.915 | 0.121 |
| Octree-GS | S | no | no | 33.12 | 0.934 | 0.109 | 31.84 | 0.917 | 0.109 |
| 4D-GS | D | no | no | 31.15 | 0.897 | 0.197 | 28.35 | 0.873 | 0.208 |
| Deform-GS | D | no | no | 32.58 | 0.909 | 0.162 | 30.04 | 0.892 | 0.174 |
| S3Gaussian | D | yes | no | 33.64 | 0.931 | 0.117 | 31.32 | 0.912 | 0.127 |
| PVG | D | yes | no | 34.37 | 0.934 | 0.102 | 31.89 | 0.912 | 0.118 |
| StreetGS | D | no | no | 35.15 | 0.935 | 0.110 | 30.24 | 0.878 | 0.125 |
| OmniRe | D | yes | no | 34.57 | 0.939 | 0.112 | 31.19 | 0.897 | 0.126 |
| Desire-GS | D | yes | yes | 34.35 | 0.925 | 0.109 | 32.35 | 0.917 | 0.122 |
| AD-GS | D | yes | no | 35.26 | 0.936 | 0.105 | 33.08 | 0.920 | 0.112 |
| DriveSplat | D | yes | yes | 35.41 | 0.937 | 0.096 | 33.83 | 0.923 | 0.103 |
S = static-only method, D = dynamic. D_opt and N_opt mark depth and normal supervision.
KITTI tab. 2
| Model | Type | Recon PSNR | Recon SSIM | Recon LPIPS | NVS PSNR | NVS SSIM | NVS LPIPS |
|---|---|---|---|---|---|---|---|
| 3D-GS | S | 24.43 | 0.817 | 0.162 | 20.10 | 0.678 | 0.224 |
| Octree-GS | S | 23.51 | 0.738 | 0.288 | 21.90 | 0.679 | 0.300 |
| GaussianPro | S | 23.51 | 0.788 | 0.181 | 18.47 | 0.607 | 0.277 |
| 4D-GS | D | 24.43 | 0.735 | 0.280 | 18.12 | 0.562 | 0.338 |
| Deform-GS | D | 27.64 | 0.810 | 0.113 | 22.01 | 0.727 | 0.156 |
| OmniRe | D | 28.68 | 0.874 | 0.115 | 20.86 | 0.592 | 0.187 |
| DriveSplat | D | 28.59 | 0.895 | 0.100 | 24.53 | 0.767 | 0.142 |
Scenes with mostly non-rigid actors (Waymo subset, PSNR = dynamic regions)* tab. 3
| Model | PSNR | SSIM | LPIPS | PSNR* |
|---|---|---|---|---|
| Deform-GS | 28.19 | 0.903 | 0.135 | 22.58 |
| 4D-GS | 23.77 | 0.860 | 0.121 | 17.90 |
| OmniRe | 30.69 | 0.906 | 0.107 | 28.79 |
| DriveSplat | 30.96 | 0.913 | 0.104 | 29.46 |
Challenging novel views, FID and FVD (lower is better), shifts of 1, 2 and 5 m tab. 4
| Model | 1 m FID | 1 m FVD | 2 m FID | 2 m FVD | 5 m FID | 5 m FVD |
|---|---|---|---|---|---|---|
| StreetGS | 38.3 | 16.8 | 61.9 | 36.7 | 149.6 | 64.9 |
| OmniRe | 41.8 | 25.4 | 60.4 | 34.5 | 155.9 | 68.4 |
| Desire-GS | 40.8 | 23.6 | 60.5 | 40.4 | 151.6 | 65.8 |
| AD-GS | 37.4 | 15.9 | 57.2 | 31.9 | 152.6 | 67.9 |
| DriveSplat | 35.8 | 12.9 | 50.0 | 27.2 | 149.3 | 64.0 |
Training and rendering cost tab. 5
| Model | Train (min) | FPS | PSNR (dB) |
|---|---|---|---|
| StreetGS | 84.6 | 44.1 | 30.24 |
| OmniRe | 68.2 | 51.5 | 31.19 |
| Desire-GS | 182.9 | 37.8 | 32.35 |
| AD-GS | 88.6 | 54.2 | 33.08 |
| DriveSplat | 69.6 | 73.5 | 33.83 |
The paper does not state the GPU used for the FPS measurements.
Ablation: point-cloud initialization tab. 6
| Initialization | PSNR | SSIM | LPIPS | Abs Rel |
|---|---|---|---|---|
| Random | 29.64 | 0.894 | 0.127 | 0.269 |
| SfM | 33.16 | 0.912 | 0.112 | 0.239 |
| LiDAR | 32.98 | 0.913 | 0.114 | 0.174 |
| DUSt3R | 31.42 | 0.887 | 0.118 | 0.209 |
| SfM + LiDAR (final) | 33.83 | 0.923 | 0.103 | 0.185 |
Ablation: background modules, added cumulatively tab. 7
| Model | PSNR | SSIM | LPIPS | FPS |
|---|---|---|---|---|
| Baseline (StreetGS background) | 31.98 | 0.915 | 0.119 | 50.87 |
| + SMG | 32.94 | 0.918 | 0.109 | 66.72 |
| + GSP | 33.47 | 0.919 | 0.107 | 61.60 |
| + LLOD | 33.83 | 0.923 | 0.103 | 73.52 |
SMG = scene-aware multi-scale Gaussian representation, GSP = geometry-guided partitioning, LLOD = learnable LOD allocation tab. 7.
Ablation: depth and normal priors tab. 8
| Depth model | AbsRel | MAE | delta 1.25 | PSNR |
|---|---|---|---|---|
| GaussianPro | 0.527 | 9.53 | 56.27 | 31.28 |
| Ours, without depth loss | 0.288 | 5.26 | 69.23 | 33.20 |
| Ours, absolute depth prior D_m | 0.124 | 3.41 | 81.99 | 33.12 |
| Ours, relative depth prior D_r (final) | 0.179 | 3.87 | 79.38 | 33.83 |
| Normal model | MAE | RMSE | Similarity | PSNR |
|---|---|---|---|---|
| GaussianPro | 1.89 | 2.65 | 0.082 | 31.28 |
| Ours, without normal loss | 1.21 | 2.24 | 0.276 | 33.31 |
| Ours, with normal loss (final) | 0.84 | 1.78 | 0.498 | 33.83 |
Ablation: dynamic-actor deformation tab. 9
| Model | PSNR | SSIM | LPIPS | FPS |
|---|---|---|---|---|
| OmniRe | 30.69 | 0.906 | 0.107 | 37.2 |
| Ours, without deformation | 28.37 | 0.891 | 0.124 | 58.9 |
| Ours, with Deform-GS network | 30.84 | 0.912 | 0.107 | 39.3 |
| Ours, with anchor-centric deformation (final) | 30.96 | 0.913 | 0.104 | 48.7 |
Ablation: loss terms tab. 10
| Model | PSNR | SSIM | LPIPS |
|---|---|---|---|
| Without normal loss | 30.51 | 0.911 | 0.105 |
| Without depth loss | 30.39 | 0.910 | 0.106 |
| Without mask loss | 30.14 | 0.908 | 0.108 |
| Full model | 30.96 | 0.913 | 0.104 |
The paper's text names mask loss the largest single contributor in this ablation §4.6.
Paper vs code
The official code is at https://github.com/Michael-Evans-Savitar/DriveSplat,
commit 0db6a70fa0a7d5f8863b9068e1f37bb7e81db05a. Its README calls it "the
official code release" for this paper README.md. The repository
owner is not one of the paper's authors. We use it because the paper's
project page (physwm.github.io/drivesplat) links it under "Code". The
repository has no LICENSE file at its root, so its license is unstated. Do
not copy code from it. Use the paths below for reference only.
Discrepancies, each with both citations:
- Partition method. Paper: cuts at the 33rd and 67th depth percentiles §3.2eq. 8. Code: a 3-component Gaussian mixture, with a 10th/90th percentile fallback hash_lod_partitioner.py.
- Learnable cuts. Paper: the two cuts and sharpness are learnable and enter through sigmoids §3.2eq. 11. Code: the cuts are stored as parameters with
requires_grad=False, and region labels are hard hash_lod_partitioner.py gaussian_model_bkgd.py. No sigmoid soft assignment was found in the code. - LOD rule. Paper: target level
floor(log_s(d_max/d))and render if level is at most the target §3.2eq. 10. Code: level islog(standard_dist / dist) / log(lod_base)plus an extra level term, minus distance-based bias, clamped and then compared with the anchor's level gaussian_model_bkgd.py.lod_baseis the hash per-level scale when hashing is on, otherwise the fork value gaussian_model_bkgd.py. The per-anchor LOD bias defined in the partitioner (paper-style Eq. 12 in its comments) is never called in the background path hash_lod_partitioner.py. - Hash lookup. Paper: one table entry per anchor at its own level, read at a grid index §3.2eq. 6. Code: trilinear interpolation over the eight corners of each level, enabled by default hash_encoding.py [code: arguments/init.py#L185]. The tiny-cuda-nn path always interpolates hash_encoding.py.
- Single-level rule for the background. Paper: single-level reads §3.2. Code: the shared default is single-level [code: arguments/init.py#L166], but the background override is off [code: arguments/init.py#L190], with a comment that the background uses its standard neural Gaussian features [code: arguments/init.py#L187-L189]. Which path runs in the released configuration was not resolved.
- Two scale sets. Paper: one ratio alpha per region §3.2eq. 9. Code: voxel/10, /5, /1 for near, mid and far gaussian_model_bkgd.py, and separately 0.8, 1.0, 1.5 in the partitioner hash_lod_partitioner.py. Which set drives the anchor level was not fully traced.
- Actor motion. Paper: global rigid transform from tracked poses §3.3eq. 12. Code: the actor pose handling was not traced in this pass.
- Anchor deformation. Paper: an N-layer MLP predicts updated anchor positions §3.3. Code: an 8 by 256 MLP predicts a 3D anchor displacement and a 6D rotation, and the offset is rotated by the anchor's rotation anchor_deformation.py anchor_deformation.py anchor_deformation.py.
- Deformation output. The deformation step returns zero rotation and scale deltas for each Gaussian deform_model.py. The paper's appearance heads for opacity and colour at time t §3.3 were not located in this pass.
- Non-rigid ramp. Paper: not stated. Code: the residual is multiplied by zero before the start, by the square root of linear progress during warm-up, and by one after generate_neural_gaussian.py. The opacity threshold ramps from 0 to 0.001 over the same schedule generate_neural_gaussian.py.
- Photometric loss form. Paper: L1 plus lambda times an SSIM loss §3.4eq. 16. Code: (1 - 0.2) L1 + 0.2 (1 - SSIM) train.py train.py. The code uses a convex combination with an explicit 1 minus SSIM.
- Depth loss form. Paper: the L1 norm of a normalized covariance between rendered depth and the relative prior §3.4eq. 17. Code: 1 minus the Pearson correlation between the rendered depth and 1/(prior + 200) train.py train.py train.py train.py. The offset of 200 is not in the paper.
- Absolute depth. Paper: supports an absolute prior with an L1 term §3.4. Code: the L1 branch exists, but
depth_modeis set to "relative" in both places, so that branch is never taken train.py train.py. - Normal loss. Paper: an L1 term plus a cosine-similarity term §3.4eq. 18. Code: L1 plus (1 minus the dot product), with the prior rescaled from [0, 1] to [-1, 1] and rotated by the camera's rotation train.py train.py.
- Mask loss. Paper: cross-entropy on actor masks with weight 0.01 §3.4§4.2. Code: the default weight is 0.000 waymo_default.py, and the only use of the semantic output in training is an activation check train.py. No cross-entropy term was found in the training loss. The renderer applies a log to the semantic output and comments that this is for cross-entropy drivesplat_render.py.
- Phi constants. Paper: phi_1 = 10 and phi_2 = 4 §4.2. Code: no matching constants were found, so their meaning is not resolved.
- Background hash table. Paper: no table size, feature dimension or primes given §3.2. Code: table 2^21, feature dimension 32, primes 73856093, 19349663 and 83492791 [code: arguments/init.py#L161] [code: arguments/init.py#L173] hash_encoding.py.
Pitfalls
- Text overstates Table 1 and 2. The text says DriveSplat has the best SSIM and LPIPS for reconstruction on Waymo §4.3. Table 1 has OmniRe at SSIM 0.939 against DriveSplat's 0.937 tab. 1. On KITTI the text says DriveSplat beats all baselines in reconstruction §4.3, but OmniRe's reconstruction PSNR is 28.68 against 28.59 tab. 2. Use the tables, not the prose.
- Sequence count differs. The text in §4.3 says "two select sequences" for the non-rigid comparison §4.3. The ablation in §4.6 says four sequences §4.6. The subset behind tab. 3 is unclear.
- Same name, different numbers. DriveSplat's PSNR is 33.83 in several tables and 30.96 in others, because the subsets differ. Compare like with like.
- Depth-loss form. Minimizing the paper's |correlation| would push the correlation toward zero, which does not match a prior that should agree with the rendered depth. The code minimizes 1 minus the correlation, which is smallest at full agreement. Implement the code's form and check the sign.
- Normal cosine term. The paper says "cosine similarity loss" §3.4 and gives no separate formula eq. 18. The code uses 1 minus the dot product. Use that.
- Background decisions are not fully specified. The paper leaves the scale ratio, the LOD scale, the table size, the level count and the feature dimension unstated §3.2. The code's values are in the Hyperparameters table, but they are code defaults, not paper claims.
- Learnable cuts are not in the code path we traced. Build the partition as hard labels from the chosen percentile or mixture method, and do not implement learnable cuts unless you verify them elsewhere.
- Depth and normal losses are gated. They run only after iteration 100 in the code, and the paper does not say so train.py train.py.
- Non-rigid schedule. Paper gives no schedule. Code uses a square-root ramp and a default of zero starting iteration in the arguments, but the renderer falls back to 3000 when the attribute is missing [code: arguments/init.py#L138-L139] generate_neural_gaussian.py.
- Reference environment is narrow. The README asks for Python 3.7, PyTorch 1.13, CUDA 11.7, a modified rasterizer, and a COLMAP binary on PATH; it warns against replacing the rasterizer with the upstream package README.md README.md.
- Data prep is a large step. Waymo needs gsutil, TFRecord conversion, LiDAR depth, sky masks via GroundingDINO and SAM, and monocular priors. Some priors are optional and controlled by config README.md.
- Paper states cost, not the GPU for FPS. 68 minutes is on one L20 for 30K iterations §4.2. The FPS figure has no stated hardware tab. 5.
- Editing is limited. Vehicles are only partly reconstructed from one viewpoint, so edits can expose holes §5.2. The paper says future work will add image-to-3D completion §5.2.
- No license for the code. Use it only for reading and for citations. Build from the paper and this card, not by copying repository files.
Lineage
- Builds on: neural Gaussians with anchors (cited as lu2024scaffold and ren2024octree) §2; deformation fields for dynamic scenes, following Deform-GS and 4D-GS §2; depth and normal priors for Gaussians §2.
- Compared against: 3D-GS, GaussianPro, Octree-GS, 4D-GS, Deform-GS, S3Gaussian, PVG, StreetGS, OmniRe, Desire-GS, AD-GS tab. 1 tab. 2.
- Superseded by: not known from the card's content.
Source and license
Adapted from “DriveSplat: Unified Neural Gaussian Reconstruction for Dynamic Driving Scenes” by Cong Wang, Ruiqi Song, Wei Tian, Chenming Zhang, Lingxi Li, Long Chen (arXiv:2508.15376), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/Michael-Evans-Savitar/DriveSplat at commit 0db6a70fa0a7 (Unlicensed (no LICENSE file in the repository)). Any quoted code is shown under that license.