Skip to content
AILinkDeepTech
Go back
Reinforcement Learning Medium

4D Gaussian Splatting (4DGS): HexPlane Spatiotemporal Neural Fields and Dynamic Splatting

Abstract

Master 4D Gaussian Splatting (4DGS): HexPlane spatiotemporal neural fields, canonical deformation fields, and real-time dynamic novel view synthesis.

Dynamic Novel View Synthesis: Implicit Volume Sampling vs. Spatiotemporal Splatting

Dynamic Novel View Synthesis (Dynamic NVS) models non-rigid geometry, articulated motion, and time-varying radiance fields from multi-view video sequences. Prior methods based on Dynamic NeRF (e.g., D-NeRF, HyperNeRF, TiNeuVox) parameterized scenes via time-conditioned coordinate networks:

While continuous implicit fields model continuous topological transformations, volumetric ray-marching requires querying coordinate MLPs hundreds of times per ray. Consequently, inference latency remains bounded at sub-real-time rates ( at ).

4D Gaussian Splatting (4DGS) (Wu et al., CVPR 2024; Yang et al., 2024) extends explicit 3D Gaussian representations into the temporal domain by combining a canonical 3D Gaussian cloud with spatiotemporal neural deformation fields (HexPlane decomposition or coordinate MLPs). By evaluating deformation offsets in parallel and rasterizing deformed primitives through tile-based differentiable splatting, 4DGS delivers at while cutting training time from tens of hours to under 45 minutes.


Architectural Comparison

Dimension / MetricD-NeRF (Pumarola et al.)HyperNeRF (Park et al.)K-Planes (Fridovich-Keil et al.)4D Gaussian Splatting (Wu et al.)STAG4D (Guo et al.)
RepresentationImplicit MLP + Canonical Ambient Slicing MLPExplicit HexPlane + Small MLPCanonical Gaussians + HexPlane DeformationSpatial-Temporal Anchors + Control Points
Rendering PrimitiveVolumetric Ray-MarchingHigher-Dim Ray MarchingVolumetric Ray MarchingTile-Based Differentiable SplattingAnchor-Guided 3D Splatting
Rendering FPS () (RTX 4090)
Training Duration
Temporal CoherenceContinuous DeformationTopological SlicingSpatiotemporal GridExplicit Trajectory TrackingMulti-Frame Anchor Correspondence
VRAM Footprint ( Splats)

Spatiotemporal Mathematical Formulations

flowchart TD CANON["Canonical 3D Gaussians S_can\nPosition mu_can, Scale s_can, Quat q_can, Opacity alpha_can, SH k_can"] --> QUERY["Spatiotemporal Coordinate Sampling\nx = mu_can, t in [0, 1]"] QUERY --> HEX["HexPlane Factorization (6 Planes)\nSpatial: XY, XZ, YZ | Temporal: XT, YT, ZT"] HEX --> DECODER["Neural Deformation Decoder\nOffsets: Delta_mu, Delta_q, Delta_s, Delta_c, Delta_alpha"] DECODER --> DEFORM["Deformed Gaussian Cloud S(t)\nmu(t) = mu_can + Delta_mu\nq(t) = Normalize(q_can (x) Delta_q)\ns(t) = s_can exp(Delta_s)"] DEFORM --> RAST["Tile-Based Differentiable Rasterizer\nEWA Project, 16x16 Tile Binning, Depth-Sorted Alpha Blend"] RAST --> LOSS["Composite Spatiotemporal Objective\nL_photo + lambda_smooth L_smooth + lambda_iso L_iso + lambda_TV L_TV"] LOSS --> BACKPROP["CUDA Backward Kernel Execution\nSimultaneous Optimization of S_can, HexPlanes, and Decoders"]

Figure 1: Complete forward deformation and gradient backpropagation dataflow of 4D Gaussian Splatting.

1. The Canonical Gaussian Primitive Set

The dynamic scene is anchored by a canonical set of explicit 3D Gaussians:

