文章目录

  • 前言
  • 一、正交相机视图空间 转化到 裁剪空间 干了什么
  • 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



前言

我们把顶点坐标信息转化为裁剪空间。有可能使用到正交相机信息 或 透视相机。我们在这篇文章中,推导一下正交相机视图空间下的坐标转化到裁剪空间的矩阵。

Unity 剪贴板_unity

  • 本地空间->世界空间->观察空间->裁剪空间->屏幕映射

一、正交相机视图空间 转化到 裁剪空间 干了什么

1、正交相机裁剪的范围主要是这个方盒子

  • 因为使用的是右手坐标系。所以,摄像机的Z轴正方向是在X轴正方向右侧的。

Unity 剪贴板_游戏引擎_02

2、裁剪了之后,需要把裁剪范围内的坐标值化到[-1,1]之间,这就是我们的裁剪空间。

  • 在不同平台下裁剪空间的X 和 Y轴范围都是[-1,1]
  • OpenGL下,Z范围[-1,1]
  • DirectX下,Z范围[0,1]

3、在Unity中,设置相机为正交相机

  • Unity视图窗口使用了左手坐标系,Z轴正方向 在 X轴正方向左侧。但是,我们计算使用的是右手坐标系,这里需要注意。

4、在这里设置相机的近裁剪面和远裁剪面

Unity 剪贴板_映射关系_03


二、把正交相机的方盒子内的坐标 转化到 裁剪空间

1、我们在Unity创建两个游戏对象来解释

Unity 剪贴板_Unity 剪贴板_04

  • 我们的绿线Cube相当于我们的裁剪空间
  • 我们的大长方体相当于世界空间下的游戏对象
  • 当我们进行转化时,对大长方体进行缩放、平移即可转化到裁剪空间

2、正交相机坐标 到 裁剪坐标 的映射关系

Unity 剪贴板_unity_05

  • Unity 剪贴板_unity_06 化为 -1 Unity 剪贴板_映射关系_07
  • Unity 剪贴板_游戏引擎_08 化为 -1 Unity 剪贴板_映射关系_07
  • Unity 剪贴板_游戏引擎_10 化为 -1 Unity 剪贴板_映射关系_07

3、化简X轴坐标

Unity 剪贴板_映射关系_12

Unity 剪贴板_游戏引擎_13

Unity 剪贴板_游戏引擎_14

Unity 剪贴板_游戏引擎_15

Unity 剪贴板_矩阵_16

Unity 剪贴板_unity_17

Unity 剪贴板_游戏引擎_18

Unity 剪贴板_unity_19

  • Unity 剪贴板_游戏引擎_20
    我们在Unity中看出,我们的正交相机是处于裁剪面中央的。
    所以,我们的裁剪面x、y坐标,在摄像机空间下,是对称的。所以 r 和 l 是相反数。

Unity 剪贴板_Unity 剪贴板_21

Unity 剪贴板_游戏引擎_22

  • Unity 剪贴板_Unity 剪贴板_23

(w为我们正交相机方盒子的宽,我们这里先假设为w。可以通过屏幕像素相除得到屏幕高宽比。然后,乘以h即可得到宽)

我们已知的是:
正交相机方盒子的高 Size(等于Unity单位值的2倍)
正交相机的近远裁剪面(Z值)

Unity 剪贴板_游戏引擎_24


Unity 剪贴板_unity_25

Unity 剪贴板_映射关系_26

4、化简Y轴坐标

Unity 剪贴板_矩阵_27

Unity 剪贴板_unity_28

Unity 剪贴板_unity_29

Unity 剪贴板_矩阵_30

Unity 剪贴板_游戏引擎_31

Unity 剪贴板_映射关系_32

Unity 剪贴板_矩阵_33

Unity 剪贴板_unity_34

  • Unity 剪贴板_游戏引擎_35
    我们在Unity中看出,我们的正交相机是处于裁剪面中央的。
    所以,我们的裁剪面x、y坐标,在摄像机空间下,是对称的。所以 b 和 t 是相反数。

Unity 剪贴板_游戏引擎_36

Unity 剪贴板_映射关系_37

Unity 剪贴板_Unity 剪贴板_38

  • Unity 剪贴板_映射关系_39

(h为我们正交相机方盒子的高,这里先假设h代替)

Unity 剪贴板_映射关系_40

5、化简Z坐标(OpenGL下 [-1,1])

Unity 剪贴板_游戏引擎_02


因为我们观察空间是右手坐标系。但是,我们裁剪空间是左手坐标系。所以,这里需要化简的式子需要变化一下。(左手坐标系Z轴正方向与上图相反)

  • Unity 剪贴板_游戏引擎_10 变为 Unity 剪贴板_unity_43

Unity 剪贴板_Unity 剪贴板_44

Unity 剪贴板_unity_45

Unity 剪贴板_映射关系_46

Unity 剪贴板_unity_47

Unity 剪贴板_矩阵_48

Unity 剪贴板_映射关系_49

Unity 剪贴板_映射关系_49

  • 化简为线性式,方便后面把式子化为矩阵

Unity 剪贴板_矩阵_51

6、化简Z坐标(DirectX下 [0,1])

Unity 剪贴板_游戏引擎_02


因为我们观察空间是右手坐标系。但是,我们裁剪空间是左手坐标系。所以,这里需要化简的式子需要变化一下。(左手坐标系Z轴正方向与上图相反)

  • Unity 剪贴板_游戏引擎_10 变为 Unity 剪贴板_unity_43

Unity 剪贴板_游戏引擎_55

Unity 剪贴板_矩阵_56

Unity 剪贴板_游戏引擎_57

Unity 剪贴板_游戏引擎_58

  • 化简为线性式,方便后面把式子化为矩阵

Unity 剪贴板_游戏引擎_59


三、把转化后的坐标转化为矩阵

  • X
    Unity 剪贴板_Unity 剪贴板_60
  • Y
    Unity 剪贴板_unity_61
  • Z(OpenGL)
    Unity 剪贴板_映射关系_62
  • Z(DirectX)
    Unity 剪贴板_unity_63

1、OpenGL下

Unity 剪贴板_unity_64

2、DirectX

Unity 剪贴板_游戏引擎_65