计算机图形:三维观察之投影变换

投影变换

img

将对象描述从世界坐标系变换到观察坐标系后,要将其投影到观察平面,即投影变换。有2种投影方式:

  1. 平行投影(parallel projection),坐标位置沿平行线变换到观察平面。保持对象的比例不变,常用于辅助绘图、设计生成工程图。获取对象平行视图的方法有2种:1)沿垂直于观察平面的直线投影;2)沿某倾斜角度投影到观察平面。

  2. 透视投影(perspective projection),对象位置沿会聚到观察平面后的一点(即投影参考点/投影中心)的直线,变换到投影坐标系。透视投影不会保持对象比例,但真实感更好。

注意:概念上,投影变换指将对象变换到观察平面;实际应用中,投影变换除了指将对象变换到观察平面,还包括规范化变换。

线段\(P_1P_2\)的平行投影、透视投影示意图:

img

正投影

对象沿与投影平面法向量N平行的方向,到投影平面上的变换N称为正投影(orthogonal projection)或正交投影(orthographic projection)。

正投影:特殊的平行投影,投影线//投影平面法向量N。常用于生成对象的前视图、侧视图、顶视图,可用于建筑和工程绘图。

img

轴测、等轴测正投影

轴测正投影:

生成显示对象多个侧面的正投影,这些视图称为轴测(axonometric)正投影。

等轴测投影:

等轴测(isometric)投影是特殊轴测投影,其投影平面与每个坐标轴的交点到原点距离相等。

常见等轴测投影:多个投影平面形成一个立方体,立方体8个顶点分布在观察坐标系的8分象限。

img

正投影坐标系

观察坐标系\(x_{view}y_{view}z_{view}\)下,如果投影方向//\(z_{view}\)轴,则任意点\((x,y,z)\)的投影坐标\((x_p,y_p,z_p)\)

\[\tag{6} x_p=x, y_p=y, z_p=z_{vp} \]

其中,\(z_{vp}\)为观察平面位置(观察平面⊥\(z_{view}\)轴)。\(z_p\)值被保存,用于可见性检测。

任一点到观察平面的正交投影:

img

裁剪窗口、正投影观察体

常用矩形裁剪窗口来模拟照相机的镜头,用于确定有多少场景要显示。
OpenGL中,裁剪窗口位于观察平面上,位置、大小由矩形左下角+右上角确定,其边与观察坐标系\(x_{view}, y_{view}\)轴平行,即\(x_{view}y_{view}\)平面的正则矩形。裁剪窗口边界限定了要显示的场景内容的x、y范围。

观察平面上用观察坐标指定裁剪窗口:

img

∵正投影的投影线⊥观察平面
∴裁剪窗口的4个边界的投影线⊥观察平面
此时,裁剪窗口的4个边界的投影线形成一个无限的裁剪区域,即没有头尾的长方体,如下图:

img

选择1个或2个边界平面(//观察平面),为该(无限裁剪)区域\(z_{view}\)方向限定边界,该区域称为正交观察体(orthographic view volume),这2个平面称为近-远裁剪平面(near-far clipping plane)或前-后裁剪平面(front-back clipping plane)。正交观察体外的场景对象会被排除,不会显示。观察方向沿\(-z_{view}\)轴,有\(z_{far} < z_{near}\)

由远、近裁剪平面形成的正交投影观察体:

img

正投影的规范化变换

观察坐标系下,任一点\((x,y,z)\)到观察平面的正交投影位置\((x,y)\)。观察体内的对象,经规范化变换到规范化立方体,直接映射到规范化观察体(normalized view volume/canonical view volume)。

\[观察坐标系(右手系)内一点\xrightarrow{正交投影}正投影观察体(右手系)\xrightarrow{规范化变换}规范化观察体(左手系) \]

规范化观察体有两种:
1)单位立方体:限制x、y、z范围为0~1;
2)对称立方体:限制x、y、z范围为-1~1。

因为屏幕坐标系常用左手系,所以规范化观察体也用左手系。观察方向正距离,代表距离屏幕(观察平面)的距离。

