3D feature grids
Lightplane Renderer or Splatter represent 3D scenes as a grid-list grid of M feature grids g_i:
grid: List[torch.Tensor] = [g_1, ..., g_M]
Each g_i is a 5D tensor of shape (B, D, H, W, C), with batch size B , number of feature channels C (equal for all grids), and the grid depth, height, and width D, H, and W respectively.
Representing Voxel grid: If all g_i’s dimensions are non-singular (H>1 or D>1 or W>1), g_i represents a batch of voxel grids with C-dimensional features.
Representing 2D plane: In case one of the g_i’s dimensions is singular (H == 1 or D==1 or W==1), g_i is treated as a planar 2D grid whose cells represent all points along a 3D line passing through the cell’s center orthogonal to the plane (akin to a triplane).
The grid-list is a mandatory argument for both LightplaneRenderer and LigthplaneMLPSplatter, and is output by LigthplaneSplatter and LigthplaneMLPSplatter.
Note
Below are examples of representing the latest grid-based representations:
Triplane:
grid = [
torch.randn(B, 1, H, W, C), # xy plane
torch.randn(B, D, 1, W, C), # xz plane
torch.randn(B, D, H, 1, C), # yz plane
]
Voxel grid:
grid = [torch.randn(B, D, H, W, C)]
Voxel grid and triplane:
grid = [
torch.randn(B, D_voxels, H_voxels, W_voxels, C), # voxel grid
torch.randn(B, 1, H, W, C), # xy plane
torch.randn(B, D, 1, W, C), # xz plane
torch.randn(B, D, H, 1, C), # yz plane
]
Note
All grids in a grid-list have to share the same number of channels C and batch size B, however, the spatial dimensions D, H, W of each grid can be arbitrarily different across grids.
Grid coordinate frame
We follow the PyTorch grid_sample coordinate convention.
Each grid g represents a 3D cube of side [-1, 1] centered at [0, 0, 0]. All rendering rays thus have to be correctly emitted to render points inside the latter cube.
A continuous 3D point pt_3d=[x,y,z] with coordinates [-1.0, -1.0, -1.0] indexes the outer corner of g’s voxel at integer cell [0, 0, 0] in the 3D grid, while a 3D point [1.0, 1.0, 1.0] corresponds to the opposite cell at [D-1, H-1, W-1].
A 3D point pt_3d=[x,y,z] indexes the g tensor in reverse order of p’s dimensions, i.e.:
x=pt_3d[0]indexes the width (i.e. 3rdW-dimension) ofgy=pt_3d[1]indexes the height (i.e. 2ndH-dimension) ofgz=pt_3d[2]indexes the depth (i.e. 1stD-dimension) ofg
For example, in a 3D grid g of size [2, 4, 8], a continuous 3D point pt_3d=[-0.25, 0.25, 0.0] corresponds to g’s element at integer coordinates [0, 1, 3].
Feature grid sampling
Lightplane Renderer and Splatter rely on a function sample_grid(pt_3d, grid) that sums the C-dimensional vectors sample(pt_3d, g) sampled at a continuous 3D location pt_3d=[x,y,z] from each grid g of the grid-list grid:
sample_grid(pt_3d, grid) = sum(sample(pt_3d, g) for g in grid)
Here, sample interpolates the grid g using a linearly-weighted scheme depending on the number of g’s non-singular dimensions:
3 non-singular dimensions: If all spatial dimensions of the grid
gare non-singular (i.e.D>1 and H>1 and W>1), the feature is trilinearly interpolated from the grid at locationpt_3d.# define a random voxel grid B, D, H, W, C = 4, 3, 7, 5, 6 g = torch.randn(B, D, H, W, C) # sample with trilinear interpolation sampled_feature = trilinear_interpolation(g, pt_3d)
2 non-singular dimensions: If one of the spatial dimensions of the grid is singular (i.e.
D==1 or H==1 or W==1), the feature is bilinearly interpolated from the 2D gridg_2d(obtained by squeezing the singular dimension ofg) at the 2D coordinatept_2dcomprising the 2 coordinates of the 3D pointpt_3dcorresponding to non-singular dimensions. The following example demonstrates Lightplane’s bilinear interpolation of a(B, D, 1, W, C)grid.# define a random grid with a singular height B, D, H, W, C = 4, 3, 1, 5, 6 g = torch.randn(B, D, H, W, C) # squeeze the singular height-dimension to obtain the corresponding 2d grid g_2d = g.squeeze(2) # the height-dimension is singular so we only sample the x- and z-coordinates # using bilinear interpolation x, y, z = pt_3d sampled_feature = bilinear_interpolation(g, [x, z])
Feature grid splatting
Lightplane Splatter pushes 3d-point-specific C-dimensional vectors f(pt_3d) to each grid g of the grid-list grid by means of splatting:
grid_splatted = [splat_to_grid(f(pt_3d), g_i) for g_i in grid]
Similar to the renderer, splatting is either bilinear or trilinear depending on the number of singular dimensions of g_i.
3 non-singular dimensions: If all spatial dimensions of the grid
gare non-singular (i.e.D>1 and H>1 and W>1), the feature is trilinearly splatted to the grid at locationpt_3d.# define a random voxel grid B, D, H, W, C = 4, 3, 7, 5, 6 g = torch.randn(B, D, H, W, C) # splat feature f(pt_3d) to the grid g to create a new grid g_splatted = trilinear_splatting(g, pt_3d, f(pt_3d))
2 non-singular dimensions: If one of the spatial dimensions of the grid is singular (i.e.
D==1 or H==1 or W==1), the feature is bilinearly splatted to the 2D gridg_2d(obtained by squeezing the singular dimension ofg) at the 2D coordinatept_2dcomprising the 2 coordinates of the 3D pointpt_3dcorresponding to non-singular dimensions. The following example demonstrates Lightplane’s bilinear splatting of a(B, D, 1, W, C)grid.# define a random grid with a singular height B, D, H, W, C = 4, 3, 1, 5, 6 g = torch.randn(B, D, H, W, C) # squeeze the singular height-dimension to obtain the corresponding 2d grid g_2d = g.squeeze(2) # the height-dimension is singular so we only sample the x- and z-coordinates # using bilinear interpolation x, y, z = pt_3d g_splatted = bilinear_splatting(g, [x, z], f(pt_3d))