天天看點

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

圖形學投影

  • 一、概述
  • 二、圖形學中常見投影
  • 三、投影規範化(projection normalization)
    • 規範化矩陣的數學表示
      • 1、定義:
      • 2、操作步驟:
  • 四、正交投影
  • 五、透視投影
  • 六、OpenGL中的實作
    • 1、正交投影
    • 2、透視投影

一、概述

投影可以了解為空間到平面的映射。同現實中陽光将事物投影到地面上一樣,投影變換将整個向量空間映射到它的其中一個子空間,并且在這個子空間中是恒等變換。

二、圖形學中常見投影

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

透視投影與正交投影示意圖

三、投影規範化(projection normalization)

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

使用平移和縮放變換将照相機坐标系下的頂點變換的預設的視見體(部分教程稱為視景體)的内部( [ − 1 , 1 ] 3 [-1, 1]^3 [−1,1]3,即 x , y , z x,y,z x,y,z 的取值範圍為 [ − 1 , 1 ] [-1, 1] [−1,1]),該過程稱為投影規範化(projection normalization)。

我們采用這種方法是因為最終由 GPU 執行的投影是固定的,投影規範化使我們能夠在同一繪制流水線中執行平行投影和透視投影。

規範化矩陣的數學表示

1、定義:

M n o r m a l M_{normal} Mnormal​ :規範化矩陣

T T T:平移矩陣

S S S :縮放矩陣

l l l:為視見體最左邊的坐标(Left)

r r r :為最右邊的坐标(Right)

t t t :為最頂的坐标(Top)

b b b :為最底坐标(Botton)

n n n :最近坐标(Near),由于相機是看向負 Z 軸,這裡的 n > f,且都為負數

f f f :最遠坐标(Far)

2、操作步驟:

  • 平移:把中心移到原點
  • 縮放:進行放縮進而使視見體的邊長為 2
    圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

四、正交投影

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

正交投影(orthographic projection,亦稱正投影)是平行投影的一種特殊情況,正交投影的投影線垂直于投影平面。

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

這裡定義投影平面(projection plane)為 z = 0 z = 0 z=0,根據平行投影的定義可得 點 p ( x , y , z ) p(x, y, z) p(x,y,z) 投影後得到的點 p ′ ( x p , y p , z p ) p'(x_p, y_p, z_p) p′(xp​,yp​,zp​),其 x x x, y y y 坐标保持不變 z p z_p zp​ 等于 0,是以正交投影的方程可表示為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

可得正交變換矩陣為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

轉換為齊次坐标為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

最終正交投影變換矩陣可表示為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

五、透視投影

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

透視投影(Perspective Projection),透視投影是所有投影線相交于投影中心(COP)(圖形學中指單點透視),變換後使得物品呈現出近大遠小的效果,更接近人眼觀察的結果。

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

計算透視投影步驟

  • 将透視投影的四棱台轉換為立方體
  • 重複正交投影的變換
    圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

根據相似三角形可得 y ′ = n z y , x ′ = n z x y' = \frac{n}{z} y, x' = \frac{n}{z}x y′=zn​y,x′=zn​x

轉換為齊次坐标表示,并尋找點p(x, y, z)變換之後的關系,

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

可得将視錐體轉換為立方體的變換矩陣為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

由于 近裁剪面上面的點 x x x, y y y, z z z 坐标變換後值不變,遠裁剪面的 z z z 坐标變換後值不變,變換後 x = x ′ x = x' x=x′, y = y ′ y = y' y=y′,這裡簡稱變換矩陣為 M M M,可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

近裁剪面的點變換後位置不變,且有 z z z 坐标等于 n n n,将 n n n 替換 z z z 可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

是以變換矩陣的第三行與點 p p p 的乘積為 n 2 n^2 n2,且這裡 x x x, y y y 可為任意值,可得 n 2 n^2 n2 與 x x x, y y y 無關

即變換矩陣的第三行可表示為 [ 0 , 0 , A , B ] [ 0, 0, A, B ] [0,0,A,B]

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

展開可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

将遠平面中心點 (0, 0, f) 代入可以得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

展開可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

解方程可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

綜上可得變換矩陣

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

