Encodings

Multiresolution Hash Encoding

GridEncoding implements Multiresolution Hash Encoding which can be used to encode 3D points prior to MLP.

Instantiate ge = GridEncoding(Backend) with a supported backend. GridEncoding handles its parameters explicitly, meaning it is up to the user to initialize and maintain them with θ = NerfUtils.init(ge).

To encode input coordinates x pass them along with the parameters θ:

# Random 3D points on the same `Backend`.
x = adapt(Backend, rand(Float32, 3, N))
y = ge(x, θ)

Note, that inputs must be in [0, 1] range, otherwise the kernel might break. GridEncoding does not check input values.

Computing gradients

GridEncoding defines respective chain rules for its kernels using ChainRules.jl package, meaning it supports any AD that works with them. Following examples use Zygote.jl for that.

Compute gradients w.r.t. θ:

∇ = Zygote.gradient(θ) do θ # Passing θ explicitly to the `gradient` function.
    sum(ge(x, θ))
end

To compute gradients w.r.t. θ and input x you have to pass additional input argument IG:

∇ = Zygote.gradient(x, θ) do x, θ
    sum(ge(x, θ, IG))
end
∇[1] # Gradient w.r.t. x.
∇[2] # Gradient w.r.t. θ.

It is done this way to dispatch to a different kernel that in the forward pass precomputes necessary values for the backward pass to speed things up.

See GridEncoding docs for the description of each argument during instantiation as you might want to configure number of levels, their resolution and feature dimensions.

NerfUtils.GridEncodingType
function GridEncoding(
    kab; n_dims::Int = 3, n_levels::Int = 16, scale::Float32 = 1.5f0,
    base_resolution::Int = 16, n_features::Int = 2, hashmap_size::Int = 19,
    align_corners::Bool = true, store_level_ids::Bool = false)

Multiresolution Hash Encoding

Arguments:

  • kab: Backend on which to instantiate GridEncoding.
  • n_dims::Int: Number of input dimensions (e.g. for 3D points it must be 3).
  • n_levels::Int: Number of levels in the grid. Higher number of levels results in better accuracy at the expense of device memory.
  • scale::Float32: By how much to scale each next level in size.
  • base_resolution::Int: Initial resolution (1st level).
  • n_features::Int: Size of the features at each level.
  • hashmap_size::Int: log₂ size of the level at which it will switch from one-to-one mapping to hashing.
  • align_corners::Bool: If true then grid corners when scaling inputs to a respective level resolution.
  • store_level_ids::Bool: If true GridEncoding will store mapping id from each feature to its level in the grid. This allows implementing GridEncoding parameter decay as mean(scatter(mean, θ.^2, level_ids)). Indices are stored in Int8 type to reduce memory usage.

Reference:

https://nvlabs.github.io/instant-ngp/

source