相机和视平面
简单的来说,光追干的事情是从每一个 pixel 向世界发送射线,然后进行反射折射等的计算,最终获得颜色来代表当前 pixel 所需要展示的颜色。
此篇聚焦在如何在各个空间中做变化,来从 0 开始向世界发出一条射线
不过实际上也非常的简单 —— 我们已经知道相机的位置,只需要知道要发射射线的那个像素的世界坐标即可
视平面
从第三人称的视角来看 —— 我们假装在相机前面一个单位距离的地方放置了一个“视平面”,上面的每一个点即为我们要的 pixel
确定视平面
那么先考虑第一个事情 —— 如何确定视平面在相机坐标系中的位置。
假设我们已经知道了 FOV 的角度(Vertical FOV),以及分辨率,那么由由于上一个 Block 说了,定义视平面距离相机位置为 1
所以
然后我们又知道了长和高的比值 aspect ratio 所以可以快速的计算出对应宽度
那么现在的“照片”像素位置就可以完美确定下来了
确定 uv
现在的 pixel(x, y) 对于整数 Pixel Index,
这样处理的另一个好处在于,我们可以让之后的计算和分辨率解耦 —— 比如对于不同分辨率的图片来说,它们的中心点是不同的,但是在 UV 表示下,都是
那么计算也非常的简单
加上
中心点偏移
上述压缩到 UV 已经很不错了,不过中心点是
计算依旧十分简单
相机坐标系表示
现在需要把归一化之后的坐标重新映射回屏幕坐标 ——
现在就是“绕了一圈”之后得到的视平面上的一个 pixel 在相机的局部坐标系下的表示了 ——
世界坐标
现在把相机坐标系下的那个像素点映射到世界坐标即可
依旧十分甚至九分的简单 —— 此处的
也就是 ——
其中
发射射线
现在有了像素点在世界坐标系中的表示,也有了相机位置的坐标,于是发射的 Ray 水到渠成,其方向为
然后起始点即
总结
当然,上述说的是一个理想化的针孔摄像机模型的计算链路,也就是所有的初始光线都从同一个 CameraPosition 出发,这样天然的会有透视等的效果。
不过对于不同的摄像机模型,会有不同的计算方式,不过大体的思路相通 —— 比如正交相机就可以是每个 Ray 的方向相同,诸如此类 —— 即找到一个合理的映射关系,使得 Pixel 的采样可以到一条 Ray