# ProbePlacement
**Repository Path**: hello_xiabo/ProbePlacement
## Basic Information
- **Project Name**: ProbePlacement
- **Description**: Probe Placement 是一种基于G3D的针对静态场景静态光源,预计算各辐照度探针位置以优化探针摆放,运行时通过四面体查找及插值来获得间接漫反射的全局光照算法
- **Primary Language**: C++
- **License**: GPL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 2
- **Created**: 2021-12-07
- **Last Updated**: 2024-03-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: IndirectLighting, Probe, Irradiance, Non-uniform, Tetrahedron
## README
# ProbePlacement
Probe Placement 是一种针对静态场景静态光源,根据梯度下降的思想,引入探针着色点的概念,通过衡量**辐照度误差**,**径向距离误差**,**阴影可见性误差**,来预计算各辐照度探针位置以优化探针摆放,并在新位置构建四面体结构。运行时通过快速的四面体查找及插值来获得间接漫反射的全局光照算法。
现因Gitee不支持LFS,新仓库地址[https://world-tree.coding.net/public/ProbePlacement/ProbePlacement/git/files](https://world-tree.coding.net/public/ProbePlacement/ProbePlacement/git/files)
## 算法介绍
基于探针的方法通常需要艺术家手动摆放探针,在引入**辐照度体积**后只用设置探针的范围和密度,操作大大减少。
然而,基于辐照度体积的方法只能相对均匀的摆放探针(例如DDGI只支持每Grid内局部偏移),均匀摆放会将部分探针放入物体内部,在着色时产生漏光或漏阴影等伪影。当遇到复杂场景和复杂光源条件时,均匀体积只能通过**提高分辨率**来获得更好的效果,而非均匀摆放只需要在变化剧烈的地方增大密度并选择更好的位置。
对于非均匀探针,因为无法编码在三维纹理内,不同与均匀探针的三线性插值,非均匀探针使用**四面体插值**方法。
为了使探针放在更好的位置,19年一篇[Fast non-uniform radiance probe placement and tracing](https://www.cim.mcgill.ca/~derek/files/NonUniformProbes-paper.pdf)探针摆放论文,通过非均匀摆放探针和相应的追踪方法获得更好的间接镜面反射。该方法首先提取场景骨架,然后通过场景可见性梯度下降来为每个探针获得更好的位置,最后引入了一种在八面体贴图中更好的光线步进方法以加速镜面反射计算。然而,他们想得到更好的**间接镜面反射**,虽然是预计算,即只适用于静态场景静态光源,却没有使用**光照信息(辐射亮度,辐照度)** 来辅助摆放。
21年有一篇[Illumination-driven Light Probe Placement](https://www.kostasvardis.com/files/research/idlp_eg_2021.pdf)论文使用了光照信息来摆放探针,他们通过设置期望保留数目,多次迭代评估当前贡献最小的探针将其直接丢弃,该算法不会改变任一探针的**初始位置**,局限太大,并且如果输入是均匀体积将在探针体积内产生空洞。
我们受到1992年一篇[Irradiance gradients](https://floyd.lbl.gov/radiance/papers/erw92/paper.pdf)论文的启发,该论文通过在光线追踪中,对每一光线样本记录额外信息来估计**辐照度梯度**,在不增加样本数量的情况下更好的进行辐照度插值,从而获得了更好的效果。我们在实现DDGI的渲染框架[G3D](https://casual-effects.com/g3d/www/index.html)上实现了非均匀探针的摆放。
## 基本思想
全局光照中间接漫反射部分可以通过将与光源无关的BRDF项(Albedo / Pi)移出积分,进而只计算半球空间内的辐照度(Irradiance)。通过在世界空间内摆放探针,记录探针位置每方向为法线的半球空间内的辐照度。在着色时找到能包围着色点的若干探针,通过插值来还原出着色点位置及法线可能具有的辐照度。
通过辐照度探针基本原理可得:
1. 探针在使用时仅用若干着色点附近的探针进行插值,虽然可以加入余弦项权重,通过VSM的思想加入可见性权重等,但仍然存在只要空间上的变化剧烈,就必须增加探针数量或缩小探针间间隔的问题。
2. 在使用探针类方法时,希望能尽量精准的代表周围会用到该探针着色的着色点,理想情况为场景大部分着色点接收的辐照度与探针中记录的辐照度差距很小,就能通过简单的插值还原出正确的光照信息。
3. 同时,加入全局光照主要为了照亮直接光照部分较弱或照不到的地方,使看起来很平的阴影部分得到间接光照,使接收强光的鲜艳物体周围产生渗色(Color Bleeding)效果。
根据以上原理,想要更好的表示场景及光照情况,最好能非均匀的摆放探针,想要获得观感良好的全局光照效果,最好能摆在需要的地方。
对输入的均匀或非均匀探针体积,限定每探针活动范围,在探针当前位置向场景通过球面斐波那契均匀采样若干采样点作为探针着色点,作为参考点集,根据**辐照度**,**径向距离**,**阴影可见性**,计算探针与若干着色点之间的误差,认为误差越小探针的表示越精准。再在空间中随机选取正交坐标系正负轴六个方向,分别做微小移动后计算新位置误差,来得到每轴误差的变化量,进而得到误差下降的空间梯度方向。在若干次迭代后或达到退出条件后将每探针移动到新的位置。移动完成后对于过于接近的探针,将根据场景可见性判断是否可以合并来将其合并。
辐照度作为最后使用的结果,探针中记录的辐照度信息需要尽量接近着色点,对探针位置和每着色点均通过蒙特卡洛采样计算辐照度。计算误差时会根据**辐照度差值相对比例**(避免绝对辐照度较小的区域其误差也会更小)及着色点与探针间的距离加权(越近的越需要精准表示)作为辐照度误差因子。
径向距离用来限制探针不会过于靠近物体表面,计算着色点集的**距离方差**。当探针靠近物体表面时,探针较大范围立体角内采样点会落在同一物体表面上,如果梯度方向指向该物体,则探针会朝向物体移动并可能进入物体内部。所以需要限制探针进入物体内部,同时使探针作用于更大范围的着色点,让探针更有用。
最后阴影可见性如字面意思,当能非均匀的摆放探针后,根据艺术家的想法,探针需要被摆放到明暗交接的部分附近,即**直接光照和阴影的交界处**,通过计算每探针位置打中阴影的着色点的占比,分为三部分,较低时使探针朝向阴影占比提高的方向移动,中等时回退其本次移动并朝垂直方向(可能的交界面上)随机移动,太大时朝反方向移动。
## 算法流程
### 预处理阶段:
**探针摆放**
1. 迭代计算探针着色点辐照度,径向距离,阴影可见性因子,加权得到当前位置误差。
2. 分别在正交坐标系下正负轴六个方向微小移动后计算测试位置误差。根据误差梯度算出下降方向。
3. 根据下降方向移动到新位置,重复迭代至最大次数或退出条件。
4. 对每探针一定范围内其他探针连线方向半球内随机发射阴影光线,若大部分未被遮挡则合并邻近探针。
**探针辐照度图集和深度图集**
1. 离线路径追踪生成每探针全球面方向接收的辐射亮度及最近击中的径向距离(深度)。
2. 对每方向辐射亮度及深度进行卷积,存储辐照度,距离及距离平方。并分别通过八面体贴图映射,存储至两张探针体积图集上。
3. 因为八面体映射纹理边界不在空间上连续,纹理平铺时进行双线性插值会产生错误的边界结果。所以需要按对称样式复制边界,来修复图集边界信息(见DDGI)提供可靠的双线性过滤采样。
**四面体生成**
1. 将最终探针位置序列化为文本。
2. 将位置导入Unity脚本中,借助Unity提供的LightProbe的Tetrahedralize()生成探针四面体,并序列化四面体结构。
**四面体查找缓冲**
1. 导入四面体结构,生成一张一定分辨率的三维纹理放置在四面体包围盒内,在格子内均匀采样点集,根据四面体查找算法,统计各采样点使用的四面体Id,记录最大比例的Id(因为四面体查找算法通过反复转移到相邻四面体,初始得到了附近的四面体后只需要一两次转移就能查找到着色点使用的四面体),着色时通过先查Id纹理,再进入查找算法得到插值使用的四面体。
### 运行时阶段:
**延迟渲染获得GBuffer**
1. 得到Position,Normal,Albedo等纹理。
**计算间接漫反射**
1. 根据四面体查找缓冲获得探针范围内着色点的四面体Id,进入四面体查找算法,大部分经过0 ~ 2次转移即找到最终采样四面体。
2. 通过四面体结构记录的四个顶点找到对应的四个探针,计算四面体插值权重,单边切比雪夫不等式可见性权重,余弦项权重得到着色点对应的辐照度,乘上漫反射BRDF得到间接漫反射。
## 结果展示
### 康奈尔盒
DDGI 2x2x2
我们的 2x1x2
路径追踪
DDGI 8x4x4
我们的 6x3x4
路径追踪
可视化移动轨迹