论文阅读:3D Gaussian Splatting for Real-Time Radiance Field Rendering

论文地址:https://arxiv.org/abs/2308.04079

代码地址:graphdeco-inria/gaussian-splatting: Original reference implementation of "3D Gaussian Splatting for Real-Time Radiance Field Rendering" (github.com)


概要

提出一个实时且能够高质量渲染场景的方法,通过结合离散和连续表示方法的优势,不仅克服了传统方法在噪声和渲染质量方面的限制,而且极大地提高了渲染速度。

辐射场:辐射场是三维空间中光分布的表示,它捕捉光如何与环境中的表面和材料相互作用。

显式辐射场:相反,显式辐射场直接表示离散空间结构中的光分布,

隐式辐射场:隐式辐射场表示场景中的光分布,而不明确定义场景的几何体。
      显式表达方法(点、网格、体素)的连续性质有助于优化,但渲染所需的随机采样成本高昂,并且可能会导致噪声。隐式表达(NeRF)耗费计算资源巨大,运行速度慢。3D GS 表示从隐式辐射场到显式辐射场的转变。它通过利用3D高斯作为灵活高效的表示,利用了这两种方法的优势。

Motivation

  • 引入各向异性3D高斯球作为辐射场的高质量、非结构化表示。
  • 一种3D高斯属性的优化方法,与自适应密度控制交织在一起,为捕获的场景创建高质量的表示。
  • 一种适用于GPU的快速可微渲染器。

系统框架

本论文的核心在于3D高斯函数的场景表达方式以及快速渲染的方法。3D高斯的表达方式能够准确、紧凑、可微地表达三维场景。而基于分块的快速渲染方法保证了渲染质量的同时提高了训练和渲染速度。给定输入:经过SFM 校准后的图像以及SFM输出的稀疏点云。该方法整体如下图所示:首先从SFM得到的稀疏点云构建三维高斯函数,在训练过程中通过可微的快速渲染器对3D高斯函数的属性进行优化,并交替进行自适应密度控制。

输入:点云
输出:渲染图像

  • 从初始的sfm点云出发,以每个点为中心生成3DGS。

  • 用相机参数把点投影到图像平面上(splatting)。

  • 从splatting的痕迹中tile-based光栅化,得到渲染图像,将渲染图像和GT求LOSS,反向传播。

  • 自适应的密度控制模块根据传递到点上的梯度,来决定是否需要对3DGS做分割或者克隆。梯度传递到3DGS里面对其存储的那几个参数进行更新。

技术细节

可微三维高斯表达方式

这一部分的目标是从无法向量先验的SFM点云中构建出可以渲染出高质量新视图的场景表达方式。

三维高斯的自适应密度优化

该方法的核心是优化过程的设计,除了优化三维高斯属性中的位置  、不透明度  以及协方差矩阵  外,还会优化  球谐系数以捕获视角相关的外观和颜色  。这些参数的优化与自适应密度控制交替进行。

最终的loss是通过二维图像计算得到的,而在三维投影到二维的过程中必然会产生歧义。因此本方法采用的三维高斯表达方式能够在网络的优化过程中能自适应的调整高斯核的数量,即自适应密度控制。

具体来说,这样一种自适应密度控制的方法能够识别出缺失几何特征的“未完全重建区域”以及高斯函数覆盖过广的“过度重建区域”。实验观察表明,出现这两种重建的错误的区域中,视图空间的位置梯度都很大,这是由于网络优化尝试移动高斯分布以纠正这种情况。这也就为识别这些重建错误的区域提供了便利,该方法将位置梯度阈值  设为0.0002,下图3是该方法针对这两种情况作出的不同处理的示意图:

首先,对于“未完全重建区域”,我们需要覆盖3D高斯到需要重建的几何处。因此该论文中采用的方法是将原有的3D高斯克隆一份相同大小的,并沿位置梯度方向移动到新的位置。其次,对于“过度重建区域”,该论文中采用的方法是将过大的3D高斯分解为两个小的,缩小幅度  为1.6,同时使用原有3D高斯的PDF来进行采样初始化新3D高斯的位置。

为了防止产生过量的3D高斯以及floater,本论文中还采用周期性重置不透明度  为零以及移除较大的3D高斯用于避免重叠。

用于三维高斯的快速可微光栅化

为了实现高效的高斯函数光栅化和渲染,该论文提出了一种基于瓦片的光栅化器,主要包括以下几个步骤和特点:

