Lightplane Renderer
Renderer module API
The Lightplane Renderer operator is implemented via following interfaces:
PyTorch module:
LightplaneRenderer
Functional interface:
lightplane_renderer
Visit Lightplane Renderer API reference for detailed documentation.
EA rendering with MLP decoding
Lightplane Renderer implements the Emission-Absorption (EA) method which marches along rendering rays in order to image a 3D feature grid (represented with a grid-list grid
).
It outputs the final color c
, alpha value m
and expected ray-termination length r
of each ray’s pixel, as follows:
Sample
N=num_samples
equispaced 3D pointspt_3d_i
between thenear
andfar
ray-lengths:pt_3d_1, ..., pt_3d_N = origin + t * direction, t = linspace(near, far, num_samples)
Using Lightplane’s MLP decoder, each sampled point
pt_3d_i
is annotated with opacity valueo_i
and color vectorc_i
(of an arbitrary dimension). Here opacityo_i = softplus(ro_i)
is a softplus-activated raw opacityro_i
, andc_i = sigmoid(lc_i)
is output by a sigmoid activation of predicted color logitslc_i
.The architecture of the decoder depends on the value of
use_separate_color_grid
argument ofLightplaneRenderer
:LightplaneRenderer.use_separate_color_grid==False
grid -> f_i -> trunk_mlp -> e_i -> e_i + ray_encoding -> color_mlp -> c_i -> opacity_mlp -> o_i
An MLP
trunk_mlp
maps the grid-sampled featuref_i
to a trunk featuree_i
, which is later converted to opacity and color with a pair of additional color and opacity MLP headscolor_mlp
andopacity_mlp
. The trunk featuree_i
is summed withray_encoding
beforecolor_mlp
to make the predicted color viewpoint dependent.LightplaneRenderer.use_separate_color_grid==True
grid -> f_i -> opacity_mlp -> o_i color_grid -> cf_i -> cf_i + ray_encoding -> color_mlp -> c_i
The lightplane kernel receives a pair of opacity and color grid-lists
grid
andcolor_grid
. Each grid-list is sampled yielding featuresf_i
andcf_i
respectively, followed by a grid-specific MLP (opacity_mlp
,color_mlp
) converting the sampled feature to opacity and color. The color featurecf_i
is summed withray_encoding
beforecolor_mlp
to make the predicted color viewpoint dependent.
The list of colors and opacities predicted for each point along the ray is integrated to form the final color render
c
(real vector), ray-length renderr
(scalar in[0, inf]
), and alpha valuem
(scalar in[0, 1]
):
c = sum_[i=0 ... N] (T_(i-1) - T_i) * c_i # color render
r = sum_[i=0 ... N] (T_(i-1) - T_i) * delta_i # ray-length render
m = 1 - T_N # alpha value
T_i = exp[-(gain * delta_0 * o_0 + ... + gain * delta_i o_i)] # transmittance
where delta_i
is the distance between two adjacent samples along the ray, and T_i
is the Transmittance of i
-th point.
Renderer configuration
Scaffolded rendering
Lightplane allows to use a binary voxel-grid scaffold to fast-track raymarching for ray-points that are known to be unoccupied (i.e. they have 0 opacity o_i==0
).
If the scaffolded raymarching is enabled, the renderer will first sample the binary scaffold voxel grid using nearest neighbor interpolation.
For a non-zero scaffold indicator, the renderer will proceed with MLP-decoding the sampled feature to opacity and color.
If the scaffold indicator yields zero, the renderer will skip MLP-decoding and directly output 0 opacity and color for the point.
Note
Scaffolded ray-marching is enabled by setting the scaffold
argument of LightplaneRenderer.forward
to a
binary (B, D, H, W)
tensor.
Opacity noise injection
To prevent the renderering decoder from collapsing to predicting zero opacities everywhere, the renderer also supports random opacity noise injection.
If enabled, the opacity o_i = softplus(ro_i + n_i); n_i ~ N(0, inject_noise_sigma)
is redefined to softplus
-activate the predicted raw opacity jittered with a noise vector eps
sampled from a zero-centered Gaussian with variance inject_noise_sigma
.
Note
Opacity noise injection is enabled by setting the inject_noise_sigma
argument of LightplaneRenderer
to a value bigger than 0. Reproducible rendering passes can be achieved by setting the seed inject_noise_sigma
of the random noise to an integer.
Modeling background
The default Lightplane renderer only represents points lying inside the [-1,1]
NDC cube which can be limiting for unbounded outdoor scenes where representing distant background is important.
To help representing the background, Lightplane supports two important tools: a) Disparity-space background ray-point sampling b) Coordinate contraction
Disparity-space background ray-point sampling
In order to render distant parts of the scene, inspired by NeRF++, Lightplane supports sampling of ray points beyond the far
plane with disparity spacing.
More specifically, Delta_i
defines the sample spacing of between the i
-th and i+1
-th 3d point far_pt_3d_i
beyond sampled beyond its ray’s far
ray-length as:
Delta_i = far / ((i + 1) * (disparity_at_inf - 1) / num_samples_inf + 1)
Here, num_samples_inf
corresponds to the total number of background ray-points and disparity_at_inf
is a small constant defining the disparity of the last sample along the ray.
For illustration, the following plots the ray-length r_i = sum(delta_0, ..., delta_N, Delta_0, ..., Delta_i)
as a function of the index i
of the point along the ray:
For the following settings: num_samples = num_samples_inf = 128, disparity_at_inf = 0.001, near = 0.1, far = 1.0
.
Note
The disparity-space sampling is enabled by setting num_samples_inf
in LightplaneRenderer
to an integer value > 0.
Coordinate contraction
Disparity-space sampling alone is inefficient for modelling distant space because the grid-list represents only the space within the [-1,1]
cube.
To deal with the latter, following MERF, we allow the box-based coordinate contraction function which ensures that any finite 3D point pt_3d
lands lands within the [-1, 1]
cube:
0.5 * pt_3d[k] if |pt_3d|_inf <= 1
contract(pt_3d)[k] = 0.5 * pt_3d[k] / |pt_3d|_inf if pt_3d[k] != |pt_3d|_inf > 1
0.5 * (2 - 1/pt_3d[k]) pt_3d[k] / |pt_3d[k]| if pt_3d[k] = |pt_3d|_inf > 1
where k in [0, 1, 2]
is the coordinate index.
When coordinate contraction is enabled, it is applied to the ray-point before just before sampling features from the grid-list:
pt_3d = contract(origin + t * direction)
Note
Coordinate contraction is enabled by setting contract_coords
in LightplaneRenderer
to True