US2S1L19——屏幕空间变换

知识回顾

  1. 在渲染管线中,顶点、法线等相关模型数据会经过以下的空间变换

    模型空间 → 世界空间 → 观察空间 → 裁剪空间 → 屏幕空间

  2. 坐标空间变换规则一般有两种

    • 方式一:通用的坐标空间变换规则(存在缩放时,轴向单位向量*缩放因子)

      Msf=(kx0000ky0000kz00001)(XsYsZsOs0001)M_{s-f} = \begin{pmatrix} kx & 0 & 0 & 0 \\ 0 & ky & 0 & 0 \\ 0 & 0 & kz & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} | & | & | & | \\ X_s & Y_s & Z_s & O_s \\ | & | & | & | \\ 0 & 0 & 0 & 1 \end{pmatrix}

    • 方式二:认为一开始模型坐标空间和世界坐标空间重合,模型发生缩放、旋转、平移变换时,模型空间下的点和向量也应该发生相同的变换

  3. 观察空间到裁剪空间变换要分情况考虑

    • 摄像机为正交投影时:

      1. 将视锥体中心位移到观察空间原点中心
      2. 将长方体视锥体的xyz坐标范围映射到(-1,1)长宽高为2的正方体中

      正交投影变换矩阵为:

      (1Aspect×Size00001Size00002FarNearNear+FarFarNear0001)\begin{pmatrix} \frac{1}{Aspect \times Size} & 0 & 0 & 0 \\ 0 & \frac{1}{Size} & 0 & 0 \\ 0 & 0 & -\frac{2}{Far - Near} & -\frac{Near+Far}{Far - Near} \\ 0 & 0 & 0 & 1 \\ \end{pmatrix}

    • 摄像机为透视投影时:

      1. 将透视视锥体变成一个长方体
      2. 将视锥体中心位移到观察空间原点中心
      3. 将长方体视锥体的xyz坐标范围映射到(-1,1)长宽高为2的正方体中

      透视投影变换矩阵为:

      (1Aspecttan(FOV2)00001tan(FOV2)0000Far+NearFarNear2FarNearFarNear0010)\begin{pmatrix} \frac{1}{Aspect \cdot \tan(\frac{FOV}{2})} & 0 & 0 & 0 \\ 0 & \frac{1}{\tan(\frac{FOV}{2})} & 0 & 0 \\ 0 & 0 & -\frac{Far + Near}{Far - Near} & -\frac{2 Far\cdot Near}{Far - Near} \\ 0 & 0 & -1 & 0 \\ \end{pmatrix}

