NGP(Neural Graphics Primitives)是一种基于神经网络的图形基元,使用全连接的神经网络进行参数化,其训练和评估成本可能很高。
作者提出了一种多分辨率哈希编码方法,该编码具有自适应性和高效性的特点,可用于改善神经网络输入以提高近似质量和训练速度。多分辨率结构允许网络消除哈希冲突的歧义,从而形成一个简单的架构,可以在现代 GPU 上并行化。
作者将多分辨率哈希编码应用到全融合的CUDA内核,使得NGP得以利用其并行性,从而减小带宽和计算上的浪费。最终能够在几秒钟内训练得到高质量的NGP,并在数十毫秒内以1920x1080的分辨率进行渲染,故称Instant-NGP。
多分辨率哈希编码(Multiresolution Hash Encoding)具有自适应和高效的特点:
具体实现原理如下:
作者在CUDA中实现该多分辨率哈希编码,将其与tiny-cuda-nn框架的快速完全融合的MLP相结合,下面是一些具体实现细节:
通过这种实现和优化,多分辨率哈希编码在CUDA中获得了高效的性能和较低的开销。
如果读者使用的是Windows环境,可根据自己的显卡直接下载下面的发行版:
如果读者使用的是Linux环境,抑或是想通过Python bindings进行更多对照实验,则需要自己构建Instant-NGP,下面是构建的过程:
读者首先要确保已配备英伟达显卡,并自行配置满足上述版本要求的C++14编译器和CMake工具,以及CUDA工具包(建议安装在/usr/local
下)。
若使用基于 Debian 的 Linux 发行版(如Ubuntu),安装以下依赖包:
sudo apt-get install build-essential git python3-dev python3-pip libopenexr-dev libxi-dev libglfw3-dev libglew-dev libomp-dev libxinerama-dev libxcursor-dev
若使用 Arch 相关的Linux环境,安装以下依赖包:
sudo pacman -S cuda base-devel cmake openexr libxi glfw openmp libxinerama libxcursor
官方建议将CUDA安装到/usr/local
目录下并配置环境变量。例如,如果已经在/usr/local
下安装了CUDA11.4,编辑~/.bashrc
文件,添加以下代码,重启终端或使用source ~/.bashrc
命令使之生效。
export PATH="/usr/local/cuda-11.4/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH"
正确配置后,在命令行输入nvcc --version
应当正常输出cuda工具包的版本信息。
下载附件压缩包
重要说明.txt
文档中的链接,下载dependencies
并解压到项目根目录使用CMake构建项目
cmake . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build --config RelWithDebInfo -j
可直接启动可执行文件
./instant-ngp
先使用conda创建并配置虚拟环境
# 创建虚拟环境(python版本>=3.7)
conda create --name instant-ngp python=3.7
# 激活环境
conda activate instant-ngp
# 安装最新版的pip工具
conda install pip
pip install --upgrade pip
# 使用pip安装依赖库
pip install -r requirements.txt
启动项目
python scripts/run.py
W
S
A
D
在场景中前后左右移动,space
(空格)和c
分别实现上升和下降其他快捷键可查阅README.md
文档
项目源码中已经有data
文件夹,其中包括了三种类型的文件:
exr格式的image文件
.exr格式的文件常用于制作贴图,用图片来实现动态的3D效果。 想要了解更多,可以阅读本文:EXR贴图究竟有多牛B?将要颠覆整个CG绘图行业! - 知乎 (zhihu.com)
我们只需要将.exr
格式文件拖入窗口内,或者在启动时带上文件路径(如下)即可。
./instant-ngp data/image/albert.exr
sdf文件
sdf(signed distance field)即符号距离场,通过记录每个点到模型边界的距离,在模型内侧的点数值为负,外侧的点数值为正,在边界上的点数值为0,所有距离为0的点构成了模型的表面,从而可以表示出一个2D或3D模型。 想要了解更多,可以阅读本文:SDF(signed distance field)基础理论和计算 - 知乎 (zhihu.com)
只需将sdf
文件夹下的.obj
格式的文件拖入到窗口中,或者在启动时带上文件路径(如下)即可。
./instant-ngp data/sdf/armadillo.obj
nerf模型
NeRF(Neural Radiance Fields)即神经辐射场,基于神经网络构建一个连续的5D函数来表示3D场景,并使用少量的输入视图来优化这个函数以生成复杂场景的新视角。 上一期我介绍了一种mip-NeRF模型,就是对NeRF的一种改进,有兴趣的可以阅读本文:【mip-NeRF】使用一组二维图像渲染3D场景视频(mip-NeRF论文复现)-CSDN博客
只需将nerf
文件夹下的场景文件夹(如fox
场景)拖入窗口内,或在启动时带上场景目录路径(如下)即可。
./instant-ngp data/nerf/fox
渲染效果图(在RTX 4090显卡上):
image(albert.exr) | SDF模型(armadillo.obj) | nerf模型(fox) |
---|---|---|
| | |
如果读者有自己的NeRF数据集,也可以使用Instant-NGP进行快速渲染,例如我们可以使用谷歌最原始的NeRF数据集,对lego
,chair
,hotdog
这三个场景进行,下载数据集后,将场景文件夹拖入到窗口内即可。下面是渲染效果图:
lego场景 | chair场景 | hotdog场景 |
---|---|---|
| | |
NeRF数据集通常由一组图片和对应的相机位姿(通常存储在transforms.json
文件中)组成。想要制作一组NeRF数据集有很多方法,通常需要一些专业的相机设备。
但是,如果你是ios用户,那幸运的是,你可以从苹果app store下载一个叫NeRF Capture
的app(不清楚安卓是否有类似的app),它可以将图像及坐标(大概用到了ARKit)传输给Instant-NGP,并通过Instant-NGP提供的脚本快速制作NeRF数据集。
操作说明如下:
首先需要安装下面的依赖
pip install cyclonedds
用流(stream)传输
打开 NeRF Capture
app
运行python脚本(启用stream模式)
python scripts/nerfcapture2nerf.py --stream
等待app与脚本连接,这会在app上显示
在app上点击 send
按钮,捕获到的场景将会发送到Instant-NGP
开始训练
保存数据集
打开 NeRF Capture
app
运行python脚本,--save_path
指定保存路径,n_frames
指定保存数据集前要捕获多少帧
python scripts/nerfcapture2nerf.py --save_path "dir1/dir2" --n_frames 20
等待app与脚本连接,这会在app上显示
在app上点击 send
按钮,捕获到的场景将会保存到指定的目录
论文主要提出了一种多分辨率哈希编码,优化了NGP的输入特征编码,并将其融合CUDA内核进行实现,可以适应图像、模型、NeRF等多种场景的渲染。通过复现实验,Instant-NGP的收敛速度之快、渲染质量之高不禁令人称奇!但是Hash编码是一种以空间换时间的数据结构,因此这种方法对显存的要求也比较高。
论文地址:[2201.05989] Instant Neural Graphics Primitives with a Multiresolution Hash Encoding (arxiv.org)
希望对你有帮助!加油!
若您认为本文内容有益,请不吝赐予赞同并订阅,以便持续接收有价值的信息。衷心感谢您的关注和支持!