最終透視投影變換矩陣可表示為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

六、OpenGL中的實作

1、正交投影

在透視投影中,将截錐形的視錐中的 3D 點(眼坐标)映射到立方體(NDC)。 x x x 坐标從 [ l , r ] [l,r] [l,r] 到 [ − 1 , 1 ] [-1,1] [−1,1] 的範圍, y y y 坐标從 [ b , t ] [b,t] [b,t] 到 [ − 1 , 1 ] [-1,1] [−1,1] 的範圍, z z z 坐标從 [ − n , − f ] [-n,-f] [−n,−f] 的範圍到 [ − 1 , 1 ] [-1,1] [−1,1] ( z z z坐标與上面的映射剛好相反,上面為 n n n 映射到 1, f f f 映射到 -1)。

注意:眼坐标是在右手坐标系中定義的,但是NDC使用左手坐标系。也就是說,原點的相機在眼睛空間中沿 − Z -Z −Z 軸看,但在NDC中沿 + Z + Z +Z 軸看。

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

正交視見體轉換為标準化裝置坐标示意圖

為了推導過程與上面的區分,我們定義 − n e a r -near −near 為近裁剪面, − f a r -far −far 為遠裁剪面。注意紅色的負号,這裡将右手系翻轉為左手系,即将 [ 1 , − 1 ] [1, -1] [1,−1] 翻轉為 [ − 1 , 1 ] [-1, 1] [−1,1],是以需要乘以 -1。

正交投影的規範化矩陣

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

代碼實作

inline mat4 Ortho(const GLfloat left, const GLfloat right,
		const GLfloat bottom, const GLfloat top,
		const GLfloat zNear, const GLfloat zFar)
{
    mat4 c;
	c[0][0] = 2.0 / (right - left);
	c[1][1] = 2.0 / (top - bottom);
	c[2][2] = 2.0 / (zNear - zFar);
	c[3][3] = 1.0;
	c[0][3] = -(right + left) / (right - left);
	c[1][3] = -(top + bottom) / (top - bottom);
	c[2][3] = -(zFar + zNear) / (zFar - zNear);
	return c;
}
           

2、透視投影

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

透視視見體與标準化裝置坐标轉換示意圖

透視投影的規範化矩陣

推導過程與 第五小節中的 透視矩陣計算 相同

根據相似三角形可得 (注:這裡 n e a r near near 為正數, z z z 為負數是以需要乘以 -1)

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

根據齊次坐标特性可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

是以可得變換矩陣為

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

代入 ( 0 , 0 , − n e a r ) (0, 0, -near) (0,0,−near) 和 ( 0 , 0 , − f a r ) (0, 0, -far) (0,0,−far),可得

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

綜上可得:

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

代碼實作

inline mat4 Frustum(const GLfloat left, const GLfloat right,
	const GLfloat bottom, const GLfloat top,
	const GLfloat zNear, const GLfloat zFar)
{
	mat4 c;
	c[0][0] = 2.0 * zNear / (right - left);
	c[0][2] = (right + left) / (right - left);
	c[1][1] = 2.0 * zNear / (top - bottom);
	c[1][2] = (top + bottom) / (top - bottom);
	c[2][2] = -(zFar + zNear) / (zFar - zNear);
	c[2][3] = -2.0 * zFar * zNear / (zFar - zNear);
	c[3][2] = -1.0;
	c[3][3] = 0.0;
	return c;
}
           

源碼位址:https://github.com/WarZhan/Graphics-Demo/blob/master/Octahedra/mat.h

參考資料:

[1] GAMES101_Lecture_04:https://sites.cs.ucsb.edu/~lingqi/teaching/resources/GAMES101_Lecture_04.pdf

[2] 中科大圖形學教程:http://staff.ustc.edu.cn/~zhuang/cgi/lectures/cg6.pdf

[3] OpenGL投影矩陣:http://www.songho.ca/opengl/gl_projectionmatrix.html

歡迎關注個人公衆号,實時推送最新博文!

圖形學投影一、概述二、圖形學中常見投影三、投影規範化(projection normalization)四、正交投影五、透視投影六、OpenGL中的實作

繼續閱讀