屏幕空间变换

  1. 屏幕空间的意义

    屏幕空间中对应的位置信息是真正的像素位置

  2. 屏幕空间变换指什么

    将模型空间中的点或向量从裁剪空间中变换到屏幕空间中
    它是顶点变换的第四步,就是将 数据 从裁剪空间 → 屏幕空间 进行变换

  3. 如何进行屏幕空间变换

    {X=WidthXclip2Wclip+Width2 Y=HeightYclip2Wclip+Height2\begin{cases} X_屏 = \frac{Width \cdot X_{clip}}{2 \cdot W_{clip}} + \frac{Width}{2} \\ \ \\ Y_屏 = \frac{Height \cdot Y_{clip}}{2 \cdot W_{clip}} + \frac{Height}{2} \end{cases}

    • Z:ZclipWclip\frac{Z_{clip}}{W_{clip}} 会被存入深度缓冲中(不同硬件商存储方式可能不同),之后用于深度测试等计算(#TODO#​)
    • W:WclipW_{clip} 也会被保留下来,用于之后进行一些计算才做,例如透视校正差值(#TODO#​)

屏幕空间的意义

屏幕空间(Screen Space)是计算机图形学中的概念
指渲染结果在屏幕上显示的坐标空间三维坐标经过一系列转换后会转换到最终的二维屏幕坐标空间中
使得图像可以在屏幕上进行展示。

屏幕空间的主要意义是屏幕空间中对应的位置信息是真正的像素位置,而不是虚拟的三维坐标。
有了相对屏幕空间的坐标位置,才能准确的控制屏幕上像素点的显示效果

屏幕空间中的注意事项

在Unity中,屏幕空间左下角为像素坐标(0,0)点
屏幕空间右上角为像素坐标(分辨率宽 Screen.width​,分辨率高 Screen.height​)

image

屏幕空间变换指什么

本课程中的屏幕空间变换指的主要是将模型空间中的点或向量从裁剪空间中变换到屏幕空间中
它是顶点变换的第四步,就是将 顶点坐标数据 从裁剪空间 → 屏幕空间 进行变换

image

从图中我们可以看到,主要是**将三维坐标(x,y,z)(x,y,z)中的x,yx,y分量映射到屏幕上,而z分量一般会被用于深度缓冲**,之后用于深度测试等(决定是否被遮挡等)

屏幕空间变换,可以说是所有空间变换中最简单的一步,
我们只需要将齐次裁剪空间(x,y,zx,y,z范围在-1到1之间,长度为2的正方体)中的顶点映射到屏幕坐标即可。
我们只需要找到他们的映射关系即可。

首先我们通过上节课知道,正交投影中 ww 分量为1,透视投影中 ww 分量可能为任一数,
我们首先需要进行透视除法,保证裁剪空间中点的数据表达在齐次裁剪空间的范围内。
即,假设 裁剪空间中的点为(Xclip,Yclip,Zclip,Wclip)(X_{clip}, Y_{clip}, Z_{clip}, W_{clip})进行透视除法

(XclipWclip,YclipWclip,ZclipWclip,WclipWclip)(\frac{X_{clip}}{W_{clip}}, \frac{Y_{clip}}{W_{clip}}, \frac{Z_{clip}}{W_{clip}}, \frac{W_{clip}}{W_{clip}})

对于正交投影来说 WW 值为1,所以除以1后,x,y,zx,y,z也不会改变
对于透视投影来说 WW 值为任一值,所以除以 WW 后,X,Y,ZX,Y,Z的范围将在-1到1之间,WW为1

如何进行屏幕空间变换

找到齐次裁剪空间和屏幕空间的映射关系,主要就是找到直线的斜率

imageimageimage

于是得到:

{X=Width2×X+Width2 Y=Height2×Y+Height2\begin{cases} X_屏 = \frac{Width}{2} \times X_齐 + \frac{Width}{2} \\ \ \\ Y_屏 = \frac{Height}{2} \times Y_齐 + \frac{Height}{2} \end{cases}

因为存在透视除法,因此上述等式可以转换为:

{X=Width2×XclipWclip+Width2=WidthXclip2Wclip+Width2 Y=Height2×YclipWclip+Height2=HeightYclip2Wclip+Height2\begin{cases} X_屏 = \frac{Width}{2} \times \frac{X_{clip}}{W_{clip}} + \frac{Width}{2} = \frac{Width \cdot X_{clip}}{2 \cdot W_{clip}} + \frac{Width}{2} \\ \ \\ Y_屏 = \frac{Height}{2} \times \frac{Y_{clip}}{W_{clip}} + \frac{Height}{2} = \frac{Height \cdot Y_{clip}}{2 \cdot W_{clip}} + \frac{Height}{2} \end{cases}

那么裁剪空间中的 z,wz, w 会如何处理呢:

  • Z:ZclipWclip\frac{Z_{clip}}{W_{clip}} 会被存入深度缓冲中(不同硬件商存储方式可能不同),之后用于深度测试等计算(TODO)
  • W:WclipW_{clip} 也会被保留下来,用于之后进行一些计算才做,例如透视校正差值(TODO)

举例:

首先我们还是之前用于举例的顶点来说明

  1. 模型空间下的顶点坐标为(0.63, 0.84, -0.04)

    image

  2. 当模型进行2倍缩放,又进行(0,45,0)的旋转,然后再进行(5,0,5)的平移后
    该顶点的世界空间下的坐标为(5.834, 1.68, 4.052)

  3. 摄像机的轴向和坐标为

    1
    2
    3
    4
    print(this.transform.right);        //x轴
    print(this.transform.up); //y轴
    print(-this.transform.forward); //z轴,注意,观察空间是右手坐标系,因此取后方
    print(this.transform.position); //原点位置

    image

    转换到观察空间后的坐标为(4.562, 0.679, -7.722, 1)

  4. 转换到裁剪空间后的坐标为

    • 正交摄像机:(0.513225, 0.1358, 0.492284, 1)
    • 透视摄像机:(4.446, 1.176, 7.2142, 7.722)
  5. 转换到屏幕空间:

    假设屏幕分辨率为 1920*1080,

    x,yx,y 数据代入到下式:

    {X=WidthXclip2Wclip+Width2 Y=HeightYclip2Wclip+Height2\begin{cases} X_屏 = \frac{Width \cdot X_{clip}}{2 \cdot W_{clip}} + \frac{Width}{2} \\ \ \\ Y_屏 = \frac{Height \cdot Y_{clip}}{2 \cdot W_{clip}} + \frac{Height}{2} \end{cases}

    得到屏幕坐标:

    • 屏幕坐标(正交摄像机):(1452.696, 613.332)
    • 屏幕坐标(透视摄像机):(1512.7272, 622.237)