終端圖像處理系列 - OpenGL ES 2.0 - 3D基礎(矩陣投影)

2021-02-08 騰訊光影研究室
Overview

行動裝置的屏幕是二維平面,要想把一個三維場景渲染在手機二維屏幕上,需要利用OpenGL中的矩陣投射,將三維空間中的點映射到二維平面上。三維矩陣的相關知識是學習OpenGL最重要的課程之一。

線性代數

學習OpenGL三維投射知識之前,我們得事先了解下一些基礎的線性代數知識,如向量運算,矩陣運算。

向量運算

向量: 指一個同時具有大小和方向的幾何對象,因常常以箭頭符號表示以區別於其它量而得名。

向量加減

向量的加(減)法定義是分量的相加(減),即將一個向量中的每一個分量加上(減去)另一個向量的對應分量:

向量相乘點乘

叉乘

矩陣運算矩陣簡介

數學上,一個 m x n 的矩陣是一個m行n列元素排列成的矩形陣列。以下是一個由6個數字元素構成的3行3列的矩陣:

矩陣運算規則矩陣的加減

矩陣與標量之間的加減:

矩陣與矩陣之間的加減:

矩陣乘法

矩陣數乘

矩陣相乘

單位矩陣

在OpenGL中,由於大部分的向量都是4分量 (x,y,z,w),所以我們通常使用 4x4 的變換矩陣。當中最簡單的變換矩陣是單位矩陣。單位矩陣是一個除了對角線以外都是0的NxN矩陣。

單位矩陣通常是生成其他變換矩陣的起點。

縮放矩陣

對一個向量進行縮放指的是對向量的長度進行縮放,而保持它的方向不變。

位移矩陣

位移是在原始向量的基礎上加上另一個向量從而獲得一個在不同位置的新向量的過程,從而在位移向量基礎上移動原始向量。

旋轉矩陣

(Rx,Ry,Rz)代表任意旋轉軸,θ是角度:

坐標系統

OpenGL在每次頂點著色器運行後,所有頂點都為標準化設備坐標,每個頂點(x,y,z)都應該在-1.0d到1.0之間。通常情況下,我們會根據畫布(屏幕)的大小設定一個坐標範圍,在頂點著色器中將這些坐標轉換為標準化設備坐標。在項目中,物體坐標最終被轉化為屏幕坐標之前會變換到多個坐標系統,因為在相應的過度坐標系中做特定運算會方便容易一些。對我們來講,一般情況下需要用到5個不同的坐標系統:

局部空間(Local Space):物體起始坐標;如一個正方體a,原點是正方體的中心O1(0,0,0)。

世界空間(World Space):物體在更大的空間範圍的坐標;如我們構造了一個圓球來表示世界,圓心為世界坐標原點O2,把正方體放在圓球中t(x1,y1,z1)位置。那么正方體a的圓心O1在世界系統會轉化為(x1,y1,z1)。物體的坐標從局部坐標變換到是世界坐標由模型矩陣(Model Matrix)負責實現。

模型矩陣是一種變換矩陣,能對物體進行位移,縮放,旋轉。

觀察空間(View Space): 觀察空間是將世界坐標轉化為用戶視野前方的坐標。一般用一個觀察矩陣(View Matrix)來完成轉換。

裁剪空間(Clip Space):頂點著色器運行到最後,OpenGL期望所有的坐標落在一個特定的範圍內,且任何在這個範圍之外的點會被裁剪掉。為了將頂點坐標從觀察變換成裁剪空間,需定義一個投影矩陣(Projection Matrix),它指定一個範圍的坐標,比如每個維度上的 -100 到 100。投影矩陣會將在這個指定範圍內的坐標變換為標準化設備坐標的範圍(-1。0,1.0)。使用投影矩陣能將3D坐標投影到2D的標準化設備坐標系中。

將觀察坐標變換為裁剪坐標的投影矩陣分為兩種不同的形式:正交投影矩陣(Orthographic Projection Matrix),透視投影矩陣(Perspective Projection Matrix)。

正交投影(Orthographic Projection)

正交投影矩陣定義一個立方體的平截頭箱,在這個立方體之外的頂點都會被裁剪掉。

正交投影矩陣直接將坐標映射到2D平面上。不過正交投影沒有透視效果,遠處箱子和近處箱子投射到平面上是一樣大的,這和我們日常生活中看東西時近大遠小的視覺效果是不符的。要解決這個問題,我們需要用到透視投影。

