分块优化:包围盒与 Tile 划分
在 3D 图形学和高斯溅射(Gaussian Splatting)中,为了提高渲染和计算的效率,我们需要将连续的像素空间离散化。这篇文章的核心,就是带你搞懂如何为每一个高斯(Gaussian)计算包围盒,并将其映射到屏幕的网格(Tile)中。
从像素空间跨入 Tile(瓦片)空间
现在,我们手头已经有了高斯在像素空间(Pixel Space)下的边界坐标(比如
如何将像素坐标转换为 Tile 索引?代码非常直观:
- # 从像素坐标转换到 Tile 索引并转换为 int64
- u_min_tile = (u_min / tile_size).to(torch.int64)
- u_max_tile = (u_max / tile_size).to(torch.int64)
- v_min_tile = (v_min / tile_size).to(torch.int64)
- v_max_tile = (v_max / tile_size).to(torch.int64)
计算每个高斯相交的 Tile 数量
知道了每个高斯起点和终点所在的 Tile 索引后,我们需要计算这个高斯到底跨越了几个 Tile。
- # 计算每个高斯在水平(u)和垂直(v)方向跨越的 Tile 数量 (+1 避免 Fencepost 误差)
- n_u = u_max_tile - u_min_tile + 1
- n_v = v_max_tile - v_min_tile + 1
获取全局最大跨度
为了后续能够在显存中分配合适大小的数据结构,我们需要知道在所有的被渲染的高斯中,单个高斯最多能跨越多少个 Tile。
- # 获取全局单个高斯跨越的最大 Tile 数 (用于统计或后续阶段验证)
- nu_max_item = int(n_u.max().item())
- nv_max_item = int(n_v.max().item())