从物体空间到屏幕:深入理解变换矩阵

前言

最近在学习写一个离线渲染器的时候,有一个需求是要实时地追踪一条射线逐个打到的物体然后显示debug信息的功能(顺便一说,这个功能真的很好用也很好玩),离线部分仿照的pbrt-v3,交互的前端则是使用的imgui+OpenGL。前面的实现都很顺利,但是到渲染车辆场景的时候,发现射线没有做到指哪打哪,那肯定是出问题了,于是我从头到尾地排查了一遍所有的变换相关的代码。发现了两个问题:

  • OpenGL中裁剪空间的Z轴范围要求范围为\([-1, 1]\),而pbrt的perspective矩阵变换的Z范围为\([0, 1]\)
  • OpenGL需要在NDC之前就考虑viewport的长宽比aspect,但是pbrt将这一步推迟至了cameraToRaster。

进行排查的同时也系统化地解决了大量疑问:

  • 老生常谈的MVP矩阵到底是在哪些空间中进行变换?
  • 变换的结果范围是什么?
  • 用的是左手还是右手坐标系?
  • ...
阅读更多