透視投影(Perspective Projection)

透視投影定義一個大平截頭體。透視投影有兩種表述方式:

glFrustum (left, right, bottom, top, zNear, zFar);

left,right,bottom,top定義near裁剪面大小,zNear和zFar定義從觀察點到遠近兩個裁剪面的距離。這六個參數定義出六個裁剪面構成的視錐體。

gluPerspective(fovy, aspect, zNear, zFar);

fovy: camera 在 y 方向上的視線角度(0~180)

aspect定義近截面的寬高比 aspect=w/h

zNear, zFar: 觀察點到遠近兩個裁剪面的距離

透視體參數轉換車過視錐體參數:

 tan(fovy/2) = (h / 2)/zNear -> h  w =  h * aspect -> w

矩陣組合

基於前面介紹的4個變換矩陣:模型矩陣,世界矩陣,觀察矩陣和投影矩陣。一個頂點坐標將會根據以下過程變換到裁剪坐標:

Vclip=Mprojection⋅Mview⋅Mmodel⋅Vlocal

注意矩陣運算的順序是從右往左閱讀,最終計算出來的頂點賦值給gl_Position

3D Demo

至此我們了解了OpenGL 3D渲染中需要知道的矩陣知識,運用這些知識,便可進行開發OpenGL3D程序了;蘋果官方提供一個很好的GL demo GLEssentials

結束


作者簡介:peicheng(程培),天天P圖iOS工程師

