前言
最近在学习写一个离线渲染器的时候,有一个需求是要实时地追踪一条射线逐个打到的物体然后显示debug信息的功能(顺便一说,这个功能真的很好用也很好玩),离线部分仿照的pbrt-v3
,交互的前端则是使用的imgui
+OpenGL
。前面的实现都很顺利,但是到渲染车辆场景的时候,发现射线没有做到指哪打哪,那肯定是出问题了,于是我从头到尾地排查了一遍所有的变换相关的代码。发现了两个问题:
- OpenGL中裁剪空间的Z轴范围要求范围为\([-1, 1]\),而pbrt的
perspective
矩阵变换的Z范围为\([0, 1]\)。 - OpenGL需要在NDC之前就考虑viewport的长宽比aspect,但是pbrt将这一步推迟至了cameraToRaster。
进行排查的同时也系统化地解决了大量疑问:
- 老生常谈的
MVP
矩阵到底是在哪些空间中进行变换? - 变换的结果范围是什么?
- 用的是左手还是右手坐标系?
- ...