文章目录

  • 前言
  • 一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化
  • 1、观察空间(右手坐标系、透视相机)
  • 2、裁剪空间(左手坐标系、且转化为了齐次坐标)
  • 3、屏幕空间(把裁剪坐标归一化设置)
  • 4、从观察空间到裁剪空间
  • 5、从裁剪空间到屏幕空间后
  • 二、透视相机的参数推导
  • 1、从XoY平面,求出X~v~从观察空间到裁剪空间的坐标投影 X~p~
  • 2、从YoZ平面,求出Y~v~从观察空间到裁剪空间的坐标投影 Y~p~
  • 三、把投影到近裁剪面的坐标 归一化设置
  • 1、求归一化设置后的 x~n~
  • 2、求归一化设置后的 y~n~
  • 3、得到最后化简的公式
  • 四、构建转化矩阵
  • 1、在OpenGL[-1,1]下:
  • 2、在DirectX[1,0]下:
  • 3、把A、B代入矩阵得



前言

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

unity RawImage 裁剪_unity


一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化

unity RawImage 裁剪_unity RawImage 裁剪_02

1、观察空间(右手坐标系、透视相机)

unity RawImage 裁剪_数码相机_03

2、裁剪空间(左手坐标系、且转化为了齐次坐标)

unity RawImage 裁剪_unity_04

3、屏幕空间(把裁剪坐标归一化设置)

unity RawImage 裁剪_归一化_05

4、从观察空间到裁剪空间

用透视投影矩阵先转化到裁剪空间
然后,在转化为齐次坐标

5、从裁剪空间到屏幕空间后

unity RawImage 裁剪_数码相机_06

unity RawImage 裁剪_数码相机_07


二、透视相机的参数推导

unity RawImage 裁剪_unity_08

  • 我们对于远裁剪面只是已知 f,其他参数都是未知

1、从XoY平面,求出Xv从观察空间到裁剪空间的坐标投影 Xp

unity RawImage 裁剪_unity RawImage 裁剪_09

  • 点 V 是观察空间下的模型顶点,xyz是已知的
    已知:unity RawImage 裁剪_unity_10
  • 点P是该点在近裁剪面上的投影点,xyz是未知的
    未知:unity RawImage 裁剪_数码相机_11
  • 我们在 XoZ平面上,能求的就是 xp
    求:unity RawImage 裁剪_unity_12

unity RawImage 裁剪_unity RawImage 裁剪_13

unity RawImage 裁剪_矩阵_14

  • v点向Z轴做垂线,原点连接v点,围成的两个三角形相似,可得:

unity RawImage 裁剪_unity_15

unity RawImage 裁剪_归一化_16

unity RawImage 裁剪_矩阵_17

2、从YoZ平面,求出Yv从观察空间到裁剪空间的坐标投影 Yp

unity RawImage 裁剪_数码相机_18

  • 点 V 是观察空间下的模型顶点,xyz是已知的
    已知:unity RawImage 裁剪_unity_10
  • 点P是该点在近裁剪面上的投影点,xyz是未知的
    未知:unity RawImage 裁剪_数码相机_11
  • 我们在 YoZ平面上,能求的就是 yp
    求: unity RawImage 裁剪_数码相机_21

unity RawImage 裁剪_unity RawImage 裁剪_13

unity RawImage 裁剪_unity RawImage 裁剪_23

  • v点向Z轴做垂线,原点连接v点,围成的两个三角形相似,可得:

unity RawImage 裁剪_数码相机_24

unity RawImage 裁剪_unity_25

unity RawImage 裁剪_unity_26


三、把投影到近裁剪面的坐标 归一化设置

unity RawImage 裁剪_unity_26

化到[-1,1]之间
具体参考Unity中Shader裁剪空间推导(正交相机到裁剪空间的转化矩阵)

1、求归一化设置后的 xn

  • unity RawImage 裁剪_归一化_28 化为: unity RawImage 裁剪_数码相机_29

unity RawImage 裁剪_数码相机_30

unity RawImage 裁剪_归一化_31

2、求归一化设置后的 yn

  • unity RawImage 裁剪_数码相机_32 化为: unity RawImage 裁剪_矩阵_33

unity RawImage 裁剪_归一化_34

unity RawImage 裁剪_unity_35

3、得到最后化简的公式

由于NDC下的坐标由透视除法而得
我们假设透视除法中的 w 为 -zv
还原到裁剪空间还需要乘以 -zv

  • X:

unity RawImage 裁剪_归一化_31

unity RawImage 裁剪_归一化_37

unity RawImage 裁剪_归一化_38

  • Y:

unity RawImage 裁剪_unity_35

unity RawImage 裁剪_unity RawImage 裁剪_40

unity RawImage 裁剪_unity RawImage 裁剪_41

  • Z:

unity RawImage 裁剪_归一化_42

unity RawImage 裁剪_数码相机_43

  • W:

unity RawImage 裁剪_数码相机_44

unity RawImage 裁剪_unity RawImage 裁剪_45


四、构建转化矩阵

裁剪空间下的点 = 观察空间下的基向量 在 裁剪空间下的矩阵 * 点在观察空间下的坐标

unity RawImage 裁剪_数码相机_46

unity RawImage 裁剪_数码相机_47

unity RawImage 裁剪_矩阵_48

  • unity RawImage 裁剪_归一化_49
  • unity RawImage 裁剪_归一化_50
  • unity RawImage 裁剪_unity RawImage 裁剪_51
  • unity RawImage 裁剪_unity_52

unity RawImage 裁剪_数码相机_53

unity RawImage 裁剪_归一化_54

最后一行由于相乘结果为1可以得出,把最后未知部分设为A,B
unity RawImage 裁剪_矩阵_55

unity RawImage 裁剪_数码相机_56

unity RawImage 裁剪_数码相机_57

unity RawImage 裁剪_数码相机_58

unity RawImage 裁剪_归一化_59

1、在OpenGL[-1,1]下:

unity RawImage 裁剪_归一化_59

unity RawImage 裁剪_unity_61

unity RawImage 裁剪_unity_62

unity RawImage 裁剪_归一化_63

unity RawImage 裁剪_unity RawImage 裁剪_64

unity RawImage 裁剪_unity_65

unity RawImage 裁剪_归一化_66

unity RawImage 裁剪_unity_67

unity RawImage 裁剪_unity RawImage 裁剪_68

unity RawImage 裁剪_矩阵_69

unity RawImage 裁剪_数码相机_70

2、在DirectX[1,0]下:

unity RawImage 裁剪_归一化_59

unity RawImage 裁剪_矩阵_72

unity RawImage 裁剪_归一化_73

unity RawImage 裁剪_归一化_74

unity RawImage 裁剪_数码相机_75

unity RawImage 裁剪_矩阵_76

unity RawImage 裁剪_矩阵_77

unity RawImage 裁剪_数码相机_78

unity RawImage 裁剪_unity_79

3、把A、B代入矩阵得

  • OpenGL
    unity RawImage 裁剪_unity RawImage 裁剪_80
  • DirectX
    unity RawImage 裁剪_归一化_81