在实现CSM阴影算法的时候,阴影总是忽隐忽现。调试了两个晚上都没有结果,我开始怀疑人生,都有放弃的念头。但是山穷水尽疑无路,柳暗花明又一村。第三个晚上完美地跑通了CSM,发现的三个bug都与正交投影有关系。
1.正交投影z范围bug。最难查的是这种不在自己代码里的bug,是基础数学库里面的bug。OpenGL中投影变换后Z坐标应该是-1到1,错误的弄成了0到1。这数学库可能是沿用DirectX里的规范导致的,之所以之前没人发现是因为从来没人关心正交投影的z坐标范围。
2.正交投影中near和far含义问题。LearnOpenGL教程中错误的以为near far是z坐标最小值和最大值。这也是错误的,应该是-near和-far的最小值和最大值。这一点和透视投影是相同的,只是在透视投影中near和far从来不会是负值,所以大家都理解成距离相机的距离了。
3.方向光位置。视图位置在算正交投影的时候已经包含在投影矩阵中了,如果灯光的模型视图变换中也有位置信息就会重复。我们用LookAt构造的矩阵中不但有方向还有位置信息,我们得从模型视图矩阵中保留方向信息,删除位置信息。