1. 瓦片划分与高斯剔除

  • 将屏幕划分为16x16的区域(瓦片),然后在每个区域内进行高斯剔除。
  • 剔除的原则是只保留那些与视锥体内相交,且置信度达到99%的高斯函数,这样避免了不必要的计算。
  • 引入了保护带(guard band),用于剔除处于极端位置、不必要的3D高斯函数,进一步提升剔除效率。

2. 排序与实例化

  • 剩余的高斯函数依据它们覆盖的区域数量实例化,每个实例被分配了一个“键值”(key),该键值包含视图空间中的深度信息以及瓦片区域的ID。
  • 使用快速的GPU基数排序算法对这些高斯函数进行排序,这一操作确保渲染过程中从前至后处理更为有效。

3. 区域列表与线程并行

  • 排序完成后,为每个瓦片区域分配一个列表,列表包含了按深度排序的高斯函数的第一个和最后一个条目。
  • 在光栅化阶段,每个区域启动一个GPU线程块,首先将对应高斯函数的数据加载到GPU共享内存中。
  • 线程块通过从前到后遍历高斯函数列表,为像素累积颜色和不透明度值,并在像素达到目标饱和度时停止相应的线程,从而提高并行处理效率。

4. 高效的梯度计算

  • 论文还提出了一种新的反向传播中高效计算梯度的方法。
  • 在前向过程中,只需存储每个点累积的总透明度 α\alphaα,而不是每个点的具体α\alphaα值。
  • 在反向传播过程中,通过将该点的总透明度除以每个点的透明度来计算梯度系数,从而减少了内存消耗和计算复杂度。

小结

总共13个真实场景上测试了算法,这些场景取自以前发布的数据集和合成的Blender数据集。特别是,在Mip-Nerf360 [Barron 2022] (NeRF渲染质量目前处于最先进水平)中提出的全场景、来自坦克和寺庙数据集的两个场景[Knapitsch 2017]和深度融合[Hedman 2018]提供的两个场景上测试了所提出方法。

近年来,在计算机视觉和三维重建领域,NeRF受到了越来越广泛的关注。虽然NeRF能够渲染出高质量的图像,但受到神经网络训练速度以及体渲染速度的限制。这类方法经常会面临速度和质量的抉择难题,同时渲染的实时性也是个限制NeRF使用扩展的重大问题。本工作首先基于SFM的点云设计了能快速精确表达场景的3D高斯函数,并以此开发了可由CUDA加速的渲染算法,实现了辐射场的实时渲染。这是其他基于点云的NeRF类方法无法做到的。

该工作兼具高效与质量的优越性,在未来结合该3D高斯表示形式,可以进一步用运在动态场景、三维生成以及SLAM-based的NeRF运用场景中。