相關焦點

  • 原創 | 學好opengl走遍天下都不怕系列《基礎篇》
    前言最近本來是想認真學習下《opengl es第三版》這本書,無奈內容過於生澀,有點看不下去,偶遇opengl-tutorial.org
  • OpenGl ES 基礎入門知識
    本文分為以下四部分介紹:建議收藏本文哦~OpenGL 基礎概念OpenGLOpenGL 即 Open Graphics Library,是一個功能強大、調用方便的底層圖形庫,它定義了跨程式語言、跨平臺的專業圖形程序接口,可用於二維或三維圖像的處理與渲染
  • OpenGL矩陣變換的數學推導
    我們用一個括號把其中一個部分括了起來,外面乘了一個因子(-1/z0),後面會說這個因子是什麼東西,現在只需要知道,x2、y2實際上就是前面括號裡那堆東西,所以上面投影矩陣的第一行和第二行就自然能輕鬆地構造出來。
  • Android OpenGl ES 基礎入門知識
    本文分為以下四部分介紹:建議收藏本文哦~OpenGL 基礎概念OpenGLOpenGL 即 Open Graphics Library,是一個功能強大、調用方便的底層圖形庫,它定義了跨程式語言、跨平臺的專業圖形程序接口,可用於二維或三維圖像的處理與渲染
  • NDK OpenGL ES渲染系列 之 繪製三角形
    前言新的知識學習都是循序漸進的,從基礎到複雜。
  • OpenGL ES和坐標變換概述
    接下來,就坐標變換這個主題,我會寫一個小系列,由多篇技術文章組成,將坐標變換相關的資料整理在一起,並盡力用通俗易懂的語言表達出來,希望能為學習OpenGL和圖像處理的同學掃清理論上的障礙。本著理論聯繫實際的原則,我們將結合Android系統上的API介紹相關的理論。
  • 【乾貨】計算機視覺實戰系列05——用Python做圖像處理
    因此,如果能用較少的綜合指標來取代原來較多的原始指標,而這幾個綜合指標又能儘可能全面地反映原始指標的信息,且彼此之間互不相關,那麼將在很大程度上降低處理多指標問題的複雜度。 即使是一幅100x100像素的小灰度圖像,也有10000維可以看成是10000維空間中的一個點。一兆像素的圖像具有百萬維。由於圖像具有很高的維數,在許多計算機視覺應用中,我們經常使用降維操作。
  • OpenCV圖像分析處理(2)
    2.0~ 8.0(4)源碼    2.圖像卷積操作    (1)卷積核定義                卷積核就是算子就是權矩陣 卷積核:卷積時使用到的權用一個矩陣表示,該矩陣與使用的圖像區域大小相同,其行、列都是奇數
  • [Python圖像處理] 一.圖像處理基礎知識及OpenCV入門函數
    該系列文章是講解Python OpenCV圖像處理知識,前期主要講解圖像入門、OpenCV基礎用法,中期講解圖像處理的各種算法,包括圖像銳化算子
  • 數學運算、矩陣和圖像
    那個時候沒有接觸微積分、沒有接觸矩陣論、沒有接觸圖像處理,也沒有接觸機器學習。我們不知道我們未來做什麼。但我們的目的是搭建一個體系,這個體系中基本上都是最基礎的知識,主要以數學為主。 從最開始的加、減、乘、除開始,有很多種數學運算,還有加權和、開方、指數、以e為底、log等運算。再到後面,有均值、方差、標準差、最值等。這些都是數學專業最最基礎的運算。
  • CV基礎:圖像投影
    查了網上的資料和文獻,大致適合項目的有兩種方法:投影分割法和連通域分割法。當然還有其他的一些改進的算法,今天就不作深入討論,以後研究了再分享。今天我們就來實現垂直投影和水平投影首先是我們的原圖片垂直投影的結果:
  • 學習OpenGL ES之教你造一面鏡子
    比如如何把鏡像攝像機的渲染結果貼到鏡面上,鏡像攝像機被其他物體遮擋該如何處理。本文代碼依然延續學習OpenGL ES的項目代碼,任何之前已經介紹的代碼將不再介紹。所以你真的想看懂本文的話,至少對OpenGL和本系列Demo項目有基本的了解。之前的代碼中一直使用GLK的方法生成觀察矩陣,這次我對攝像機進行了封裝,主要是為了更方便的進行鏡像。攝像機的類是Camera。
  • OpenGl著色器簡單範例
    在文件名字為  minimal.vert裡面填上如下(圖代碼)void main(){        gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; }在文件名字為  minimal.frag裡面填上如下(圖代碼)void main(){    gl_FragColor = vec4(0.6,0.4,0.2,1.0
  • Matlab圖像處理系列教程(一)
    索引圖像可把像素值「直接映射」為調色板數值,原理就是矩陣 X 中的每個值,代表的是映射矩陣 map 的行,然後顏色既是map 中這一行的組合色調。MATLAB自帶的woman信號構成的圖像的像素索引矩陣和調色板矩陣。woman圖像是一幅典型的索引圖像。其圖像矩陣大小為256×256,表示有65535個像素點構成。調色板大小為256×3,表示有256種顏色。
  • OpenCV圖像處理中「投影技術」的使用
    本文將由「問題引出」、「概念抽象」、「算法實現」三個部分由表及裡具體講解OpenCV圖像處理中「投影技術」的使用,並通過「答題卡識別」、「OCR
  • 面試中經常被問到的 OpenGL ES 對象,你知道的有哪些?
    本例將 MVP 變換矩陣設置為一個 uniform 塊,即我們後面創建的 UBO 中將保存 3 個矩陣。#version 310 eslayout(location = 0) in vec4 a_position;layout(location = 1) in vec2 a_texCoord;layout (std140) uniform MVPMatrix{    mat4 projection;    mat4 view;
  • OpenGL ES 3.0 實例化(Instancing)
    利用內建變量gl_InstanceID在 3D 空間繪製多個位於不同位置的立方體,利用 u_offsets[gl_InstanceID]對當前實例的位置進行偏移,對應的著色器腳本:// vertex shader GLSL#version 300 es                            layout(location = 0) in
  • 同學,你要的OpenCV圖像處理系列教程已安排.
    img = np.zeros((512, 512, 3), np.uint8)cv2.line(img, (0, 0), (512, 512), (255, 0, 0), 5)cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)畫圓需要指定圓心和半徑
  • 基於OpenGL ES的深度學習框架編寫
    實時的情況下,深度學習框架的輸入和輸出都在GPU端,使用CPU進行計算往往需要拷貝圖像出來,算好後再傳到GPU端,因此基於GPU實現的深度學習的庫能持平CPU版本的效率就有足夠優勢了。比如實時摳人像這個case: 對每一幀相機預覽產生的數據,系統將其映射為opengl 的一個external texture,然後需要 計算出一個 mask texture,與原先的texture作混合,顯示出來。
  • OpenGL glfw學習(一)初識,環境,窗口
    計算機術語中,渲染是指從模型生成圖像的過程。這個接口由近350個不同的函數調用組成,用來繪製從簡單的圖形比特到複雜的三維景象。 解釋一下就是,OpenGL不是什麼語言,也不是包、庫,而僅僅是一套接口,一套規範。我們可以調用其編程接口處理圖像,完成圖形的渲染過程。而對於實現其接口的程序庫,則由不同企業或個人來實現,甚至你自己也可以來寫OpenGL接口的具體實現。