投影矩阵推导

games101 https://sites.cs.ucsb.edu/~lingqi/teaching/resources/GAMES101_Lecture_04.pdf
https://www.cnblogs.com/leixinyue/p/11166135.html
(http://glasnost.itcarlow.ie/~powerk/GeneralGraphicsNotes/projection/perspective_projection.html)

正交投影

描述: 长方体.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QX0BAhIl-1635505648983)(./images/000.png)]

  • X轴: left,right
  • Y轴: top,bottom
  • Z轴: near,far

M o r t h o = [ 2 r − l 0 0 − r + l 2 0 2 t − b 0 − t + b 2 0 0 2 f − n − n + f 2 0 0 0 1 ] M_{ortho} = \left[ \begin{matrix} \frac{2}{r-l} & 0 & 0 & -\frac{r+l}{2} \\ 0 & \frac{2}{t-b} & 0 & -\frac{t+b}{2}\\ 0 & 0 & \frac{2}{f-n} & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \\ \end{matrix} \right] Mortho=rl20000tb20000fn202r+l2t+b2n+f1

透视投影

1 投影到近平面
  1. 首先挤压视锥到长方体
  2. 做一次正交投影
    请添加图片描述

视锥挤压为长方体, 也就相当于: 把视锥内的点都投影到视锥的近平面,z值暂时不考虑
设视锥内的点 p ( x , y , z ) p(x,y,z) p(x,y,z),映射到近投影面之后 p ′ ( x ′ , y ′ , z ′ ) p'(x',y',z') p(x,y,z)

请添加图片描述

这里是z的负轴,所以z是负的.

这种映射关系满足相似三角形,可以得出:
x ′ = n − z x y ′ = n − z y z ′ = ? x' = \frac{n}{-z} x \\ y' = \frac{n}{-z} y \\ z' = ? x=znxy=znyz=?

$ p = (x,y,z)$, p ′ = ( x ′ , y ′ , z ′ ) p'=(x',y',z') p=(x,y,z)

这里的映射可以用其次转矩阵表示为:
M = [ n 0 0 0 0 n 0 0 ? ? ? ? 0 0 − 1 0 ] M = \left[ \begin{matrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & -1 & 0 \\ \end{matrix} \right] M=n0?00n?000?100?0

投影后点的其次坐标形式:
p ′ = M p = [ n 0 0 0 0 n 0 0 ? ? ? ? 0 0 − 1 0 ] [ x y z 1 ] = [ n x n y ? − z ] p'=Mp=\left[ \begin{matrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & -1 & 0 \\ \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1 \\ \end{matrix} \right] = \left[ \begin{matrix} nx \\ ny \\ ? \\ -z \\ \end{matrix} \right] p=Mp=n0?00n?000?100?0xyz1=nxny?z

转换成普通点,同除第四个分量,这一步称为透视除法
p ′ ( x ′ , y ′ , z ′ ) = ( n − z x , n − z y , ? ) p'(x',y',z')=(\frac{n}{-z} x, \frac{n}{-z} y, ?) p(x,y,z)=(znx,zny,?)

2 存储深度

到目前位置,所有点的深度信息未知, 如果没有相对深度信息,以后将无法去除隐藏的表面。
因为深度信息和 x , y x,y x,y无关,所以矩阵第三行一定是 ( 0 , 0 , A , B ) (0, 0, A, B) (0,0,A,B),
因此投影后的深度可以表示为:
z ′ = z A + B − z z' = \frac{zA+B}{-z} z=zzA+B

由两个关键已知条件:

  • 任何近平面的点深度都会被映射到 -1
  • 任何远平面的点深度都会被映射到 +1

− A n + B n = − 1 − A f + B f = 1 \frac{-An + B}{n} = -1 \\ \frac{-Af+B}{f} = 1 nAn+B=1fAf+B=1

可以得出:
A = − f + n f − n B = − 2 f n f − n A = -\frac{f+n}{f-n} \\ B= \frac{-2fn}{f-n} A=fnf+nB=fn2fn

所以,变换矩阵目前变为:
M = [ n 0 0 0 0 n 0 0 0 0 − f + n f − n − − 2 f n f − n 0 0 − 1 0 ] M = \left[ \begin{matrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & -\frac{f+n}{f-n} & -\frac{-2fn}{f-n} \\ 0 & 0 & -1 & 0 \end{matrix} \right] M=n0000n0000fnf+n100fn2fn0

3、CVV (Canonical View Volume)

为了提高裁剪效率,我们希望修改变换后的视图体积的形状,使其独立于相机属性。这将称为规范视图体积(CVV)。这个变换可以通过下面这个矩阵完成。
N = [ 2 r − l 0 0 − r + l r − l 0 2 t − b 0 − t + b t − b 0 0 1 0 0 0 0 1 ] N = \left[ \begin{matrix} \frac{2}{r-l} & 0 & 0 & -\frac{r+l}{r-l} \\ 0 & \frac{2}{t-b} & 0 & -\frac{t+b}{t-b} \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] N=rl20000tb2000010rlr+ltbt+b01

4、最后矩阵

将该归一化矩阵与透视变换矩阵相乘得到透视投影矩阵。
P = N ∗ M = [ 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 = N*M = \left[ \begin{matrix} \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{matrix} \right] P=NM=rl2n0000tb2n00rlr+ltbt+bfnf+n100fn2fn0

// three.js/Matrix4.js
function makePerspective( left, right, top, bottom, near, far ) {
	const te = this.elements;
	const x = 2 * near / ( right - left );
	const y = 2 * near / ( top - bottom );

	const a = ( right + left ) / ( right - left );
	const b = ( top + bottom ) / ( top - bottom );
	const c = - ( far + near ) / ( far - near );
	const d = - 2 * far * near / ( far - near );

	te[ 0 ] = x;	te[ 4 ] = 0;	te[ 8 ] = a;	te[ 12 ] = 0;
	te[ 1 ] = 0;	te[ 5 ] = y;	te[ 9 ] = b;	te[ 13 ] = 0;
	te[ 2 ] = 0;	te[ 6 ] = 0;	te[ 10 ] = c;	te[ 14 ] = d;
	te[ 3 ] = 0;	te[ 7 ] = 0;	te[ 11 ] = - 1;	te[ 15 ] = 0;
	return this;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值