<think>好的,我现在需要帮助用户解决他们在Unity中加载并渲染由3D Gaussian Splatting训练输出的PLY文件的问题。用户之前已经按照之前的指南操作,但可能遇到了问题,因为这种PLY文件与普通的结构不同。 首先,我需要确认用户提到的3D Gaussian Splatting生成的PLY文件有什么不同。通常,传统的PLY文件包含顶点、面片等数据,而Gaussian Splatting可能使用点云数据,每个点可能有额外的属性,如颜色、法线、协方差矩阵或其他用于渲染的参数。这些属性可能在标准的PLY解析库(如PlyRuntimeImporter)中无法正确处理,导致加载失败或渲染不正确。 用户可能已经尝试使用之前的代码,但发现模型无法正确显示,或者材质效果不符合预期。他们需要一种方法来解析这些特殊的PLY文件,并将其渲染为Gaussian Splats,这可能涉及到自定义着色器或使用点云渲染技术。 接下来,我需要考虑如何在Unity中处理这种数据。可能需要以下几个步骤: 1. **解析PLY文件**:因为标准库可能不支持这些额外属性,需要自定义解析器来读取Gaussian Splatting的特定数据,如位置、颜色、协方差等。 2. **数据结构转换**:将解析后的数据转换为Unity可以处理的格式,例如点云数据,可能需要生成自定义的Mesh或使用粒子系统。 3. **渲染方法**:Gaussian Splats通常需要特殊的渲染技术,如使用片元着色器来模拟高斯分布的外观。这可能需要编写自定义的Shader,或者在Unity中使用计算着色器进行高效渲染。 4. **性能优化**:考虑到HoloLens 2的硬件限制,需要确保渲染方法在移动设备上高效运行,可能需要简化数据或使用LOD(细节层次)技术。 另外,用户可能需要参考3D Gaussian Splatting的相关论文或文档,了解其数据结构和渲染方法,以确保正确解析和渲染。例如,Gaussian Splatting的每个点可能包含位置、颜色(RGB)、不透明度(alpha)、缩放(scale)、旋转(rotation)和协方差矩阵(covariance)等信息,这些都需要在解析时提取出来。 在实现过程中,可能会遇到以下问题: - **PLY文件格式差异**:Gaussian Splatting的PLY文件可能有不同的头信息或数据排列方式,需要仔细检查文件结构,可能需要手动解析或调整现有的解析器。 - **着色器编写复杂性**:实现高斯泼溅的渲染效果需要高级的Shader编程,可能需要参考现有的实现或论文中的方法。 - **性能问题**:在HoloLens 2上实时渲染大量高斯点可能对性能有较高要求,需要考虑数据简化或优化渲染管线。 用户可能需要使用Unity的Compute Shader来处理大量的点数据,或者使用GPU Instancing来高效渲染每个高斯点。此外,可能还需要将数据转换为纹理或缓冲区,以便在Shader中高效访问。 最后,需要确保部署到HoloLens 2时,所有的设置(如UWP功能、空间感知权限等)都正确配置,并且渲染效果在设备上能够正确显示,同时保持流畅的性能。</think>以下是针对 **3D Gaussian Splatting 输出的PLY文件** 在Unity中的加载与渲染的详细解决方案。由于此类PLY文件包含高斯泼溅(Gaussian Splatting)特有的数据(如协方差矩阵、球谐系数等),需特殊处理才能正确渲染。 --- ### **一、3D Gaussian Splatting的PLY文件特点** - **数据结构差异**: - 每个“点”代表一个高斯椭球体。 - 包含以下关键属性(以[官方格式](https://github.com/graphdeco-inria/gaussian-splatting)为例): ```properties x, y, z // 位置 nx, ny, nz // 法线(可能未使用) f_dc_0, f_dc_1, f_dc_2 // 球谐系数(颜色) opacity // 不透明度 scale_0, scale_1, scale_2 // 各向异性缩放 rot_0, rot_1, rot_2, rot_3 // 旋转四元数 ``` - 传统PLY解析库无法直接读取这些属性,需自定义解析逻辑。 --- ### **二、实现步骤** #### 1. **自定义PLY解析脚本** 需手动解析二进制PLY文件,提取高斯泼溅参数。以下为简化版代码框架: ```csharp using System.IO; using UnityEngine; public class GaussianSplatLoader : MonoBehaviour { public string plyFilePath = "point_cloud.ply"; void Start() { string path = Path.Combine(Application.streamingAssetsPath, plyFilePath); byte[] data = File.ReadAllBytes(path); // 解析PLY头信息 int vertexCount = ParseHeader(data); // 解析顶点数据(二进制小端格式) int offset = FindDataOffset(data); for (int i = 0; i < vertexCount; i++) { // 解析位置(float32 x 3) Vector3 pos = new Vector3( System.BitConverter.ToSingle(data, offset), System.BitConverter.ToSingle(data, offset + 4), System.BitConverter.ToSingle(data, offset + 8) ); offset += 12; // 解析法线(跳过) offset += 12; // 解析球谐系数(float32 x 3) Vector3 shCoeff = new Vector3( System.BitConverter.ToSingle(data, offset), System.BitConverter.ToSingle(data, offset + 4), System.BitConverter.ToSingle(data, offset + 8) ); offset += 12; // 解析不透明度(float32) float opacity = System.BitConverter.ToSingle(data, offset); offset += 4; // 解析缩放(float32 x 3) Vector3 scale = new Vector3( System.BitConverter.ToSingle(data, offset), System.BitConverter.ToSingle(data, offset + 4), System.BitConverter.ToSingle(data, offset + 8) ); offset += 12; // 解析旋转四元数(float32 x 4) Quaternion rot = new Quaternion( System.BitConverter.ToSingle(data, offset), System.BitConverter.ToSingle(data, offset + 4), System.BitConverter.ToSingle(data, offset + 8), System.BitConverter.ToSingle(data, offset + 12) ); offset += 16; // 创建高斯点对象 CreateGaussianSplat(pos, rot, scale, shCoeff, opacity); } } int ParseHeader(byte[] data) { /* 解析PLY头,返回顶点数量 */ } int FindDataOffset(byte[] data) { /* 找到二进制数据起始位置 */ } void CreateGaussianSplat(Vector3 pos, Quaternion rot, Vector3 scale, Vector3 color, float opacity) { // 此处需实现高斯泼溅的渲染逻辑(见下一步) } } ``` --- #### 2. **实现高斯泼溅渲染** 传统网格渲染无法直接表现高斯椭球,需通过**自定义Shader**模拟其效果。以下是关键思路: ##### **方案一:基于Compute Shader的GPU渲染** 1. **将数据传入Compute Buffer**: ```csharp // 在CreateGaussianSplat中收集所有高斯点数据 List<GaussianData> gaussianList = new List<GaussianData>(); void CreateGaussianSplat(...) { gaussianList.Add(new GaussianData(pos, rot, scale, color, opacity)); } // 最终将数据传入GPU ComputeBuffer buffer = new ComputeBuffer(gaussianList.Count, sizeof(float) * 16); buffer.SetData(gaussianList.ToArray()); ``` 2. **编写Compute Shader**: ```hlsl // GaussianSplat.compute #pragma kernel CSMain RWStructuredBuffer<float4x4> _GaussianBuffer; float4x4 _ViewProjMatrix; [numthreads(64,1,1)] void CSMain (uint3 id : SV_DispatchThreadID) { // 读取高斯参数,计算投影后的椭球方程 // 生成覆盖椭球的屏幕空间四边形(Billboard) } ``` 3. **顶点/片元着色器**: ```hlsl // 根据椭球参数计算颜色与透明度 float4 frag (v2f i) : SV_Target { // 计算当前像素到高斯中心的距离,结合协方差矩阵 // 使用球谐系数计算颜色,混合透明度 } ``` ##### **方案二:使用粒子系统近似模拟** 若无需严格物理正确性,可简化为粒子+动态缩放: ```csharp // 在CreateGaussianSplat中生成粒子 void CreateGaussianSplat(...) { GameObject particle = new GameObject("Splat"); particle.transform.position = pos; particle.transform.rotation = rot; particle.transform.localScale = scale; var renderer = particle.AddComponent<SpriteRenderer>(); renderer.sprite = Resources.Load<Sprite>("GaussianSprite"); renderer.material.SetVector("_Color", color); renderer.material.SetFloat("_Opacity", opacity); } ``` --- ### **三、HoloLens 2部署优化** 1. **性能关键点**: - **减少Draw Call**:使用GPU Instancing合并渲染。 - **LOD优化**:根据距离动态调整渲染精度。 - **剔除不可见点**:基于空间映射数据剔除被遮挡的高斯点。 2. **Shader适配**: - 在OpenXR中启用**单通道立体渲染**(Single Pass Instanced)。 - 使用HoloLens推荐的**Unlit Shader模板**,避免复杂光照计算。 3. **空间锚定**: ```csharp // 使用MRTK的SpatialAnchor using Microsoft.MixedReality.Toolkit; using Microsoft.MixedReality.Toolkit.SpatialManipulation; void AnchorModel() { var anchor = gameObject.AddComponent<SpatialAnchor>(); anchor.LocalOffset = transform.localPosition; } ``` --- ### **四、完整工作流程** 1. **导出PLY文件**: - 确保从3D Gaussian Splatting训练中导出**二进制PLY格式**(非ASCII)。 2. **Unity预处理**: - 将PLY文件放入 `StreamingAssets`,使用自定义解析器加载。 - 按需简化数据量(如剔除低`opacity`点)。 3. **部署到设备**: - 按照常规HoloLens 2部署流程,需特别注意: - 在Player Settings中启用**InternetClientServer**与**SpatialPerception**。 - 若使用Compute Shader,检查OpenXR插件是否兼容。 --- ### **五、参考资源** 1. **3D Gaussian Splatting原始论文**: [“3D Gaussian Splatting for Real-Time Radiance Field Rendering”](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) 2. **Unity DOTS高性能渲染**: 结合Entities Graphics实现大规模点云渲染。 3. **HoloLens着色器优化指南**: [MRTK Shaders](https://learn.microsoft.com/en-us/windows/mixed-reality/mrtk-unity/performance/shader-recommendations) --- 通过上述方法,你可以将3D Gaussian Splatting的输出结果准确呈现在HoloLens 2中。若需进一步交互(如手势调整渲染参数),可结合MRTK的**HandInteractionExamples**模块实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值