Skip to content

From NeRF to Surf

NeuS

S density function

Propose to use a S-density function (Derivative of Sigmoid):

ϕs(x)=sesx(1+sesx)2

S_density

Note the std is given by 1/s, which would approaches to 0 as the training convergences. That is to say, the function will be more concentrated to surface point.

import numpy as np
import matplotlib.pyplot as plt
def s_density(x,s=1):
    return s*np.exp(-s*x)/(1+np.exp(-s*x))**2

s_vals = np.linspace(0, 10, 200)
sdf_vals = np.linspace(-5, 5, 200)

sdf_grid, s_grid  = np.meshgrid(sdf_vals, s_vals)
heat = s_density(sdf_grid, s_grid)

plt.imshow(heat, cmap="hot", extent=[sdf_vals[0], sdf_vals[-1], s_vals[-1], s_vals[0]])
plt.xlabel("SDF")
plt.ylabel("s")

Naive solution for S density

Set σ in NeRF as S-density, and result in biased solution...

naive

(Note: t is surface, f(t) is a SDF function, σ(t) is now set to be S-density function, w(t) is the weight function for rendering)

Proposed method

Propose a weight function as follows:

w(t)=ϕs(f(p(t)))0ϕs(f(p(u)))du

The problem of this weight function is that it is not occlusion aware... (This is similar to Neural RGBD weight function). Thus, NeuS proposes to get the weight function in a similar way to NeRF (NeRF's alpha compositing is actually occulusion-aware):

w(t)=T(t)ρ(t),whereT(t)=exp(0tρ(u)du).

How to get ρ?

We can firstly get sdf function

f(p(t))=|cos(θ)|(tt)

Then, the weight function can be rewritten as:

w(t)=ϕs(f(p(t)))ϕs(f(p(u)))du=ϕs(f(p(t)))ϕs(|cosθ|(ut))du=ϕs(f(p(t)))|cosθ|1ϕs(ut)du=|cosθ|ϕs(f(p(t)))=T(t)ρ(t)=dTdt(t).

Note that:

|cosθ|ϕs(f(p(t)))=dΦsdt(f(p(t)))=dTdt(t)

We can get

$$ T(t) = \Phi_s(f(\mathbf{p}(t))) $$ Then we get ρ(t):

tρ(u)du=ln(Φs(f(p(t))))ρ(t)=dΦsdt(f(p(t)))Φs(f(p(t)))

For multiple surface intersection, f(p(t)) might be smaller than 0, then, we need clip it:

ρ(t)=max(dΦsdt(f(p(t)))Φs(f(p(t))),0)

VolSDF

Transformed learnable SDF

Propose to model the density using a transformed learnable SDF:

Ψβ(s)={12exp(sβ) if s0112exp(sβ) if s>0

SDF_density

UniSurf

Unifying Surface and Volume Rendering

The rendering equation of NeRF can be written as:

C^(r)=i=1Nα(xi)j<i(1α(xj))c(xi,d)

UniSurf re-write the equation as:

C^(r)=i=1No(xi)j<i(1o(xj))c(xi,d),

where o(xi) is a continous occupancy function parameterized with an MLP.

Reference

[NeurIPS'21] NeuS: NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction

[NeurIPS'21] VolSDF: Volume Rendering of Neural Implicit Surfaces

[ICCV'21] UNISURF: Unifying Neural Implicit Surfaces and Radiance Fields for Multi-View Reconstruction