渲染 | Gaussian Splatting 源码解析

❗️此坑还没填完

TODO: GS 组成

  • point cloud
  • render flow
  • optimize

仓库结构

仓库由 C++/CUDA 和 Python 组成,CUDA 包括 diff-rasterization ,Python 包括 optimize 。CUDA 部分依赖 glm ,只用了 glm 的 vector 数据类型。

Rendering (C++/CUDA Part)

Python-CUDA 接口

CUDA 向 Python 暴露的就三个方法,rasterize_gaussians , rasterize_gaussians_backwardmark_visible 。 Python 再包装上 torch.autograd.Function ,最后以 GaussianRasterizerGaussianRasterizationSettings 这俩个接口。

Python 和 CUDA 映射如下:

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
  m.def("rasterize_gaussians", &RasterizeGaussiansCUDA);
  m.def("rasterize_gaussians_backward", &RasterizeGaussiansBackwardCUDA);
  m.def("mark_visible", &markVisible);
}

Frustum Culling

相关定义主要在 cuda_rasterizer/auxiliary.h in_frustum()

做俩次变换投影到 ImageSpace,比较深度(z 坐标),这里的 z 值是到相机原点平面的深度,在屏幕平面后的点舍弃(z<0.2)。

函数中注释了对 x 和 y 方向的判断,因为 Gaussian Splatting 严格是无限大,和传统 culling Frustum 不太一样。 需要通过置信度阈值来筛选置信度,不能简单地通过投影后的二维距离来判断。

不过 mark visible 似乎根本就没有调用?

Chunk Management

相关定义主要在 cuda_rasterizer\rasterizer_impl.h

把内存按切分成一个个 chunk(内存块),每个 chunk的第一个地址是起始地址,起始地址都是对齐的。比如按 16 字节切分,起始地址就是 0x00, 0x10, 0x20 ... ;0x00~0x0F ,0x10~0x1F ,0x20~0x2F 是切好的一个个 chunk,chunk 也可以用起始地址标识。

下面方法先获取指针所指位置 chunk(起始地址/对齐地址),再在起始地址上偏移相应元素得到新地址,是一个多对一的函数映射。

static void obtain(char*& chunk, T*& ptr, std::size_t count, std::size_t alignment)
{
    std::size_t offset = (reinterpret_cast<std::uintptr_t>(chunk) + alignment - 1) & ~(alignment - 1);
    ptr = reinterpret_cast<T*>(offset);
    chunk = reinterpret_cast<char*>(ptr + count);
}

diff GS Chunk 内管理着三种 buffer 数据 :GeometryState, ImageState, BinningState,都以 128 字节作为 chunk size 切割分块。

  • GeometryState 点云的基本信息,位置(means2D)、协方差(cov)、颜色(rgb)、透明度(conic_opacity)等(这个似乎是投影过后的)
  • ImageState 渲染到图像上的数据,主要是存储渲染过程中的 partial sum
  • BinningState 用来管理点云列表排序

通过 fromChunk() 从统一的 chunk 获取对应的 strut 实例。

Forward

Gaussian Splatting 表示

类似 NeRF,GS 的 color 是 view-denpendence 的,和观察的视角有关。也就是一个视角到 Color 的函数映射。NeRF 使用神经网络表示该函数;GS 是 pure explict 结构,采用球谐函数表示。

preprocess

TODO

Optimize (Python Part)

相关定义主要在 train.py

  • Densification
    • Split
    • Clone
  • Opacity Reset

默认训练超参数如下:

Params Value
iterations 30k
densify_until_iter 15k
densify_from_iter 0.5k
densification_interval 0.1k
opacity_reset_interval 3k

分阶段优化方案

  • 0 只优化 GS 的参数
  • desinify_until_iter ~ densify_until_iter,优化 GS 的参数和数量
    • 每 densification_interval 优化数量
    • 每 opacity_reset_interval 重置透明度上限(如果开启 white background 则每 iter 都会重置透明度上限)
  • densify_until_iter ~ iterations,只优化 GS 的参数

Split & Clone

TODO

Reset Opacity

相关文件 scene\gaussian_model.py reset_opacity()

将 Opacity clamp 到 \((-\infty, 0.01)\)

posted @ 2024-04-23 16:47  DevilXXL  阅读(528)  评论(0编辑  收藏  举报