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

前言

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

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

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

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

正交投影&透视投影

Let's do some math.

由于我们在计算机中的三维图像最终都是需要渲染到屏幕上的,所以我们需要对其进行一次投影的操作,首先假定我们的坐标为右手系,我们首先在\((0,0,0)\) 原点坐标处放置朝向\(-z\)方向,上方为\(y\)轴方向的摄像机,需要得到的图像的大小为 1x1(假设下的理想情况)。现在,有两种投影方式可供选择:

正交投影 Orthographic Projection

虽然这并不是我们最终希望使用的投影方式,但是正交投影在许多场景如 2D 游戏、工程制图等都得到了较为广泛的应用。

6XPBMn.png

阅读更多