左手屏幕坐标系:

img

  • 规范化变换

设近平面、远平面:\(z=z_{near},z=z_{far}, z_{far}<z_{near}<0\);规范化变换映射:\((xw_{min},yw_{min},z_{near})\to(-1,-1,-1)\)\((xw_{max},yw_{max},z_{far})\to(1,1,1)\)

正交投影的规范化变换示意图:

img

正交投影规范化变换有两种推导方法:

方法一:分解法,将变换分解为三步:
1)平移:将观察体中心平移到规范化坐标系原点;
2)反射:以z轴为反射轴,将观察体进行反射;
2)缩放:将x、y、z坐标放缩到-1~1范围.

平移矩阵:

\[\begin{aligned} T&=T(-{xw_{min}+xw_{max}\over 2},-{yw_{min}+yw_{max}\over 2},-{z_{near}+z_{far}\over 2})\\ &=\begin{pmatrix} 1&0&0&-{xw_{min}+xw_{max}\over 2}\\ 0&1&0&-{yw_{min}+yw_{max}\over 2}\\ 0&0&1&-{z_{near}+z_{far}\over 2}\\ 0&0&0&1 \end{pmatrix} \end{aligned} \]

\(z_{norm}\)轴与\(z_{view}\)轴反向
∴反射矩阵(参见计算机图形:特殊几何变换):

\[Reflect_z=\begin{pmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&-1&0\\ 0&0&0&1 \end{pmatrix} \]

放缩矩阵:

\[\begin{aligned} S&=S({2\over xw_{max}-xw_{min}},{2\over yw_{max}-yw_{min}},{2\over z_{near}-z_{far}})\\ &=\begin{pmatrix} {2\over xw_{max}-xw_{min}}&0&0&0\\ 0&{2\over yw_{max}-yw_{min}}&0&0\\ 0&0&{2\over z_{near}-z_{far}}&0\\ 0&0&0&1 \end{pmatrix} \end{aligned} \]

复合变换矩阵:

\[\tag{7} \begin{aligned} M_{ortho,norm}&=S\cdot Reflect_z\cdot T\\ &=\begin{bmatrix} {2\over xw_{max}-xw_{min}} & 0 & 0 & -{xw_{min}+xw_{max}\over xw_{max}-xw_{min}}\\ 0 & {2\over yw_{max}-yw_{min}} & 0 & -{yw_{min}+yw_{max}\over yw_{max}-yw_{min}}\\ 0 & 0 & {-2\over z_{near}-z_{far}} & {z_{near}+z_{far}\over z_{near}-z_{far}}\\ 0 & 0 & 0 & 1 \end{bmatrix} \end{aligned} \]

方法二:坐标变换法

以z轴为例:

img

变换遵循原则:z坐标在变换前后,到起点的距离与z轴跨度的比例保持不变。即:

\[\begin{aligned} &\frac{z-z_{near}}{z_{far}-z_{near}}=\frac{z_c-(-1)}{1-(-1)}\\ \implies &z_c=\frac{-2}{z_{far}-z_{near}}z+\frac{z_{near}+z_{far}}{z_{near}-z_{far}}\\ \end{aligned} \]

其中,近、远平面为:\(z=z_{near},z=z_{far},z_{far}<z_{near}<0\)

同理,

\[\begin{aligned} &\frac{x-xw_{min}}{xw_{max}-xw_{min}}=\frac{x_c-(-1)}{1-(-1)}\\ &\frac{y-yw_{min}}{yw_{max}-yw_{min}}=\frac{y_c-(-1)}{1-(-1)}\\ \implies &x_c=\frac{2}{xw_{max}-xw_{min}}x-\frac{xw_{min}+xw_{max}}{xw_{max}-xw_{min}}\\ &y_c=\frac{2}{yw_{max}-yw_{min}}y-\frac{yw_{min}+yw_{max}}{yw_{max}-yw_{min}} \end{aligned} \]

根据坐标变换,可以构造出正交投影变换矩阵\(M_{ortho,norm}\)(即上面式(7)),以满足:

\[\begin{pmatrix} x_c\\y_c\\z_c\\1 \end{pmatrix} =M_{ortho,norm}\begin{pmatrix} x\\y\\z\\1 \end{pmatrix} \]

注意:有的文献中,z轴变换会有差异,这是因为近、远平面设置不同. 例如,令近、远平面\(z=-z_{near},z=-z_{far},z_{far}>z_{near}>0\)
此时,

\[\begin{aligned} &\frac{z-(-z_{near})}{(-z_{far})-(-z_{near})}=\frac{z_c-(-1)}{1-(-1)}\\ \implies &z_c=\frac{2}{z_{far}-z_{near}}z+\frac{z_{near}+z_{far}}{z_{near}-z_{far}}\\ \implies &M_{ortho,norm}(3;3)=\frac{2}{z_{far}-z_{near}},\\&M_{ortho,norm}(3;4)=\frac{z_{near}+z_{far}}{z_{near}-z_{far}} \end{aligned} \]

斜投影

当平行投影的投影线与观察平面不平行时,该映射称为斜投影(oblique parallel projection)。

平行投影={正交投影, 斜投影}

斜平行投影

如下图,场景中一点\(P(x,y,z)\)在观察平面(\(z=z_{vp}\))正投影点\(P_1(x,y,z_{vp})\),斜投影点\(P_2(x_p,y_p,z_{vp})\)\(|P_1P_2|=L\)
斜平行投影用2个角度描述:
1)α,斜平行投影线与\(P_1P_2\)的夹角;
2)φ,\(P_1P_2\)\(x_{view}\)轴的夹角;
其中,α∈[0,π/2),φ∈[0,2π)