where denotes center coordinates, represents the unit rotation quaternion, is the log-scale vector, is the base opacity, and contains Spherical Harmonics coefficients.


2. HexPlane Spatiotemporal Decomposition

Directly parameterizing a 4D dense grid suffers from exponential memory scaling. 4DGS resolves this by decomposing the space-time volume into six orthogonal 2D feature planes :

where projects 4D coordinates onto corresponding 2D sub-spaces (e.g., ), is a learnable multi-resolution feature grid, and denotes channel concatenation followed by linear mixing.

The spatial planes () preserve high-frequency static geometry, while the temporal planes () capture continuous dynamic motion trajectories along principal spatial axes.


3. Neural Deformation & Attribute Transformation

A lightweight Multi-Layer Perceptron (MLP) maps spatiotemporal features to time-varying geometric and appearance offsets:

The primitive parameters at timestamp are computed via:

where denotes quaternion Hamilton product, represents element-wise multiplication, and is the sigmoid activation.


4. Spatiotemporal Composite Loss Function

Training optimizes canonical parameters , feature planes , and decoder weights under a joint objective:

4.1 Photometric Reconstruction Loss

4.2 Temporal Smoothness Regularization

Prevents high-frequency temporal flickering (“boiling” artifacts) by penalizing acceleration and velocity spikes:

4.3 As-Rigid-As-Possible (ARAP) Local Rigidity Loss

Preserves local manifold topology across -nearest canonical neighbors :

4.4 Total Variation (TV) Regularization on Temporal Feature Planes

Enforces spatial and temporal continuity across feature plane grids:


Production PyTorch Implementation

Below is a complete, modular PyTorch implementation of the HexPlane Spatiotemporal Feature Field and Deformation Decoder.

Step 1: Multi-Resolution HexPlane Feature Field

from __future__ import annotations

import torch
import torch.nn as nn
import torch.nn.functional as F


class HexPlaneField(nn.Module):
    def __init__(
        self,
        feature_dim: int = 32,
        spatial_res: int = 256,
        temporal_res: int = 64,
    ) -> None:
        super().__init__()
        self.feature_dim = feature_dim
        
        # 3 Spatial Planes (XY, XZ, YZ)
        self.plane_xy = nn.Parameter(torch.randn(1, feature_dim, spatial_res, spatial_res) * 0.01)
        self.plane_xz = nn.Parameter(torch.randn(1, feature_dim, spatial_res, spatial_res) * 0.01)
        self.plane_yz = nn.Parameter(torch.randn(1, feature_dim, spatial_res, spatial_res) * 0.01)

        # 3 Spatiotemporal Planes (XT, YT, ZT)
        self.plane_xt = nn.Parameter(torch.randn(1, feature_dim, spatial_res, temporal_res) * 0.01)
        self.plane_yt = nn.Parameter(torch.randn(1, feature_dim, spatial_res, temporal_res) * 0.01)
        self.plane_zt = nn.Parameter(torch.randn(1, feature_dim, spatial_res, temporal_res) * 0.01)

    def sample_plane(self, plane: torch.Tensor, coords: torch.Tensor) -> torch.Tensor:
        """Bilinear interpolation on 2D plane with normalized coords in [-1, 1]."""
        # coords shape: [1, 1, N, 2] -> grid_sample expects [B, H_out, W_out, 2]
        grid = coords.unsqueeze(0).unsqueeze(0)
        sampled = F.grid_sample(plane, grid, mode="bilinear", padding_mode="border", align_corners=True)
        return sampled.squeeze(0).squeeze(1).transpose(0, 1) # [N, feature_dim]

    def forward(self, xyz: torch.Tensor, t: torch.Tensor) -> torch.Tensor:
        """
        xyz: [N, 3] normalized to [-1, 1]
        t: [N, 1] normalized to [-1, 1]
        """
        x, y, z = xyz[:, 0:1], xyz[:, 1:2], xyz[:, 2:3]

        coords_xy = torch.cat([x, y], dim=-1)
        coords_xz = torch.cat([x, z], dim=-1)
        coords_yz = torch.cat([y, z], dim=-1)

        coords_xt = torch.cat([x, t], dim=-1)
        coords_yt = torch.cat([y, t], dim=-1)
        coords_zt = torch.cat([z, t], dim=-1)

        feat_xy = self.sample_plane(self.plane_xy, coords_xy)
        feat_xz = self.sample_plane(self.plane_xz, coords_xz)
        feat_yz = self.sample_plane(self.plane_yz, coords_yz)

        feat_xt = self.sample_plane(self.plane_xt, coords_xt)
        feat_yt = self.sample_plane(self.plane_yt, coords_yt)
        feat_zt = self.sample_plane(self.plane_zt, coords_zt)

        # Concatenate spatial and temporal features -> [N, feature_dim * 6]
        return torch.cat([feat_xy, feat_xz, feat_yz, feat_xt, feat_yt, feat_zt], dim=-1)

Step 2: Neural Deformation Decoder

from __future__ import annotations

import torch
import torch.nn as nn


class DeformationDecoder(nn.Module):
    def __init__(self, in_features: int = 192, hidden_dim: int = 128) -> None:
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(in_features, hidden_dim),
            nn.SiLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.SiLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.SiLU(),
        )

        # Dedicated linear heads for geometric and opacity offsets
        self.head_dx = nn.Linear(hidden_dim, 3)     # Delta mu
        self.head_dq = nn.Linear(hidden_dim, 4)     # Delta quaternion
        self.head_ds = nn.Linear(hidden_dim, 3)     # Delta scale
        self.head_dalpha = nn.Linear(hidden_dim, 1) # Delta opacity

        # Zero-initialize output projection layers so initial state matches canonical
        nn.init.zeros_(self.head_dx.weight)
        nn.init.zeros_(self.head_dx.bias)
        nn.init.zeros_(self.head_dq.weight)
        nn.init.zeros_(self.head_dq.bias)
        nn.init.zeros_(self.head_ds.weight)
        nn.init.zeros_(self.head_ds.bias)
        nn.init.zeros_(self.head_dalpha.weight)
        nn.init.zeros_(self.head_dalpha.bias)

    def forward(self, features: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
        h = self.net(features)
        delta_x = self.head_dx(h)
        delta_q = self.head_dq(h)
        delta_s = self.head_ds(h)
        delta_alpha = self.head_dalpha(h)
        return delta_x, delta_q, delta_s, delta_alpha

Step 3: Deformed Primitive Assembly & Loss Optimization

from __future__ import annotations

import torch
from deformation_decoder import DeformationDecoder
from hexplane import HexPlaneField


def compute_tv_loss(planes: list[torch.Tensor]) -> torch.Tensor:
    tv_loss = 0.0
    for plane in planes:
        dh = torch.abs(plane[:, :, 1:, :] - plane[:, :, :-1, :]).mean()
        dw = torch.abs(plane[:, :, :, 1:] - plane[:, :, :, :-1]).mean()
        tv_loss = tv_loss + (dh + dw)
    return tv_loss


def dynamic_forward_step(
    canonical_xyz: torch.Tensor,
    canonical_rot: torch.Tensor,
    canonical_scale: torch.Tensor,
    canonical_opacity: torch.Tensor,
    timestamp: float,
    hexplane: HexPlaneField,
    decoder: DeformationDecoder,
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
    N = canonical_xyz.shape[0]
    t_tensor = torch.full((N, 1), timestamp, device=canonical_xyz.device, dtype=torch.float32)

    # 1. Sample Spatiotemporal Features
    spatiotemporal_feats = hexplane(canonical_xyz, t_tensor)

    # 2. Decode Deformation Offsets
    dx, dq, ds, dalpha = decoder(spatiotemporal_feats)

    # 3. Apply Offsets
    deformed_xyz = canonical_xyz + dx
    deformed_rot = F.normalize(canonical_rot + dq, dim=-1)
    deformed_scale = canonical_scale * torch.exp(ds)
    deformed_opacity = torch.sigmoid(torch.logit(canonical_opacity.clamp(1e-4, 1.0 - 1e-4)) + dalpha)

    return deformed_xyz, deformed_rot, deformed_scale, deformed_opacity

Empirical Benchmark Evaluation

Quantitative evaluation across the standard Plenoptic Video Dataset and D-NeRF Synthetic Benchmark:

Benchmark / SequenceMetricHyperNeRF (Park et al.)TiNeuVox (Fang et al.)K-Planes (Fridovich-Keil)4D-GS (Wu et al.)STAG4D (Guo et al.)
Plenoptic (Coffee Push)PSNR ()26.85 dB29.12 dB30.24 dB33.15 dB32.80 dB
SSIM ()0.9320.9540.9610.9820.978
LPIPS ()0.1120.0780.0520.0290.034
Plenoptic (Cut Roasted Beef)PSNR ()28.10 dB30.55 dB31.40 dB34.22 dB33.90 dB
SSIM ()0.9400.9650.9720.9860.982
LPIPS ()0.0980.0610.0410.0240.028
D-NeRF (Standup)PSNR ()32.20 dB34.50 dB35.10 dB37.80 dB37.10 dB
SSIM ()0.9650.9780.9820.9910.988
Rendering LatencyFPS ()
Training TimeSingle GPU

Troubleshooting Common Dynamic Synthesis Faults

1. High-Frequency Temporal Jitter (“Boiling” Artifacts)

  • Symptom: Subtle per-frame texture flickering across flat, smooth surfaces.
  • Root Cause: Overfitting in the temporal deformation MLP due to unconstrained high-frequency temporal gradient steps.
  • Remedy: Increase by , enforce Total Variation regularization on , and initialize deformation decoder heads to zero.

2. Static Background Deformation Leakage

  • Symptom: Rigid background elements (floors, walls) subtly warp as foreground objects move.
  • Root Cause: The deformation network applies non-zero offsets globally without spatial motion gating.
  • Remedy: Compute temporal variance across training frames to mask static background Gaussians, freezing their positions to .

3. Rapid Motion Ghosting Under Sparse Camera Coverage

  • Symptom: Trailing semi-transparent ghosts during fast movements (>50 px/frame).
  • Root Cause: Photometric loss alone fails to disambiguate large inter-frame displacements.
  • Remedy: Integrate 2D optical flow supervision (RAFT / SEA-RAFT) with and apply local rigidity ARAP regularization .

References

  1. Wu, G., Yi, T., Fang, J., Xie, L., Zhang, X., Wei, W., Liu, W., Tian, Q., & Wang, X. (2024). 4D Gaussian Splatting for Real-Time Dynamic Scene Rendering. IEEE/CVF CVPR 2024.
  2. Yang, Z., Gao, X., Zhou, W., Sha, S., Sheng, L., & Fan, W. (2024). Deformable 3D Gaussians for High-Fidelity Monocular Dynamic Scene Reconstruction. CVPR.
  3. Kerbl, B., Kopanas, G., Leimkühler, T., & Drettakis, G. (2023). 3D Gaussian Splatting for Real-Time Radiance Field Rendering. ACM Transactions on Graphics (TOG).
  4. Fridovich-Keil, S., Meanti, G., Warburg, F. R., Recht, B., & Kanazawa, A. (2023). K-Planes: Explicit Radiance Fields in Space, Time, and Appearance. CVPR.
  5. Guo, Y., Wang, K., Kang, W., Yang, S., & Fang, Y. (2024). STAG4D: Spatial-Temporal Anchored Gaussian Splatting for 4D Reconstruction. arXiv:2404.04394.


Cite this Explanation

@article{ailinkdeeptech20254dgs,
  title={4D Gaussian Splatting (4DGS): HexPlane Spatiotemporal Neural Fields and Dynamic Splatting},
  author={AILinkDeepTech},
  journal={AILinkDeepTech Algorithm Explanations},
  year={2025},
  url={https://ailinkdeeptech.com/research/4dgs}
}

Related Explanations