任务目标:
参与一个可微分渲染的项目,主要负责其中的渲染部分相关工作,在前期需要使用已有的Mesh和Texture数据生成网络所需要的输入数据。其中就包括Visibility,刚开始做的时候什么都不太懂,学习相关知识耽误了很多时间,故整理于此。
任务理解:
经与导师沟通后,本项目要求的Visibility并不是从相机角度看过去的可视性,而是更像环境光照那种,设想有一个无限大的球面,在球面上通过遍历不同的经纬得到不同的光线方向,对于模型上面的每一个顶点,计算在球面上各个方向其是否可视(光线不被其他物体或者面片遮挡)。
为了方便数据输入网络,导师还要求将这个可视数据通过球谐函数Spherical Harmonics计算得到在球谐函数空间的前9维系数,从而将每一个顶点在各个方向上是否可见的信息,转化为一个9维的向量,作为Mesh中顶点的附加属性。
整个过程需要:
- 遍历Mesh上面的每一个顶点。
- 计算该点向球面上各个方向的可见性(场景中无相交),可见为1,不可见为0。
- 将可见性信息投影到Equirectangualr Map(这一步主要用于中间结果观察,不影响SH计算)
- 将可见性信息投影到SH球谐函数上,使用前4阶系数(10个系数)。
- 将该系数向量作为顶点的固有属性储存下来。
- (选)将该系数向量作为顶点的信息使用OpenGL绘制成texture space的贴图,得到9个通道的贴图,储存的是每一个像素对应uv的可见性信息在SH空间下的系数。
具体实现:
因为在计算Visibility中需要对整个球面进行光线方向的采样,并计算其在整个场景中是否与其他物体或者面片相交,因此其实可以转化为使用一个光线追踪的框架来帮助完成这个工作,在前期探索中,曾经试图使用Games202 Assignment2的Nori框架来完成这件事,但是后面与导师沟通后,导师建议我使用Mitsuba来完成该工作,原因主要有下:Mitsuba的使用场合较为广泛,相关的资料和实验室能够提供的帮助也较多;另外学习Mitsuba也对我之后在渲染方向的继续探索有帮助。
具体我使用的是Python+Mitsuba的方式,用python脚本去调用Mitsuba的接口及其中的光追框架。
用mitsuba里面的enoki库实现了并行化计算visibility,这部分目前不计算球谐投影过程的话,20k面片的场景,两秒内完成计算Visibility信息。
而对于投影到SH这一步,目前我在Giuhub上找到一个开源的项目:
初步决定在其基础上进行修改完成第二部分计算工作。这个项目初衷是针对Image Based Lighting的SH投影计算,其使用的IBL投影方式是Equirectangular Projection(ERP)。相关资料:
因此首先要把球面采样的代码修改到与该投影方式对应,得到一张这样的图像,再使用该项目计算SH。
具体实现中遇到的问题
- 从maya导出的mesh 在Maya中没有Transform 但是导入Blender有x轴上90度的旋转,而进入到Mitsuba时其在空间坐标系中的状态是Blender中去掉90旋转之后的状态,原因是Maya、Blender和Mitsuba三者的坐标系有些不同,虽然都是右手坐标系,但是Blender中默认是Z轴向上的,而另外两个是Y轴向上。
- 在进行球面采样的时候,需要为了防止边界出现问题,需要将每个像素点的坐标变换到像素点中心,即遍历xy时对其进行x+0.5 y+0.5的计算。
相关知识点
Image Based Lighting分为三种不同的投影方式:
- Cube Map
- Dual Paraboloid Map
- Equirectangualr Map
相关资料
- Spherical Harmonics:
https://www.jianshu.com/p/a379b4c6d346