img

斜投影坐标:

\[\tag{8} x_p=x+L\cos φ\\ y_p=y+L\sin φ \]

\(\vartriangle PP_1P_2\)中,求L:

\[\tag{9} \tan α={z_{vp}-z\over L}\\ \therefore L={z_{vp}-z\over \tan α}=(z_{vp}-z)\cot α \]

\(z_{vp}-z=1\)时,\(L=\cot α\)
有,

\[x_p=x+\cot α\cos φ\\ y_p=y+\cot α\sin φ \]

α=π/2时,可得正投影。

  • 斜平行投影向量

斜投影线的方向,称为斜平行向量(parallel-projection vector),用\(V_p\)表示。观察坐标系下,\(V_p=(V_{px},V_{py},V_{pz}), \tan φ={V_{py}\over V_{px}}\)
\(V_p//\overrightarrow{P_1P_2}\)
\(V_p,\overrightarrow{P_1P_2}\)\(x_{view},y_{view},z_{view}\)轴分量比例相同(证明见下文),即

\[\frac{(\overrightarrow{P_1P_2})_x}{(\overrightarrow{P_1P_2})_z}={x_p-x\over z_{vp}-z}={V_{px}\over V_{pz}}\\ \frac{(\overrightarrow{P_1P_2})_y}{(\overrightarrow{P_1P_2})_z}={y_p-y\over z_{vp}-z}={V_{py}\over V_{pz}} \]

于是,斜平行投影可用正交投影向量表示成:

\[\tag{10} \begin{aligned} x_p=x+(z_{vp}-z){V_{px}\over V_{pz}}\\ y_p=y+(z_{vp}-z){V_{py}\over V_{pz}} \end{aligned} \]

推论:三维空间下,平行向量\(\vec V_1(x_1,y_1,z_1),\vec V_2(x_2,y_2,z_2)\)的xyz坐标分量比例相同,即

\[{x_1\over y_1}={x_2\over y_2},{x_1\over z_1}={x_2\over z_2}, {y_1\over z_1}={y_2\over z_2} \]

证明:
假设\(\vec V_1=(x_1,y_1,z_1)//\vec V_2=(x_2,y_2,z_2)\),那么,
存在λ∈R且λ≠0,使得

\[\vec V_1=λ\vec V_2\\ \implies (x_1,y_1,z_1)=λ(x_2,y_2,z_2)\\ \implies {x_1\over x_2}={y_1\over y_2}={z_1\over z_2}=λ\\ \implies {x_1\over y_1}={x_2\over y_2},{x_1\over z_1}={x_2\over z_2}, {y_1\over z_1}={y_2\over z_2} \]

即得证。

斜等测、斜二测平行投影

φ常用π/3(60°)、π/4(45°),显示对象前、侧、顶视图的组合(或前、侧、底)。

α常用值:
1)α=45°(tan α=1),获得视图称为斜等测(cavalier)投影图,垂直于投影平面的线条投影后长度不变。

2)α≈63.4°(tan α=2),获得视图称为斜二测(cabinet)投影图,垂直于投影平面的线条投影后长度为原来一半。真实感较1)更好。

