文章目录
- 前言
- 一、正交相机视图空间 转化到 裁剪空间 干了什么
- 1、正交相机裁剪的范围主要是这个方盒子
- 2、裁剪了之后,需要把裁剪范围内的坐标值化到[-1,1]之间,这就是我们的裁剪空间。
- 3、在Unity中,设置相机为正交相机
- 4、在这里设置相机的近裁剪面和远裁剪面
- 二、把正交相机的方盒子内的坐标 转化到 裁剪空间
- 1、我们在Unity创建两个游戏对象来解释
- 2、正交相机坐标 到 裁剪坐标 的映射关系
- 3、化简X轴坐标
- 4、化简Y轴坐标
- 5、化简Z坐标(OpenGL下 [-1,1])
- 6、化简Z坐标(DirectX下 [0,1])
- 三、把转化后的坐标转化为矩阵
- 1、OpenGL下
- 2、DirectX
前言
我们把顶点坐标信息转化为裁剪空间。有可能使用到正交相机信息 或 透视相机。我们在这篇文章中,推导一下正交相机视图空间下的坐标转化到裁剪空间的矩阵。
- 本地空间->世界空间->观察空间->裁剪空间->屏幕映射
一、正交相机视图空间 转化到 裁剪空间 干了什么
1、正交相机裁剪的范围主要是这个方盒子
- 因为使用的是右手坐标系。所以,摄像机的Z轴正方向是在X轴正方向右侧的。
2、裁剪了之后,需要把裁剪范围内的坐标值化到[-1,1]之间,这就是我们的裁剪空间。
- 在不同平台下裁剪空间的X 和 Y轴范围都是[-1,1]
- OpenGL下,Z范围[-1,1]
- DirectX下,Z范围[0,1]
3、在Unity中,设置相机为正交相机
- Unity视图窗口使用了左手坐标系,Z轴正方向 在 X轴正方向左侧。但是,我们计算使用的是右手坐标系,这里需要注意。
4、在这里设置相机的近裁剪面和远裁剪面
二、把正交相机的方盒子内的坐标 转化到 裁剪空间
1、我们在Unity创建两个游戏对象来解释
- 我们的绿线Cube相当于我们的裁剪空间
- 我们的大长方体相当于世界空间下的游戏对象
- 当我们进行转化时,对大长方体进行缩放、平移即可转化到裁剪空间
2、正交相机坐标 到 裁剪坐标 的映射关系
化为 -1
化为 -1
化为 -1
3、化简X轴坐标
我们在Unity中看出,我们的正交相机是处于裁剪面中央的。
所以,我们的裁剪面x、y坐标,在摄像机空间下,是对称的。所以 r 和 l 是相反数。
(w为我们正交相机方盒子的宽,我们这里先假设为w。可以通过屏幕像素相除得到屏幕高宽比。然后,乘以h即可得到宽)
我们已知的是:
正交相机方盒子的高 Size(等于Unity单位值的2倍)
正交相机的近远裁剪面(Z值)
4、化简Y轴坐标
我们在Unity中看出,我们的正交相机是处于裁剪面中央的。
所以,我们的裁剪面x、y坐标,在摄像机空间下,是对称的。所以 b 和 t 是相反数。
(h为我们正交相机方盒子的高,这里先假设h代替)
5、化简Z坐标(OpenGL下 [-1,1])
因为我们观察空间是右手坐标系。但是,我们裁剪空间是左手坐标系。所以,这里需要化简的式子需要变化一下。(左手坐标系Z轴正方向与上图相反)
变为
- 化简为线性式,方便后面把式子化为矩阵
6、化简Z坐标(DirectX下 [0,1])
因为我们观察空间是右手坐标系。但是,我们裁剪空间是左手坐标系。所以,这里需要化简的式子需要变化一下。(左手坐标系Z轴正方向与上图相反)
变为
- 化简为线性式,方便后面把式子化为矩阵
三、把转化后的坐标转化为矩阵
- X
- Y
- Z(OpenGL)
- Z(DirectX)
1、OpenGL下
2、DirectX