頂點資料經過模型變換、相機變換轉換到觀察空間,之後渲染系統引入視椎體的概念,並通過投影變換將視椎體轉換到統一裝置座標系中,方便剪裁和後續視窗對映工作。投影變換其實就是將不同對的視錐體對映到標準裝置座標的過程,投影變換過程中實際上並未實際計算頂點的ndc座標,而是在後面齊次除法中進行,不過投影變換的整個過程與之息息相關,應該說是作為乙個目標。
一般而言,常用的視錐體有兩種, 如下圖所示。視錐體一般由6個剪裁平面決定,包括近剪裁面和遠剪裁面
可以理解為乙個立方體,中心點在中間,x,
y,z
方向的範圍[−
1,1]
(opengl中,在有些文件中描述為cvv,傻傻的分不清楚了,但是表達的意思是相同的),注意的是不同的api定義的ndc不盡相同,directx定義z
範圍為[0,
1]
,本文主要使用opengl的ndc座標範圍,不過整個推導過程相同。
轉換過程推導以opengl為準,也就是採用右手座標系,觀察方向位沿z軸負方向涉及的符號為不帶符號數,比如下文中近鄰面
z
座標
n
大於遠鄰面
f
設觀察空間中,視椎體的為[l
,r]×
[b,t
]×[f
,n]
,其中l
ndbnd
f平行視椎體 和ndc都是立方體,所以可以通過平移t(
t)和縮放s(
s)實現 , 其過程如下圖所示t(
t)將視椎體中心移動到座標系中心,平移矩陣如下: t
(t)=
⎡⎣⎢⎢
⎢⎢⎢⎢
1000
0100
0010
−l+r
2−t+
b2−n
+f21
⎤⎦⎥⎥
⎥⎥⎥⎥
s(s)
將平移後視椎體的(x
,y,z
) 轉換到[−1
,1]
區間, s(
s)=⎡
⎣⎢⎢⎢
⎢⎢2r
−l00
002t
−b00
002n
−f00
001⎤
⎦⎥⎥⎥
⎥⎥
所以轉換矩陣mo
th=s
(s)t
(t)=
⎡⎣⎢⎢
⎢⎢⎢⎢
2r−l
0000
2t−b
0000
2n−f
0r+l
r−lt
+bt−
bn+f
n−f1
⎤⎦⎥⎥
⎥⎥⎥⎥
透視投影的特徵就是投影線都會經過視點,也就是攝像機中心,一般在計算中會將視椎體的近平面z=
n
作為成像平面。投影矩陣可以直接通過投影關係以及視錐體和ndc區間的關係建立方程求教獲得,可以參考mathematics for 3d game programming and computer graphics 第五章 。不過這裡採用另外一種方式,先將透視投影的視椎體轉換為平面投影的視椎體,然後再利用平行投影的視椎體獲得透視投影矩陣。
假設空間中一點的座標為p(p
x,py
,pz)
,其在$z = n 上的
投影點位
q(q_x , q_y,n)$ , 根據比例關係可知:⎧⎩
⎨⎪⎪⎪
⎪qx=
npzp
xqy=
npzp
yqz=
n 上述過程可以實現將空間中點轉換到2d影象中,但點q(q
x,qy
,n)
的z
保持為n
, 實際上z
應該保持[n,
f]的區間,另一方面在光柵化過程中對1
z
進行插值,所以z
的變換函式應該是1
z
的線性函式,假設z
的變換函式為
=apz
+b
由z的區間對映關係[n
,f]→
[n,f
] 以得:{n=
an+b
f=af
+b
計算可得:{a
=−nf
b=n+
f 也就是說轉換函式為qz
=−nf
pz+(
n+f)
通過上面的推導,透視投影視椎體轉換為平行投影視椎體的過程可以表達為: ⎧
⎩⎨⎪⎪
⎪⎪⎪⎪
⎪⎪qx
pz=n
pxqy
pz=n
pyqz
pz=(
n+f)
pz−n
fpz=
pz
用齊次座標表達以及轉換過程:⎡⎣
⎢⎢⎢⎢
qxpz
qypz
qzpz
pz⎤⎦
⎥⎥⎥⎥
=⎡⎣⎢
⎢⎢⎢q
xqyq
z1⎤⎦
⎥⎥⎥⎥
=⎡⎣⎢
⎢⎢⎢n
pxnp
y(n+
f)pz
−nfp
z⎤⎦⎥
⎥⎥⎥=
⎡⎣⎢⎢
⎢n00
00n0
000n
+f10
0−fn
0⎤⎦⎥
⎥⎥⎡⎣
⎢⎢⎢⎢
pxpy
pz1⎤
⎦⎥⎥⎥
⎥=mp
er→o
th⎡⎣
⎢⎢⎢⎢
pxpy
pz1⎤
⎦⎥⎥⎥
⎥
結合平行投影轉換矩陣,獲得透視投影轉換矩陣: m
pre=
moth
mper
→oth
即:mpre=
⎡⎣⎢⎢
⎢⎢⎢⎢
2nr−
l000
02nt
−b00
r+lr
−lt+
bt−b
n+fn
−f10
02nf
n−f0
⎤⎦⎥⎥
⎥⎥⎥⎥
canonical view volume(cvv) 與 normalized device coordinaate(ndc)的關係,參考了幾本書中的描述,其實都有點混淆,包括rtr中也會同時出現這兩個概念,不過最終還是沒弄明白怎麼個區分方法,暫且當做乙個概念吧
z
投影前後的計算公式,好幾本書都是直接給出結論的,最後還是在mathematics for 3d game programming and computer graphics中找到具體的流程,也可以參考另外一篇ppt
總之,本文會有很多描述不清晰或者弄錯的地方,遇到的請幫忙指教。
投影矩陣推導
投影變換是計算機圖形學的基礎,理解並推導投影矩陣也是很有必要的。正交投影比較簡單,沒有透視失真效果 近大遠小 而透視投影比較符合人類的眼睛感知,平行線在遠處會相交於一點。投影是通過乙個4x4的矩陣來完成的,將視錐對映成標準觀察體 齊次裁剪空間 opengl採用的是右手座標系,z軸朝螢幕向外,因此觀察...
墨卡托投影推導
為啥一堆人都說墨卡托投影是從圓心向圓柱面發射線,反正我覺得不是那樣,不然公式顯然就不對了 也可能是我馬虎 後來去wiki查了一下,找到了公式的推導.x r 0 y rln tan 4 2 qquad y r ln left tan left right right x r 0 y r ln tan ...
OpenGL 投影矩陣的推導
計算機顯示器是乙個2d平面。opengl渲染的3d場景必須以2d影象方式投影到計算機螢幕上。gl projection矩陣用於該投影變換。首先,它將所有定點資料從觀察座標轉換到裁減座標。接著,這些裁減座標通過除以w分量的方式轉換到歸一化裝置座標 ndc 本文主要推導正交投影矩陣和透視投影矩陣。注意n...