90 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Untitled
date: 2024-01-01 18:57:57
excerpt:
tags:
rating: ⭐
---
# 前言
- https://github.com/graphdeco-inria/gaussian-splatting/tree/main/gaussian_renderer
基于Sibr渲染器制作的3D高斯查看器。
# 项目结构
- [x] gaussian
- render - sibr_gaussian
- apps - SIBR_gaussianViewer_app
- [ ] diff-gaussian-rasterization(CUDA)
# render - sibr_gaussian
- picojsonJSON库
- rapidxmlXML库
- **nanoflann**是一个c++11标准库用于构建具有不同拓扑R2R3点云SO(2)和SO(3)2D和3D旋转组的KD树。
## GaussianSurfaceRenderer
### GaussianData
- GaussianData()通过构造函数形参接受CPU端读取的高斯数据再通过调用glCreateBuffers()、glNamedBufferStorage()创建GL缓存对象并且初始化并使用GLuint进行记录index
- render给Shader绑定GL缓存并且绘制数组实例。
### GaussianSurfaceRenderer
- GaussianSurfaceRenderer():初始化相关变量。
- 初始化VS/Frag Shader。
- rayOrigin、MVP、alpha_limit、stage变量
- 创建idTexture、colorTexture贴图变量以及过滤器
- 创建fbo对象以及depthBuffer之后调用makeFBO()正式创建FBO
- 创建清屏Shader。
- makeFBX()创建idTexture、colorTexture、depthBuffer FBO用于将顶点数据传递到FragShader中。
- process():整个渲染过程逻辑处理。
1. 清屏。
2. 判断如果分辨率与FBO大小不同则重新创建FBO。
3. 获取绘制Buffer的Index调用glDrawBuffers() 绘制colorTexture、idTexture。
4. 开启深度测试关闭Blend模式。
5. 给Shader绑定相关`_paramMVP``_paramCamPos``_paramLimit``_paramStage`变量并且调用GaussianData.render()进行一次**不透明物体**的渲染。以小方盒的形式绘制点云数据。
6. 调用glDrawBuffers() 绘制colorTexture。
7. 关闭深度测试开启透明Blend模式。
8. GaussianData.render()进行一次**透明物体**的渲染,融合模式**additive blendnig**。以小方盒的形式绘制点云数据。
9. 开启深度测试关闭Blend模式。
10. 将结果显示在屏幕上?
## GaussianView
继承自sibr::ViewBase用与调用渲染器以及显示结果。
### GaussianView
- GaussianView()
- 初始化_pointbasedrenderer渲染器
- 初始化_copyRenderer渲染器
- 载入图片并且加入debug模式应该sibr自带的那个多视角图片debug模式
- 载入*.ply点云文件函数为loadPly()。
- CUDA相关处理应该是为了计算3D高斯结果所需的数据。
- 生成GaussianData指针变量gData。
- 初始化3D高斯渲染器对象_gaussianRenderer。
- 创建GL缓存对象imageBuffer。
- CUDA插值操作。
- 绑定3个geomBufferFunc、binningBufferFunc、imgBufferFunc仿函数。
- onRenderIBR()View的渲染函数。
- Ellipsoids椭圆体渲染使用_gaussianRenderer->process() 进行渲染。(OpenGL)
- Initial Points`_pointbasedrenderer->process()`渲染点。
- Splats使用CudaRasterizer::Rasterizer::forward()进行渲染。最后通过_copyRenderer->process()复制回imageBuffer缓存。
- onGUI()GUI相关逻辑。
CUDA文件位于`SIBR_viewers\extlibs\CudaRasterizer\CudaRasterizer\cuda_rasterizer\rasterizer_impl.cu`以及`forward.cu`,这些为核心逻辑。
## Shader
可以理解为将点云渲染成一个个的椭圆体,每个椭圆体的颜色与点云数据中的颜色相关。
### VertexShader
1. 取得IndexID。
2. 使用IndexID从传入Shader的Buffer中获取的椭圆体中心、alpha、ellipsoidScale、q四元数rotation之后将rotation转成3x3矩阵 ellipsoidRotation。
3. 取得当前顶点Index并获得坐标。再乘以椭圆体旋转值并加上椭圆体中心坐标取得最终的WorldPos当前顶点的世界坐标
4. 使用IndexID从传入Shader的Buffer中取得**辐射照度?辐射强度?** 数据。
5. 将不符合要求的顶点堆到vec4(0,0,0,0)点。
6. 输出顶点数据到FragShader。
### FragShader
1. 计算摄像机=>当前顶点世界坐标的方向向量dir。
2. 调用closestEllipsoidIntersection(),计算与椭圆体的相交的坐标与相交点的法线。
1. 计算椭圆体空间的localRayOrigin与localRayDirection
2. 计算椭圆与直线相交的方程。
3. 计算摄像机朝向的椭圆体的外表面。如果是内表面最终颜色值 * 0.4。
4. 将相交的世界坐标乘以MVP矩阵得到摄像机View坐标下的的世界坐标。
5. 计算深度缓存。
6. 计算Alpha。
7. 渲染`out_color = vec4(align * colorVert, a);` 也就是colorTexture
8. 渲染`out_id = boxID;`也就是idTexture
# apps - SIBR_gaussianViewer_app
调用`gaussianviewer/renderer/GaussianView.hpp`封装的App。