斜平行投影变换

由式(10),可得斜平行投影变换矩阵:

\[\begin{aligned} P_2&=M_{oblique}\cdot P\\ \begin{bmatrix} x_p\\ y_p\\ z_{vp}\\ 0 \end{bmatrix} &= M_{oblique} \cdot \begin{bmatrix} x\\ y\\ z\\ 0 \end{bmatrix} \end{aligned}\\ \implies \tag{11} M_{oblique}=\begin{bmatrix} 1 & 0 & -{V_{px}\over V_{pz}} & z_{vp}{V_{px}\over z_{pz}}\\ 0 & 1 & -{V_{py}\over V_{pz}} & z_{vp}{V_{py}\over V_{pz}}\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

透视投影

将对象沿会聚到投影参考点(projection reference point)或投影中心(center of projection)的路径投影到观察平面来逼近几何光学效果,称为透视投影

平行投影:保持对象相对比例;
透视投影:模仿人眼或照相机,具有近大远小的真实感。

透视投影示意图:

img

投影参考点与观察原点

  • 投影参考点是透视投影才有的概念;观察原点是基于观察坐标系的概念,所有投影都有。

  • 有的图形软件包将投影参考点设在观察原点,即视点;有的将投影参考点作为另一观察参数来选择。i.e. 投影参考点可视作观察原点,也可不同,取决于具体环境,参见下文“特殊透视投影”部分。

坐标变换

场景中任一点\(P(x,y,z)\)到投影参考点\(P_{0}(x_{prp},y_{prp},z_{prp})\)的投影示意图:

img

投影线与观察平面交点\(P'(x_p,y_p,z_{vp})\)

投影线上任一点\((x',y',z')\)参数方程(证明见下面推论):

\[\tag{12} \begin{aligned} x'&=x-(x-x_{prp})u\\ y'&=y-(y-y_{prp})u\\ z'&=z-(z-z_{prp})u \end{aligned} \]

u=0时,代表点P(x,y,z);
u=1时,代表投影参考点\(P_0(x_{prp},y_{prp},z_{prp})\)

写成点形式:

\[P'=(1-u)P+uP_{0},u=\frac{|PP'|}{|PP_0|}\in [0,1] \]

推论:两点\(S_1(x_1,y_1,z_1)、S_2(x_2,y_2,z_2)\)确定直线段L,L上任一点\(S(x,y,z)\)坐标方程:

\[\begin{cases} x&=ux_1+(1-u)x_2\\ y&=uy_1+(1-u)y_2 & u\in [0,1]\\ z&=uz_1+(1-u)z_2 \end{cases} \]

证明:
∵S位于直线L
\(S_1S//S_2S\)
∴存在非0实数λ,使得\(x-x_1=λ(x-x_2)\)
\(x={1\over 1-λ}x_1-{λ\over 1-λ}x_2\)
\(u={1\over 1-λ}\),有\(x=ux_1+(1-u)x_2\)
∵x在线段\(S_1S_2\)上,不妨设\(x_1\le x_2\)
\(x_1\le x\le x_2\)
\(x_1\le ux_1+(1-u)x_2\le x_2\)
\(0\le u\le 1\)

同理可证,y、z坐标也成立。故得证。

证明也可参见:数学基础:三角形重心坐标插值公式的证明

  • 如何求投影变换公式?

要求投影变换公式,就需要求出P在观察平面\(z'=z_{vp}\)上的投影点\(P'\)

img

如上图,根据三角形相似性,可求出:

\[\tag{13} u={z_{vp}-z\over z_{prp}-z}=\frac{|PP'|}{|PP_0|} \]

于是

\[\tag{14} \begin{aligned} x_p&=(1-u)x+ux_{prp}={z_{prp}-z_{vp}\over z_{prp}-z}x+{z_{vp}-z\over z_{prp}-z}x_{prp}\\ y_p&=(1-u)y+uy_{prp}={z_{prp}-z_{vp}\over z_{prp}-z}y+{z_{vp}-z\over z_{prp}-z}y_{prp}\\ z_p&=z_{vp} \end{aligned} \]

特殊透视投影

限制投影参考点或观察平面。

1)投影参考点限制在\(z_{view}\)轴,即\(x_{prp}=y_{prp}=0\)

\[\tag{15} x_p={z_{prp}-z_{vp}\over z_{prp}-z}x, y_p={z_{prp}-z_{vp}\over z_{prp}-z}y \]

2)将投影参考点固定在原点,即\((x_{prp},y_{prp},z_{prp})=(0,0,0)\)

\[\tag{16} x_p={z_{vp}\over z}x, y_p={z_{vp}\over z}y \]

3)观察平面是uv平面(uvn坐标系),对投影参考点位置不限制,即\(z_{vp}=0\)

\[\tag{17} \begin{aligned} x_p&={z_{prp}\over z_{prp}-z}x-{z\over z_{prp}-z}x_{prp}\\ y_p&={z_{prp}\over z_{prp}-z}y-{z\over z_{prp}-z}y_{prp} \end{aligned} \]

tips:uvn坐标系下,\(u,v,n\)分别代表\(x_{view},y_{view},z_{view}\)。参见uvn观察坐标系

4)观察平面是uv平面,投影参考点在\(z_{view}\)轴,即\(z_{vp}=0,x_{prp}=y_{prp}=0\)

\[\tag{18} \begin{aligned} x_p&={z_{prp}\over z_{prp}-z}x\\ y_p&={z_{prp}\over z_{prp}-z}y \end{aligned} \]

注意:投影参考点不能位于观察平面\(z_{prp}\neq z_{vp}\),否则所有对象投影到观察平面上一点。

灭点

当一个场景使用透视投影到观察平面上时,平行于观察平面的线条投影后仍然平行。但任何与观察平面不平行的平行线组投影后,会成为一组会聚线条。一组投影平行线会聚的点,称为灭点(vanishing point)。每组平行线都有自己的灭点。

主灭点(principal vanishing point):对象上平行于一个主轴的一组平行线的灭点。坐标轴有3个,所以主灭点最多有3个。

通过投影平面的方向,可以控制主灭点的数量(1,2或3),对应透视投影分为一点、两点或三点投影。

下图是一个立方体的一点、两点透视投影:

img

灭点与投影参考点

不同点:

  • 是否能修改

投影参考点模拟人眼或摄像机,一旦选定,不能随意修改;灭点会随着对象的几何变换而改变位置。

  • 针对对象

灭点针对对象的一组平行线,可能有0个或多个;投影参考点针对所有透视投影,只有1个点。i.e. 透视投影一定存在投影参考点,而平行于观察平面的线组不存在灭点。

透视投影观察体

在观察平面上指定一个矩形裁剪窗口,可得到透视投影观察体(perspective projection view volumes),称为视觉棱锥体(pyramid of vision)。棱锥体外的所有对象,都会被裁剪子程序消除。

视觉棱锥体:

img

注: 投影中心也是投影参考点。

添加垂直于\(z_{view}\)的远、近平面,可得到棱台观察体(frustum view volumes)。通常,远、近平面位于投影参考点同侧(简化版人眼/相机观察模型),且远平面距投影参考点更远。

棱台观察体:

img

注:有些应用/模型为计算方便,将近裁剪平面设为与观察平面重合.

透视投影变换矩阵

式(14)给出透视投影变换的一般形式,但不能直接得到变换矩阵,因为x、y系数含z(非常数)。可将其转化成别的参数形式,然后再用三维齐次坐标表示:

\[\tag{19} x_p={x_h\over h},y_p={y_h\over h} \]

其中,任一点\(P(x,y,z)\),P的投影点\(P'(x_p,y_p,z_p)\),投影参考点\(P_0(x_{prp},y_{prp},z_{prp})\),观察平面\(z=z_{vp}\)

齐次参数:

\[\tag{20} h=z_{prp}-z \]

\(x_h,y_h\)

\[\tag{21} \begin{aligned} x_h=x(z_{prp}-z_{vp})+x_{prp}(z_{vp}-z)\\ y_h=y(z_{prp}-z_{vp})+y_{prp}(z_{vp}-z) \end{aligned} \]

用齐次坐标的矩阵变换表示透视变换:

\[\tag{22} P_h=M_{pers}\cdot P \]

其中,\(P_h=(x_h,y_h,z_h,h)^T,P=(x,y,z,1)^T\)

可得一种可能的透视投影变换矩阵:

\[\tag{22} M_{pers}=\begin{bmatrix} z_{prp}-z_{vp} & 0 & -x_{prp} & x_{prp}z_{vp}\\ 0 & z_{prp}-z_{vp} & -y_{prp} & y_{prp}z_{vp}\\ 0 & 0 & s_z & t_z\\ 0 & 0 & -1 & z_{prp} \end{bmatrix} \]

其中,参数\(s_z,t_z\)是z坐标投影值规范化过程中的比例和平移因子,值依赖于棱台观察体范围和规范化范围。如果不放缩、平移,则默认值分别为1, 0。

特例:如果将投影参考点限制在观察原点,且不做规范化和平移即\(s_z=1,t_z=0\),则\((x_{prp},y_{prp},z_{prp})=(0,0,0)\). 那么,\(h=-z\)

\[\begin{aligned} M_{pers}&=\begin{bmatrix} -z_{vp} & 0 & 0 & 0\\ 0 & -z_{vp} & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & -1 & 0 \end{bmatrix} \end{aligned} \]

对称透视投影椎体

两种描述方法:

1. 使用中心线

从投影参考点到裁剪窗口中心并穿过观察体的线条,是透视投影棱台的中心线。如下图,如果中心线⊥投影平面,则观察体为对称棱台(symmetric frustum)(相对于中心线)。

img

观察坐标系下,观察平面\(z=z_{vp}\),投影参考点\(P_{prp}(x_{prp},y_{prp},z_{prp})\),则中心线与观察平面交于\((x_{prp},y_{prp},z_{vp})\)。裁剪窗口宽、高分别为width、height,则裁剪窗口边界:

\[\begin{aligned} xw_{min}&=x_{prp}-{width\over 2}, xw_{max}=x_{prp}+{width\over 2}\\ yw_{min}&=y_{prp}-{height\over 2}, yw_{max}=y_{prp}+{height\over 2} \end{aligned} \]

注意:xw/yw的w指clipping window.

因此,对于对称透视投影锥体,可用裁剪窗口宽、高代替窗口坐标。

2. 使用视场角、裁剪窗口宽高比

视场角(field-of-view angle):棱台的上裁剪平面与下裁剪平面的夹角。对称棱台近似于照相机镜头捕获的场景视锥,可用于度量镜头的尺寸。

img

视场角与裁剪窗口高度关系:

\[\tag{23} \tan ({\theta\over 2})={height/2\over z_{prp}-z_{vp}} \]

于是,裁剪窗口高度:

\[\tag{24} height=2(z_{prp}-z_{vp})\tan ({\theta\over 2}) \]

再利用裁剪窗口宽高比aspect,就能得到宽度:\(width=aspect\cdot height\)

img

对称棱台观察体经透视投影变换后,变成矩形平行管道观察体,变换后的点的范围限制在平行管道观察体内:

img

斜透视投影棱台

如果透视投影观察体的中心线不垂直于观察平面,则得到一个斜棱台(oblique frustum)。

斜透视投影 = 错切 + 透视变换

斜棱台顶视图:

img

斜棱台投影观察体,可通过相对于z轴的x方向、y方向错切(参见三维错切)变换成对称棱台。

为计算方便,将投影参考点设为观察原点,即\((x_{prp},y_{prp},z_{prp})=(0,0,0)\). 可设错切矩阵:

\[\tag{24} \begin{aligned} M_{zshear}=\begin{bmatrix} 1 & 0 & sh_{zx} & 0\\ 0 & 1 & sh_{zy} & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \end{aligned} \]

如果观察平面 = 近裁剪平面(即\(z_{vp}=z_{near}\)),则透视投影矩阵可进一步简化。

∵错切将裁剪窗口\((xw_{min},xw_{max},z_{near})\)中心移到观察平面原点\((0,0,z_{near})\)

∴错切参数\(sh_{zx},sh_{zy}\)满足:

\[\tag{25} \begin{bmatrix} 0\\ 0\\ z_{near}\\ 1 \end{bmatrix}= M_{zshear}\cdot \begin{bmatrix} {xw_{min}+xw_{max}\over 2}\\ {yw_{min}+yw_{max}\over 2}\\ z_{near}\\ 1 \end{bmatrix} \]

∴有

\[\tag{26} \begin{aligned} sh_{zx}&=-{xw_{min}+xw_{max}\over 2z_{near}}\\ sh_{zy}&=-{yw_{min}+yw_{max}\over 2z_{near}} \end{aligned} \]

  • 简化(对称)透视投影矩阵

当投影参考点位于观察原点,且近裁剪平面与观察平面重合(OpenGL默认)时,则透视投影变换矩阵(22)可简化为:

\[\tag{27} M_{pers}=\begin{bmatrix} -z_{near} & 0 & 0 & 0\\ 0 & -z_{near} & 0 & 0\\ 0 & 0 & s_z & t_z\\ 0 & 0 & -1 & 0 \end{bmatrix} \]

其中,z坐标缩放和平移参数\(s_z, t_z\)由规范化确定。\(h=z_{prp}-z=-z\)

  • 简化斜透视投影矩阵

将简化后的透视矩阵(27)和错切矩阵(24)合并,可得到将场景中坐标转换为齐次正交坐标系的斜透视投影矩阵。该变换中,投影参考点是观察原点,近裁剪平面是观察平面:

\[\tag{28} \begin{aligned} M_{oblique\_pers}&=M_{pers}\cdot M_{zshear}\\ &=\begin{bmatrix} -z_{near} & 0 & {xw_{min}+xw_{max}\over 2} & 0\\ 0 & -z_{near} & {yw_{min}+yw_{max}\over 2} & 0\\ 0 & 0 & s_z & t_z\\ 0 & 0 & -1 & 0 \end{bmatrix} \end{aligned} \]

如果裁剪窗口关于观察原点对称,即\(xw_{max}=-xw_{min},yw_{max}=-yw_{min}\),则棱台观察体是对称的,(28)可简化为(27)(无需错切,因为投影参考点位于观察原点)。

透视投影的规范化变换

透视投影最后一步:棱台观察体(矩形平行管道,坐标符合右手系)\(\xrightarrow{规范化}\)规范化观察体(对称立方体,坐标符合左手系)。

透视投影规范化 = 平行管道观察体的正交投影

规范化示意图(近裁剪平面作为观察平面):

img

规范化变换中,矩形平行管道中心线\(z_{view}\),在x、y方向不再需要平移,只需要相对于原点的x、y缩放。xy规范化缩放矩阵:

\[\tag{29} M_{xyscale}=\begin{pmatrix} s_x & 0 & 0 & 0\\ 0 & s_y & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{pmatrix} \]

将(28)(29)合并,生成透视投影变换的规范化矩阵:

\[\tag{30} \begin{aligned} M_{norm\_pers}&=M_{xyscale}\cdot M_{oblique\_pers}\\ &=\begin{pmatrix} s_x & 0 & 0 & 0\\ 0 & s_y & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} -z_{near} & 0 & {xw_{min}+xw_{max}\over 2} & 0\\ 0 & -z_{near} & {yw_{min}+yw_{max}\over 2} & 0\\ 0 & 0 & s_z & t_z\\ 0 & 0 & -1 & 0 \end{pmatrix}\\ &=\begin{pmatrix} -z_{near}s_x & 0 & \frac{xw_{min}+xw_{max}}{2}s_x & 0\\ 0 & -z_{near}s_y & \frac{yw_{min}+yw_{max}}{2}s_y & 0\\ 0 & 0 & s_z & t_z\\ 0 & 0 & -1 & 0 \end{pmatrix} \end{aligned} \]

(30)对应的规范化变换:

\[\tag{31} \begin{pmatrix} x_h\\ y_h\\ z_h\\ h \end{pmatrix} =M_{norm\_pers}\cdot \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} \]

\(P(x,y,z)\)的投影坐标\(P'(x_p,y_p,z_p)\)

\[\begin{aligned} x_p&=\frac{x_h}{h}=\frac{-s_xz_{near}x+s_x(xw_{min}+xw_{max})/2}{-z}\\ y_p&=\frac{y_h}{h}=\frac{-s_yz_{near}x+s_y(yw_{min}+yw_{max})/2}{-z}\\ z_p&=\frac{z_h}{h}=\frac{s_zz+t_z}{-z} \end{aligned} \]

其中,\(h=-z\)

如何确定参数\(s_x,s_y,s_z,t_z\)

坐标映射:\((xw_{min},yw_{min},z_{near})\xrightarrow{}(-1,-1,-1), (xw_{max},yw_{max},z_{far})\xrightarrow{}(1,1,1)\).

\(s_x,s_y\)分别将长度\(xw_{max}-xw_{min},yw_{max}-yw_{min}\)放缩为新长度2,2

\[\begin{aligned} s_x&=\frac{2}{xw_{max}-xw_{min}},\\ s_y&=\frac{2}{yw_{max}-yw_{min}} \end{aligned} \]

\(s_z,t_z\)将输入坐标\(z_{near},z_{far}\)分别转换为\(-1,1\)
∴需满足

\[\begin{aligned} -1&=\frac{s_zz_{near}+t_z}{-z_{near}}\\ 1&=\frac{s_zz_{far}+t_z}{-z_{far}} \end{aligned} \]

∴有

\[\begin{aligned} s_z&=\frac{z_{near}+z_{far}}{z_{near}-z_{far}},\\ t_z&=\frac{-2z_{near}z_{far}}{z_{near}-z_{far}} \end{aligned} \]

∴代入(30)可得

\[M_{norm\_pers}=\begin{pmatrix} \frac{-2z_{near}}{xw_{max}-xw_{min}} & 0 & \frac{xw_{min}+xw_{max}}{xw_{max}-xw_{min}} & 0\\ 0 & \frac{-2z_{near}}{yw_{max}-yw_{min}} & \frac{yw_{min}+yw_{max}}{yw_{max}-yw_{min}} & 0\\ 0 & 0 & \frac{z_{near}+z_{far}}{z_{near}-z_{far}} & \frac{-2z_{near}z_{far}}{z_{near}-z_{far}}\\ 0 & 0 & -1 & 0 \end{pmatrix} \]

这就是透视投影(包括规范化)矩阵.

注意:该投影矩阵对应模型与OpenGL约定一致,包括
1)观察坐标系为右手系统,规范化坐标系为左手系统;
2)投影参考点位于观察原点,观察平面位于近裁剪平面;
3)远、近裁剪平面关系:\(z_{far}<z_{near}<0\)(包含符号).

posted @ 2024-04-24 13:51  明明1109  阅读(842)  评论(0编辑  收藏  举报