距离上一篇博客更新差不多又过了一个多月,目前还在调试ReSTIR GI。用这个博客总结一下到现在为止又写了那些内容,踩了哪些坑。
上图是正在测试的茶壶,Sponza场景现在还有一堆Bug。
Meshletization
由于使用了Mesh Shader,所有的网格都需要经过Meshlet化的预处理,这无可避免地会复制一部分顶点,但令我震惊的是,Sponza场景在经过Meshlet化后,几何数据竟然从147.5MB被压缩到了57MB,我怀疑是因为顶点法向和Index Buffer节约了太多空间(顶点法向被我压到了32位,而单个Index由于是Meshlet本地的,所以只需要8位),看来Mesh Shader不仅能节省带宽还能节约显存。
原来的Meshletization方法很搞,复杂度是O(N^2)的,我以为剪枝能减下去然而其实并不能,于是写了个更好更快的版本。
SBT
现在SBT Buffer从动态的变成静态的了,每个材质对应一个SBT项而非每个Instance对应一个项。这样做的代价是一个Instance只能使用一种材质,不过这一点可以在以后改进。好处是每帧渲染时不需要额外进行同步了。
GLTF与Sponza
GLTF很搞的一点是它允许用户自定义面得切线空间,于是我准备用一个Index Buffer同大小的Buffer来压缩这个切线空间。目前还没写,这玩意导致Sponza的法线分崩离析,目前正在调试。
后记:法线爆炸貌似是半透明材质和缺失顶点法向的Mesh造成的
Sponza场景在调试好之后应该就是之后我的常用测试场景了,现在材质的读取也被写成了多线程的,一次重新载入大概要消耗15秒,还不够快,但已经不错了。
其它
逐渐发现光GI一个东西也远没有我最初想象的那么简单...接下来要做的东西大概有:
- 完整版多Bounce的ReSTIR GI
- 挑选降噪方法,比若SVGF(调研与实现)
- Direct Lighting采样算法,这个貌似没什么好调研的,主要是实现
- 创新,准备稍微调研一下Differential Rendering的东西,以试着使用Motion数据来优化渲染
又一次改变
一开始有个用哈希来想的BitGuiding的光追引导算法的想法,但这个想法实现到一半就废弃了,大致就是使用类似Virtual Texture的3D UINT纹理压位存储Path Guiding数据。废弃的原因是这种存储更类似与Trick,效果也不一定有其它缓存方法好,还有同步问题和较大的内存开销。
准备先实现Direct Lighting采样数据结构,然后试试实现Surfel GI类似的方法(来缓存空间上的各类数据),实现后看看效果如何。
Direct Lighting
实现好了,没什么说的,基本就是一个两层次的树从上到下采样,高层次树结构每帧重建。
然后现在陷入了迷茫,ReSTIR的效果目前来看强差人意,不知道应该些什么,最近又有点摆烂啥都没干...或许再多做些调研吧。
先看GRIS(这周之内),然后看SVGF,然后实现一下(下周),然后在考虑其它的。
Bug与GRIS(并没有看完)
这周找出了好多Bug(比如这个)...而且一个个攻克了,但是一个画面抖动的问题目前还不知道为何,初步怀疑是我显卡显存的锅(毕竟在服务器和SunIsMe的电脑上都能正常运行,但我这里就出事故了)。上次提出的论文仍没看,时间已经接近12月了,进度比想象中更慢,淦。
感觉ReSTIR也不是很理想,总而言之这是现在的效果
(1440 x 900,20fps,2 bounce,10 x Spatial Reuse):
(1440 x 900,full path,10 fps,10 x Spatial Reuse)
逐渐发现以ReSTIR为主的方法也受某些掣肘,准备换赛道了,只有多种方法复合的GI才是好GI。
11月录制的视频: