Chapter 4 Transforms

(个人笔记,由于刚开始学习再加上英语不太好,所以有的地理解的可能不太对,望指正)

Chapter 4 Transforms

基础变换

仿射变换的特点是保证了平行关系,但是长度跟角度可能发生变化。

各种变换操作的描述:

在这里插入图片描述

其中正交投影是正交的。。。

Basic Transforms

Translation

T ( t ) = T ( t x , t y , t z ) = ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) T − 1 ( t ) = T ( − t ) T(t) = T(t_x, t_y, t_z) = \begin{pmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \\ \end{pmatrix} \\ \qquad \\ \qquad T^{-1}(t) = T(-t) T(t)=T(tx,ty,tz)=100001000010txtytz1T1(t)=T(t)

Rotation

旋转会保持点之间的距离以及handness

二维旋转

u = ( r c o s ( θ + ϕ ) r s i n ( θ + ϕ ) ) = ( r ( c o s θ c o s ϕ − s i n θ c o s ϕ ) r ( s i n θ c o s ϕ + s i n ϕ c o s θ ) ) = ( c o s ϕ − s i n ϕ s i n ϕ c o s ϕ ) ( r c o s θ r s i n θ ) = R ( ϕ ) v u = \begin{pmatrix} rcos(\theta + \phi) \\ rsin(\theta + \phi) \end{pmatrix} = \begin{pmatrix} r(cos\theta cos\phi - sin\theta cos\phi) \\ r(sin\theta cos\phi + sin\phi cos\theta) \end{pmatrix} = \begin{pmatrix} cos \phi & -sin\phi \\ sin \phi & cos \phi \end{pmatrix} \begin{pmatrix} rcos\theta \\ rsin\theta \end{pmatrix} = R(\phi)v u=(rcos(θ+ϕ)rsin(θ+ϕ))=(r(cosθcosϕsinθcosϕ)r(sinθcosϕ+sinϕcosθ))=(cosϕsinϕsinϕcosϕ)(rcosθrsinθ)=R(ϕ)v

三维旋转

R x ( ϕ ) = ( 1 0 0 0 0 c o s ϕ − s i n ϕ 0 0 s i n ϕ c o s ϕ 0 0 0 0 1 ) , R y ( ϕ ) = ( c o s ϕ 0 s i n ϕ 0 0 1 0 0 − s i n ϕ 0 c o s ϕ 0 0 0 0 1 ) , R z ( ϕ ) = ( c o s ϕ − s i n ϕ 0 0 s i n ϕ c o s ϕ 0 0 0 0 1 0 0 0 0 1 ) R_x(\phi) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & cos\phi & -sin\phi & 0 \\ 0 & sin\phi & cos\phi & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}, \\ R_y(\phi) = \begin{pmatrix} cos\phi & 0 & sin\phi & 0 \\ 0 & 1 & 0 & 0 \\ -sin\phi & 0 & cos\phi & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}, \\ R_z(\phi) = \begin{pmatrix} cos\phi & -sin\phi & 0 & 0 \\ sin\phi & cos\phi & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} Rx(ϕ)=10000cosϕsinϕ00sinϕcosϕ00001,Ry(ϕ)=cosϕ0sinϕ00100sinϕ0cosϕ00001,Rz(ϕ)=cosϕsinϕ00sinϕcosϕ0000100001

三维旋转矩阵的迹(trace)都为:

t r ( R ) = 1 + 2 c o s ϕ tr(R) = 1 + 2cos\phi tr(R)=1+2cosϕ

所有旋转矩阵的行列式值都为1并且都是正交的。

R i − 1 ( ϕ ) = R i ( − ϕ ) R_i^{-1}(\phi) = R_i(-\phi) Ri1(ϕ)=Ri(ϕ)

例子:绕一点旋转

在这里插入图片描述

旋转公式:

X = T ( p ) R z ( ϕ ) T ( − p ) X = T(p)R_z(\phi)T(-p) X=T(p)Rz(ϕ)T(p)

Scaling

S ( s ) = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) S − 1 ( s ) = S ( 1 / s x , 1 / s y , 1 / s z ) S(s) = \begin{pmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 &1 \end{pmatrix} \\ \qquad \\ S^{-1}(s) = S(1/s_x, 1/s_y, 1/s_z) S(s)=sx0000sy0000sz00001S1(s)=S(1/sx,1/sy,1/sz)

反射变换可以通过-1作为参数进行缩放,反射变换可能导致顶点顺序发生变化。要判断某个变换是否是反射,则计算左上3x3矩阵的行列式,如果为负则是反射变换。

Shearing

三维空间下Shearing变换共有六种: H x y ( s ) , H x z ( s ) , H y x ( s ) , H y z ( s ) , H z x ( s ) , H z y ( s ) H_{xy}(s), H_{xz}(s), H_{yx}(s), H_{yz}(s), H_{zx}(s), H_{zy}(s) Hxy(s),Hxz(s),Hyx(s),Hyz(s),Hzx(s),Hzy(s)其中第一个脚注表示是哪个维度值发生变化,第二个值是哪个维度进行shearing操作,也就是乘以哪个维度的值,以 H x z ( s ) H_{xz}(s) Hxz(s)为例:

在这里插入图片描述

变换矩阵为:

改变换产生了一个点 ( p x + s p z , p y , p z ) (p_x + sp_z, p_y, p_z) (px+spz,py,pz)
shearing变换的逆变换: H i j − 1 ( s ) = H i j ( − s ) H_{ij}^{-1}(s)=H_{ij}(-s) Hij1(s)=Hij(s)

The Rigid-Body Transform

只包含平移跟旋转的变换矩阵称为刚体变换。

$$
X=T(t)R=\begin{pmatrix}
R & T \
0 & 1 \
\end{pmatrix}

x^{-1}=(T(t)R)^{-1}=R^{-1}T(t)^{-1}=R^TT(-t)

$$

Normal Transform

M n = ( A − 1 ) T A − 1 = 1 ∣ A ∣ A ∗ M_n = (A^{-1})^T \\ A^{-1}=\frac{1}{|A|}A^* Mn=(A1)TA1=A1A

法线变化只需要计算左上3x3的部分

Special Matrix Transforms and Operations

x-pitch, y-head, z-roll

Extracting Parameters from the Euler Transform

$$
E(h, p, r) = \begin{pmatrix}
e_{00} & e_{01} & e_{02} \
e_{10} & e_{11} & e_{12} \
e_{20} & e_{21} & e_{22}
\end{pmatrix} = R_z®R_x§R_y(h)
\ \qquad
\ \qquad
\ = \begin{pmatrix}
cosrcosh-sinrsinpsinh & -sinrcosp & cosrsinh+sinrsinpcosh \
sinr
cosh+cosrsinpsinh & cosrcosp & sinrsinh-cosrsinpcosh \
-cospsinh & sinp & cospcosh
\end{pmatrix}

\\ \qquad
\\ \qquad

\\ sinp = e_{21} \\
\frac{e_{01}}{e_{11}} = \frac{-sinr}{cosr}=-tanr\\
\frac{e_{20}}{e_{22}} = \frac{-sinh}{cosh}=-tanh\\
可以得出:\\
h=atan(-e_{20}, e_{22})\\
p=arcsin(e_{21})\\
r=atan(-e_{01},e_{11})

$$

万向锁:https://blog.csdn.net/hanjuefu5827/article/details/80659343

Rotation about an Arbitrary Axis

绕任意轴r旋转:

在这里插入图片描述

其中M矩阵:

M = ( r T s T t T ) M = \begin{pmatrix} r^T \\ s^T \\ t^T \end{pmatrix} M=rTsTtT

绕任意轴旋转矩阵:

X = M T R x ( α ) M X=M^TR_x(\alpha)M X=MTRx(α)M

Quaternions

定义:

q ^ = ( q v → , q w ) = i q x + j q y + k q z + q w = q v → + q w q v → = i q x + j q y + k q z = ( q z , q y , q z ) , i 2 = j 2 = k 2 = − 1 , j k = − k y = i , k i = − i k = j , i j = − j i = k \hat{q}=(\overrightarrow{q_v}, q_w)=iq_x+jq_y+kq_z+q_w=\overrightarrow{q_v}+q_w \\ \overrightarrow{q_v}=iq_x+jq_y+kq_z=(q_z,q_y,q_z),\\ i^2=j^2=k^2=-1,\\ jk=-ky=i,ki=-ik=j,ij=-ji=k q^=(qv ,qw)=iqx+jqy+kqz+qw=qv +qwqv =iqx+jqy+kqz=(qz,qy,qz),i2=j2=k2=1,jk=ky=i,ki=ik=j,ij=ji=k

乘法:

q ^ r ^ = ( i q x + j q y + k q z + q w ) ( i r x + j r y + k r z + r w ) = i ( q y r z − q z r y + r w q x + q w r x ) + j ( q z r x − q x r z + r w q y + q w r y ) + k ( q x r y − q y r x + r w q z + q w r z ) + q w r w − q x r x − q y r y − q z r z ‘ = ( q v → ∗ r v → + r w q v → + q w r v → ,   q w r w − q v → ∙ r v → ) \hat{q}\hat{r}=(iq_x+jq_y+kq_z+q_w)(ir_x+jr_y+kr_z+r_w)\\ =i(q_yr_z-q_zr_y+r_wq_x+q_wr_x)+j(q_zr_x-q_xr_z+r_wq_y+q_wr_y)+k(q_xr_y-q_yr_x+r_wq_z+q_wr_z)+q_wr_w-q_xr_x-q_yr_y-q_zr_z\\` =(\overrightarrow{q_v}*\overrightarrow{r_v} + r_w\overrightarrow{q_v}+q_w\overrightarrow{r_v},\ q_wr_w-\overrightarrow{q_v}\bullet \overrightarrow{r_v}) q^r^=(iqx+jqy+kqz+qw)(irx+jry+krz+rw)=i(qyrzqzry+rwqx+qwrx)+j(qzrxqxrz+rwqy+qwry)+k(qxryqyrx+rwqz+qwrz)+qwrwqxrxqyryqzrz=(qv rv +rwqv +qwrv , qwrwqv rv )

共轭(conjugate):

$$
\hat{q}*=(\overrightarrow{q_v},q_w)=(-\overrightarrow{q_v},q_w)\
(\hat{q}*)
=\hat{q}\
(\hat{q}+\hat{r})*=\hat{q}+\hat{r}^\
(\hat{q}\hat{r})*=\hat{r}\hat{q}^

$$

模(norm):

n ( q ^ ) = q ^ ∗ q ^ = q v → ∙ q v → + q w 2 = q x 2 + q y 2 + q z 2 + q w 2 n ( q ^ ∗ ) = n ( q ^ ) n ( q ^ r ^ ) = n ( q ^ ) n ( r ^ ) n(\hat{q})=\sqrt{\hat{q}^*\hat{q}}=\sqrt{\overrightarrow{q_v} \bullet \overrightarrow{q_v}+q_w^2}\\ =\sqrt{q_x^2+q_y^2+q_z^2+q_w^2}\\ \\n(\hat{q}^*)=n(\hat{q}) \\n(\hat{q}\hat{r})=n(\hat{q})n(\hat{r}) n(q^)=q^q^ =qv qv +qw2 =qx2+qy2+qz2+qw2 n(q^)=n(q^)n(q^r^)=n(q^)n(r^)

Identity:

i ^ = ( 0 → , 1 ) \hat{i}=(\overrightarrow{0}, 1) i^=(0 ,1)

逆:

q ^ − 1 = 1 n ( q ^ ) 2 q ^ ∗ \hat{q}^{-1}=\frac{1}{n(\hat{q})^2}\hat{q}^* q^1=n(q^)21q^

对于单位四元素它的模为1,所以他可以被写成:

q ^ = ( s i n ϕ u q , c o s ϕ ) ∣ ∣ u q ∣ ∣ = 1 \hat{q}=(sin\phi u_q, cos\phi)\\ ||u_q||=1 q^=(sinϕuq,cosϕ)uq=1

根据欧拉公式,也可以写成:

q ^ = s i n ϕ u q + c o s ϕ = e ϕ u q l o g ( q ^ ) = l o g ( e ϕ u q ) = ϕ u q q ^ t = ( s i n ϕ u q + c o s ϕ ) t = e ϕ t u q = s i n ( ϕ t ) u q + c o s ( ϕ t ) \hat{q}=sin\phi u_q+cos\phi=e^{\phi u_q}\\ log(\hat{q})=log(e^{\phi u_q})=\phi _uq \hat{q}^t=(sin\phi u_q+cos\phi)^t=e^{\phi tu_q}=sin(\phi t)u_q+cos(\phi t) q^=sinϕuq+cosϕ=eϕuqlog(q^)=log(eϕuq)=ϕuqq^t=(sinϕuq+cosϕ)t=eϕtuq=sin(ϕt)uq+cos(ϕt)

Quaternion Transforms

假定一个点或者是向量 p = ( p x   p y   p z   p w ) T p=(p_x \ p_y \ p_z \ p_w)^T p=(px py pz pw)T,一个单位四元数 q ^ = ( s i n ϕ u q , c o s ϕ ) \hat{q}=(sin\phi u_q,cos\phi) q^=(sinϕuq,cosϕ),可以证明 q ^ p ^ q ^ − 1 \hat{q}\hat{p}\hat{q}^{-1} q^p^q^1可以表示为 p ^ \hat{p} p^绕轴 u q u_q uq旋转 2 ϕ 2\phi 2ϕ,由于是单位四元数所以 q ^ − 1 = q ^ ∗ \hat{q}^{-1}=\hat{q}^* q^1=q^

对于任何非零实数诚意 q ^ \hat{q} q^任然表示相同的变换,这意味着 q ^ \hat{q} q^ − q ^ -\hat{q} q^表示相同的旋转。

对于多个旋转,可以通过结合律:

r ^ ( q ^ p ^ q ^ ∗ ) r ^ ∗ = ( r ^ q ^ ) p ^ ( q ^ ∗ r ^ ∗ ) \hat{r}(\hat{q}\hat{p}\hat{q}^*)\hat{r}^*=(\hat{r}\hat{q})\hat{p}(\hat{q}^*\hat{r}^*) r^(q^p^q^)r^=(r^q^)p^(q^r^)

Matrix Conversion

M q = ( 1 − s ( q y 2 + q z 2 ) s ( q x q y − q w q z ) s ( q x q z + q w q y ) 0 s ( q x q y + q w q z ) 1 − s ( q x 2 + q z 2 ) s ( q y q z − q w q x ) 0 s ( q x q z − q w q y ) s ( q y q z + q w q x ) 1 − s ( q x 2 + q y 2 ) 0 0 0 0 0 ) M^q = \begin{pmatrix} 1-s(q_y^2+q_z^2) & s(q_xq_y-q_wq_z) & s(q_xq_z+q_wq_y) & 0 \\ s(q_xq_y+q_wq_z) & 1-s(q_x^2+q_z^2) & s(q_yq_z-q_wq_x) & 0 \\ s(q_xq_z-q_wq_y) & s(q_yq_z+q_wq_x) & 1-s(q_x^2+q_y^2) & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}\\ Mq=1s(qy2+qz2)s(qxqy+qwqz)s(qxqzqwqy)0s(qxqyqwqz)1s(qx2+qz2)s(qyqz+qwqx)0s(qxqz+qwqy)s(qyqzqwqx)1s(qx2+qy2)00000

其中 s = 2 / ( n ( q ^ ) ) 2 s=2/(n(\hat{q}))^2 s=2/(n(q^))2
对于单位四元数,可以简化为

M q = ( 1 − 2 ( q y 2 + q z 2 ) 2 ( q x q y − q w q z ) 2 ( q x q z + q w q y ) 0 2 ( q x q y + q w q z ) 1 − 2 ( q x 2 + q z 2 ) 2 ( q y q z − q w q x ) 0 2 ( q x q z − q w q y ) 2 ( q y q z + q w q x ) 1 − 2 ( q x 2 + q y 2 ) 0 0 0 0 0 ) M^q = \begin{pmatrix} 1-2(q_y^2+q_z^2) & 2(q_xq_y-q_wq_z) & 2(q_xq_z+q_wq_y) & 0 \\ 2(q_xq_y+q_wq_z) & 1-2(q_x^2+q_z^2) & 2(q_yq_z-q_wq_x) & 0 \\ 2(q_xq_z-q_wq_y) & 2(q_yq_z+q_wq_x) & 1-2(q_x^2+q_y^2) & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}\\ Mq=12(qy2+qz2)2(qxqy+qwqz)2(qxqzqwqy)02(qxqyqwqz)12(qx2+qz2)2(qyqz+qwqx)02(qxqz+qwqy)2(qyqzqwqx)12(qx2+qy2)00000

球面线性插值

根据 q ^ \hat{q} q^ r ^ \hat{r} r^以及参数 t ∈ [ 0 , 1 ] t\in[0,1] t[0,1]求一个差值四元数

s ^ ( q ^ , r ^ , t ) = ( r ^ q ^ − 1 ) t q ^ \hat{s}(\hat{q}, \hat{r}, t)=(\hat{r}\hat{q}^{-1})^t\hat{q} s^(q^,r^,t)=(r^q^1)tq^

实际计算中使用

s ^ ( q ^ , r ^ , t ) = s l e r p ( q ^ , r ^ , t ) = s i n ( ϕ ( 1 − t ) ) s i n ϕ q ^ + s i n ( ϕ t ) s i n ϕ r ^ \hat{s}(\hat{q}, \hat{r}, t)=slerp(\hat{q}, \hat{r}, t)\\ =\frac{sin(\phi(1-t))}{sin\phi}\hat{q}+\frac{sin(\phi t)}{sin\phi}\hat{r} s^(q^,r^,t)=slerp(q^,r^,t)=sinϕsin(ϕ(1t))q^+sinϕsin(ϕt)r^

其中 c o s ϕ = q x r x + q y r y + q z r z + q w r w cos\phi=q_xr_x+q_yr_y+q_zr_z+q_wr_w cosϕ=qxrx+qyry+qzrz+qwrw

将一个向量旋转到另一个向量

将限量 s s s旋转到向量 t t t:首先归一化 s s s t t t,然后计算旋转轴 u = ( s ∗ t ) / ∣ ∣ s ∗ t ∣ ∣ u=(s*t)/||s*t|| u=(st)/st,第三设 e = s ∙ t = c o s ( 2 ϕ )     ∣ ∣ s ∗ t ∣ ∣ = s i n ( 2 ϕ ) e=s\bullet t=cos(2\phi) \ \ \ ||s*t||=sin(2\phi) e=st=cos(2ϕ)   st=sin(2ϕ),其中 2 ϕ 2\phi 2ϕ s s s t t t的夹角。那么这个四元数可以表示为 q ^ = ( s i n ϕ u , c o s ϕ ) \hat{q}=(sin\phi u,cos\phi) q^=(sinϕu,cosϕ),化简可得:

q ^ = ( s i n ϕ s i n 2 ϕ ( s ∗ t ) , c o s ϕ ) = ( q v , q w ) = ( 1 2 ( 1 + e ) ( s ∗ t ) , 2 ( 1 + e ) 2 ) \hat{q}=(\frac{sin\phi}{sin2\phi}(s*t), cos\phi)\\ =(q_v,q_w)=(\frac{1}{\sqrt{2(1+e)}}(s*t),\frac{\sqrt{2(1+e)}}{2}) q^=(sin2ϕsinϕ(st),cosϕ)=(qv,qw)=(2(1+e) 1(st),22(1+e) )

顶点混合(Vertex Blending)

皮肤表面顶点收到多个骨骼影响,经过动画变换最终位置的基本公式是:

u ( t ) = ∑ i = 0 n − 1 ω i B i ( t ) M i − 1 p ,    w h e r e ∑ i = 0 n − 1 = 1 ,    ω i ≥ 0 u(t)=\sum_{i=0}^{n-1}\omega_iB_i(t)M_i^{-1}p,\ \ where \sum_{i=0}^{n-1}=1,\ \ \omega_i\ge 0 u(t)=i=0n1ωiBi(t)Mi1p,  wherei=0n1=1,  ωi0

其中 ω i \omega_i ωi表示第 i i i块骨骼对于顶点 p p p的影响权重。 M i M_i Mi表示从骨骼的本地坐标转换到世界坐标的变换矩阵。 B i ( t ) B_i(t) Bi(t)表示第 i i i个骨骼随着物体动画的进行所需要的世界变换矩阵,通常来讲是一系列矩阵的结合,比如说是之前各级骨骼的变换以及本地动画矩阵(什么鬼。。。)

每一个骨骼将一个顶点根据每一帧中的索引变换到一个位置,最终的位置是根据一系列计算出的顶点差值得到的。在一些说明中 M i M_i Mi会作为 B i ( t ) B_i(t) Bi(t)的一部分,在实际中也是。发现的计算也可以使用上述公式,需要将 B i ( t ) M i B_i(t)M_i Bi(t)Mi替换成逆的转置。

在GPU计算中,mesh顶点会作为静态的缓存一次性发送给GPU,这部分数据可以被GPU反复使用,每次要变化的只有骨骼的矩阵。骨骼变换也可以储存到纹理当中,每一次变换如果使用四元数则只需要两个纹理元素来表示旋转的话。

顶点混合的缺点是会出现一些折叠(folding)、扭曲(twisting)和自相交(self intersection)。解决的方法之一是使用对偶四元数(dual quaternions),它可以很好地避免肢体的糖纸扭曲(candy wrapper twist)

变形(Morphing)

变形效果主要有两个主要问题:顶点对应(vertex correspondence)问题和插值问题。对于两个顶点数量不同,拓扑结构不同,网格连接关系不同的模型进行变形首先要做的就是顶点对应。

如果对于一个顶点能够一一对应的模型,那么就可以进行逐顶点的插值了。对于一个时间点 t ∈ [ t 0 , t 1 ] t\in[t_0,t_1] t[t0,t1],首先计算 s = ( t − t 0 ) / ( t 1 − t 0 ) s=(t-t_0)/(t_1-t_0) s=(tt0)/(t1t0),然后就可以先行插值了:

m = ( 1 − s ) p 0 + s p 1 m=(1-s)p_0+sp_1 m=(1s)p0+sp1

Geometry Cache Playback

Projections

正交投影(Orthographic Projection)

P o = S ( s ) T ( t ) = ( 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 f − n 0 0 0 0 1 ) ( 1 0 0 − l + r 2 0 1 0 − t + b 2 0 0 1 − f + n 2 0 0 0 1 ) = ( 2 r − l 0 0 − r + l r − l 0 2 t − b 0 − t + b t − b 0 0 2 f − n − f + n f − n 0 0 0 1 ) P_o = S(s)T(t) = \begin{pmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{f-n} & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & -\frac{l+r}{2} \\ 0 & 1 & 0 & -\frac{t+b}{2} \\ 0 & 0 & 1 & -\frac{f+n}{2} \\ 0 & 0 & 0 & 1 \end{pmatrix} \\ = \begin{pmatrix} \frac{2}{r-l} & 0 & 0 & -\frac{r+l}{r-l} \\ 0 & \frac{2}{t-b} & 0 & -\frac{t+b}{t-b} \\ 0 & 0 & \frac{2}{f-n} & -\frac{f+n}{f-n} \\ 0 & 0 & 0 & 1 \end{pmatrix} Po=S(s)T(t)=rl20000tb20000fn2000011000010000102l+r2t+b2f+n1=rl20000tb20000fn20rlr+ltbt+bfnf+n1

示意图如下:

在这里插入图片描述

透视投影(Perspective Projection)

示意图如下:

在这里插入图片描述

p在投影平面上的投影q的坐标为 q = ( q x , q y , − d ) q=(q_x,q_y,-d) q=(qx,qy,d) q x q_x qx q y q_y qy的计算公式如下:

q x p x = − d p z   ⇒   q x = − d p x p z \frac{q_x}{p_x}=\frac{-d}{p_z} \ \Rightarrow \ q_x=-d\frac{p_x}{p_z} pxqx=pzd  qx=dpzpx

透视矩阵:
P p = ( 1 0 0 0 0 1 0 0 0 0 1 0 0 0 − 1 / d 0 ) P_p = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & -1/d & 0 \end{pmatrix} Pp=100001000011/d0000

变换效果如下:

在这里插入图片描述

点p的透视变换

q = P p p = ( 1 0 0 0 0 1 0 0 0 0 1 0 0 0 − 1 / d 0 ) ( p x p y p z 1 ) = ( p x p y p z − p z / d ) ⇒ ( − d p x / p z − d p y / p z − d 1 ) q = P_pp = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & -1/d & 0 \end{pmatrix} \begin{pmatrix} p_x \\ p_y \\ p_z \\ 1 \end{pmatrix} =\begin{pmatrix} p_x \\ p_y \\ p_z \\ -p_z/d \end{pmatrix} \Rightarrow \begin{pmatrix} -dp_x/p_z \\ -dp_y/p_z \\ -d \\ 1 \end{pmatrix} q=Ppp=100001000011/d0000pxpypz1=pxpypzpz/ddpx/pzdpy/pzd1

Field of view

ϕ = 2 a r c t a n ( w / ( 2 d ) ) \phi = 2arctan(w/(2d)) ϕ=2arctan(w/(2d))

其中 ϕ \phi ϕ表示field of view, w w w表示垂直于视线的物体的宽度, d d d表示距离物体的距离

透视变换

P p = ( 2 n r − l 0 − r + l r − l 0 0 2 n t − b − t + b t − b 0 0 0 f + n f − n − 2 f n f − n 0 0 1 0 ) P_p = \begin{pmatrix} \frac{2n}{r-l} & 0 & -\frac{r+l}{r-l} & 0 \\ 0 & \frac{2n}{t-b} & -\frac{t+b}{t-b} & 0 \\ 0 & 0 & \frac{f+n}{f-n} & -\frac{2fn}{f-n} \\ 0 & 0 & 1 & 0 \end{pmatrix} Pp=rl2n0000tb2n00rlr+ltbt+bfnf+n100fn2fn0

对于 f f f趋近于无穷,也可以写成

P p = ( 2 n r − l 0 − r + l r − l 0 0 2 n t − b − t + b t − b 0 0 0 1 − 2 n 0 0 1 0 ) P_p = \begin{pmatrix} \frac{2n}{r-l} & 0 & -\frac{r+l}{r-l} & 0 \\ 0 & \frac{2n}{t-b} & -\frac{t+b}{t-b} & 0 \\ 0 & 0 & 1 & -2n \\ 0 & 0 & 1 & 0 \end{pmatrix} Pp=rl2n0000tb2n00rlr+ltbt+b11002n0

在OpenGL当中会首先乘以S(1, 1, -1, 1),那么 0 < n ′ < f ′ 0<n'<f' 0<n<f得到:

P p = ( 2 n ′ r − l 0 − r + l r − l 0 0 2 n ′ t − b − t + b t − b 0 0 0 − f ′ + n ′ f ′ − n ′ − 2 f ′ n ′ f ′ − n ′ 0 0 − 1 0 ) P_p = \begin{pmatrix} \frac{2n'}{r-l} & 0 & -\frac{r+l}{r-l} & 0 \\ 0 & \frac{2n'}{t-b} & -\frac{t+b}{t-b} & 0 \\ 0 & 0 & -\frac{f'+n'}{f'-n'} & -\frac{2f'n'}{f'-n'} \\ 0 & 0 & -1 & 0 \end{pmatrix} Pp=rl2n0000tb2n00rlr+ltbt+bfnf+n100fn2fn0

根据fov可以化简为:

P p = ( c / a 0 0 0 0 c 0 0 0 0 − f ′ + n ′ f ′ − n ′ − 2 f ′ n ′ f ′ − n ′ 0 0 − 1 0 ) 其 中 a = w / h , c = 1.0 / t a n ( ϕ / 2 ) P_p = \begin{pmatrix} c/a & 0 & 0 & 0 \\ 0 & c & 0 & 0 \\ 0 & 0 & -\frac{f'+n'}{f'-n'} & -\frac{2f'n'}{f'-n'} \\ 0 & 0 & -1 & 0 \end{pmatrix} \\ 其中 a = w / h,c=1.0/tan(\phi/2) Pp=c/a0000c0000fnf+n100fn2fn0a=w/hc=1.0/tan(ϕ/2)

z-buffer的精确度

点p经过透视变换之后可得:

v = P p = ( ⋯ ⋯ d p z + e ± p z ) v=Pp=\begin{pmatrix} \cdots \\ \cdots \\ dp_z+e \\ \pm p_z \end{pmatrix} v=Pp=dpz+e±pz

其中 d = − f ′ + n ′ f ′ − n ′ d=-\frac{f'+n'}{f'-n'} d=fnf+n e = − 2 f ′ n ′ f ′ − n ′ e=-\frac{2f'n'}{f'-n'} e=fn2fn,可以得到:

z N D C = d p z + e − p z = d − e p z z_{NDC}=\frac{dp_z+e}{-p_z}=d-\frac{e}{p_z} zNDC=pzdpz+e=dpze

变换曲线:

在这里插入图片描述

为了提高深度的精确度,一个常用的方法是翻转z(reversed z),也就是使用 1.0 − z N D C 1.0-z_{NDC} 1.0zNDC。几种不同处理的对比如下:

在这里插入图片描述

对于屏幕空间的深度计算,可以使用以下公式进行remapping:

z = w ( l o g 2 ( m a x ( 1 0 − 6 , 1 + w ) ) f c − 1 ) , [ O p e n G L ] z = w l o g 2 ( m a x ( 1 0 − 6 , 1 + w ) ) f c / 2 , [ D X ] z=w(log_2(max(10^{-6}, 1+w))f_c-1), \qquad [OpenGL] \\ z=wlog_2(max(10^{-6}, 1+w))f_c/2, \qquad [DX] \\ z=w(log2(max(106,1+w))fc1),[OpenGL]z=wlog2(max(106,1+w))fc/2,[DX]

其中 w w w是顶点经过透视变换之后的 w w w值, z z z是顶点着色器中得到的 z z z值, f c = 2 / l o g 2 ( f + 1 ) f_c=2/log_2(f+1) fc=2/log2(f+1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值