OpenGL ES 入門之旅--OpenGL 下的坐標(biāo)系和著色器渲染流程

OpenGL坐標(biāo)系

在學(xué)習(xí)坐標(biāo)系之前,我們先來(lái)了解下圖形的維度:


圖形的維度.png
2D笛卡爾積坐標(biāo)系
2D.png

X軸與Y軸互相垂直,它們共同定義了一個(gè)XY面,也就是說(shuō),在任何坐標(biāo)系統(tǒng)中,2條軸如果垂直相交就定義了一個(gè)平面,如果一個(gè)系統(tǒng)只有2個(gè)軸,那么就只有一個(gè)平面用來(lái)繪制圖形。

3D笛卡爾積坐標(biāo)系

3D.png
(這里的Z軸實(shí)際是垂直于X,Y軸的,為了便于表示才如此畫圖)3D笛卡爾坐標(biāo)系在2D的基礎(chǔ)上多了深度的坐標(biāo)軸。
相信大家都聽(tīng)說(shuō)過(guò)右手坐標(biāo)系,左手坐標(biāo)系,圖解如下:
左右手坐標(biāo)系.png
左手坐標(biāo)系:伸開左手,大拇指指向X軸正方向,食指指向Y軸正方向,其他三個(gè)手指指向Z軸正方向。
右手坐標(biāo)系:伸開右手,大拇指指向X軸正方向,食指指向Y軸正方向,其他三個(gè)手指指向Z軸正方向。左手和右手坐標(biāo)注系的區(qū)別在于兩者Z軸的方向是相反的。
其實(shí),我們?cè)谏厦嫣岬降牡芽栕鴺?biāo)系其實(shí)就是右手坐標(biāo)系。

下面,我們先來(lái)簡(jiǎn)單了解一下OpenGL中的幾個(gè)坐標(biāo)系的概念:

OpenGL攝像機(jī)坐標(biāo)系
攝像機(jī)坐標(biāo)系.jpg

攝像機(jī)坐標(biāo)系(照相機(jī)坐標(biāo)系)又稱為觀察者坐標(biāo)系,OpenGL中的觀察者是在原點(diǎn)的位置進(jìn)行觀察。

局部坐標(biāo)系(物體坐標(biāo)系),世界坐標(biāo)系,慣性坐標(biāo)系
坐標(biāo)系關(guān)聯(lián).png

局部坐標(biāo)系:局部坐標(biāo)系又稱為物體坐標(biāo)系/對(duì)象坐標(biāo)系,它與特定的物體相關(guān)聯(lián),每個(gè)物體都有自己特定的坐標(biāo)系。不同物體之間的坐標(biāo)系相互獨(dú)立,當(dāng)物體發(fā)生移動(dòng)或者旋轉(zhuǎn),物體坐標(biāo)系發(fā)生相同的平移或者旋轉(zhuǎn),物體坐標(biāo)系和物體之間運(yùn)動(dòng)同步,相互綁定。(舉個(gè)栗子:記得科目一有道題目是說(shuō)人在運(yùn)動(dòng)的時(shí)候,方向的隨意性。每一個(gè)人都有自己的一個(gè)坐標(biāo)系,人在運(yùn)動(dòng)的過(guò)程中,每個(gè)人的方向都不一樣,都是按照自己的物體坐標(biāo)系運(yùn)動(dòng),不受他人的影響。)
世界坐標(biāo)系:世界坐標(biāo)系是一個(gè)特殊的坐標(biāo)系,它建立了描述其他坐標(biāo)系所需要的參考系。也就是說(shuō),可以用世界坐標(biāo)系去描述其他所有坐標(biāo)系或者物體的位置。而且世界坐標(biāo)系是固定不變的。
慣性坐標(biāo)系:慣性坐標(biāo)系是為了簡(jiǎn)化世界坐標(biāo)系到慣性坐標(biāo)系的轉(zhuǎn)化而產(chǎn)生的。慣性坐標(biāo)系的原點(diǎn)與物體坐標(biāo)系的原點(diǎn)重合,慣性坐標(biāo)系的軸平行于世界坐標(biāo)系的軸。引入了慣性坐標(biāo)系之后,物體坐標(biāo)系轉(zhuǎn)換到慣性坐標(biāo)系只需旋轉(zhuǎn),從慣性坐標(biāo)系轉(zhuǎn)換到世界坐標(biāo)系只需平移。

那么,一個(gè)圖形從坐標(biāo)頂點(diǎn)數(shù)據(jù)顯示到屏幕上,會(huì)經(jīng)歷多少坐標(biāo)系空間的轉(zhuǎn)換呢?
坐標(biāo)系統(tǒng)變換過(guò)程.png

在上面的圖中,OpenGL只定義了裁剪坐標(biāo)系、規(guī)范化設(shè)備坐標(biāo)系和屏幕坐標(biāo)系,然而物體坐標(biāo)系)世界坐標(biāo)系和攝像機(jī)坐標(biāo)系都是為了方便用戶設(shè)計(jì)而自定義的坐標(biāo)系。
其中,模型變換、視變換,投影變換,這些變換可以由用戶根據(jù)需要自行指定,這些內(nèi)容在頂點(diǎn)著色器中完成;透視除法、視口變換,這兩個(gè)步驟是OpenGL自動(dòng)執(zhí)行的,在頂點(diǎn)著色器處理后的階段完成。
下面我們通過(guò)攝像機(jī)拍攝物體(即從三維物體到二維圖像的過(guò)程)來(lái)展示一下上面的坐標(biāo)變換流程:
1.模型變換
我們將一個(gè)物體放在一個(gè)場(chǎng)景中,應(yīng)該就相當(dāng)于模型變換。模型變換是在世界坐標(biāo)系中進(jìn)行的,物體模型的中心定位在坐標(biāo)系的中心處,通過(guò)對(duì)物體模型執(zhí)行平移(glTranslate)、縮放(glScale)、旋轉(zhuǎn)(glRotate)等操作,來(lái)調(diào)整物體模型在世界坐標(biāo)系中的位置。
2.視變換

將相機(jī)置于三角架上,讓它對(duì)準(zhǔn)三維物體,它相當(dāng)于OpenGL中調(diào)整視點(diǎn)的位置,即視變換。經(jīng)過(guò)模型變換,物體的坐標(biāo)都處于世界坐標(biāo)系中,視變換就是確定了場(chǎng)景中物體的視點(diǎn)位置和方向。在實(shí)際拍攝物體時(shí),我們可以保持物體的位置不動(dòng),調(diào)整相機(jī)距離物體的距離和角度,這就相當(dāng)于視點(diǎn)變換,我們也可以保持相機(jī)的固定位置,將物體遠(yuǎn)離相機(jī),這就相當(dāng)于模型轉(zhuǎn)換。其實(shí)可以看出,在OpenGL中,以逆時(shí)針旋轉(zhuǎn)物體就相當(dāng)于以順時(shí)針旋轉(zhuǎn)相機(jī)。
視變換.png
視變化就可以理解為:根據(jù)攝像機(jī)的位置和角度,然后觀察世界坐標(biāo)系下的物體。
在上圖的左邊部分,是將攝像機(jī)放進(jìn)世界坐標(biāo)系,右邊部分則是將世界坐標(biāo)系內(nèi)的物體模型變換到攝像機(jī)空間(即是視圖空間)。
3.投影變換
經(jīng)過(guò)模型變換和視變換之后,物體已經(jīng)處在了場(chǎng)景中所希望存在的位置上,此時(shí)我們選擇相機(jī)鏡頭并調(diào)整相機(jī)焦距,使得三維物體投影在二維膠片上,它相當(dāng)于OpenGL中把三維模型投影到二維屏幕上的過(guò)程,即OpenGL的投影變換。
下面來(lái)看一下OpenGL的投影方式:
投影.png

透視投影:即離視點(diǎn)近的物體大,離視點(diǎn)遠(yuǎn)的物體小,遠(yuǎn)到極點(diǎn)即為消失。
正投影:又叫平行投影。這種投影的視景體是一個(gè)矩形的平行管道,也就是一個(gè)長(zhǎng)方體,正射投影的最大一個(gè)特點(diǎn)是無(wú)論物體距離相機(jī)多遠(yuǎn),投影 后的物體大小尺寸不變。
如果在開發(fā)的過(guò)程中,渲染是二維的平面圖形,可以使用正投影的方式,就不會(huì)存在"近大遠(yuǎn)小"的問(wèn)題。
如果需要渲染立體圖形,為保證立體圖形的逼真效果,就使用透視投影。(在立體圖形下,使用正投影也可以,只是在顯示的過(guò)程中,沒(méi)有立體效果)。

4.透視除法
透視除法這個(gè)步驟是OpenGL自動(dòng)執(zhí)行的,在頂點(diǎn)著色器處理后的階段完成,無(wú)需我們開發(fā)者來(lái)處理。

著色器的渲染流程
著色器渲染流程.png

在頂點(diǎn)著色器處理圖元頂點(diǎn)之后進(jìn)入圖元裝配階段。這一階段,執(zhí)行裁剪、透視分割和視口變換操作。
圖元裝配.png

下面我們先來(lái)解釋一下圖元裝配的流程:

1.坐標(biāo)系統(tǒng):

頂點(diǎn)以物體或者本地坐標(biāo)空間輸入到OpenGL中,這是最可能用來(lái)建模和存儲(chǔ)一個(gè)對(duì)象的坐標(biāo)空間。在頂點(diǎn)著色器執(zhí)行之后,頂點(diǎn)位置被認(rèn)為是在裁剪坐標(biāo)空間內(nèi)。頂點(diǎn)位置從本地坐標(biāo)系統(tǒng)(也就是物體坐標(biāo)) 到裁剪坐標(biāo)的變換通過(guò)加載執(zhí)行這一行轉(zhuǎn)換的對(duì)應(yīng)矩陣來(lái)完成,這些矩陣保存在頂點(diǎn)著色器中定義的對(duì)應(yīng)統(tǒng)一變量中。
坐標(biāo).png
  1. 裁剪

    為了避免在可視景體之外處理圖元,圖元被裁剪到裁剪空間。執(zhí)行頂點(diǎn)著色器之后的頂點(diǎn)位置處于裁剪坐標(biāo)空間內(nèi)。裁剪坐標(biāo)是由(x, y, z, w)指定的同類坐標(biāo)。在裁剪空間(x, y, z, w)中定義的頂點(diǎn)坐標(biāo)根據(jù)視景體裁剪。下圖是一個(gè)裁剪體,由6個(gè)裁剪平面定義,稱作近、遠(yuǎn)、左、右、上、下裁剪平面。
    裁剪.png

    裁剪階段將把每個(gè)圖元裁剪為上圖所示的裁剪體。

    對(duì)于每種圖元類型,執(zhí)行以下操作:
    裁剪三角形: 如果三角形完全在視景體內(nèi)部,則不執(zhí)行任何裁剪。如果三角形完全在視景體外,則該三角形被放棄。如果三尖形部分在視景體內(nèi),則根據(jù)相應(yīng)的屏幕裁剪三角形。裁剪操作將生成新的頂點(diǎn),這些頂點(diǎn)被裁剪到三角扇形的平面。
    裁剪直線:直線完全在視景體內(nèi)部,則不執(zhí)行任何裁剪。如果直線完全在視景體之外,則該直線被放棄。
    裁剪點(diǎn) : 如果點(diǎn)位置在近平面或遠(yuǎn)平面之外,則被拋棄。否則將不做變化地通過(guò)該階段。
    頂點(diǎn)坐標(biāo)經(jīng)過(guò)透視裁剪分割之后,變成規(guī)范化的設(shè)備坐標(biāo)。規(guī)范化的設(shè)備坐標(biāo)范圍是 -1.0 到 1.0。

3.透視分割
透視分割將裁剪坐標(biāo)(x, yy, z, w) 指定的點(diǎn)投影到屏幕或者視口上。投影動(dòng)作將(x, y, z)執(zhí)行(x/w)、(y/w)、(z/w) 之后,我們得到規(guī)范化的設(shè)備坐標(biāo)(x’, y‘, z’)。這些坐標(biāo)被稱為規(guī)范化設(shè)備坐標(biāo)。這些規(guī)范化的坐標(biāo)根據(jù)視口的大小將被轉(zhuǎn)換為真正的屏幕(或窗口)坐標(biāo)。規(guī)范化的z坐標(biāo)將用glDepthRangef 指定的near 和far深度值轉(zhuǎn)換為屏幕的z值。這些轉(zhuǎn)換在視口變換階段進(jìn)行。

4.視口變換
視口變換專業(yè)解釋為:OpenGL 對(duì)裁剪坐標(biāo)執(zhí)行透視除法從而將它們變換到標(biāo)準(zhǔn)化設(shè)備坐標(biāo)。OpenGL 會(huì)使用 glViewPort 內(nèi)部的參數(shù)來(lái)將標(biāo)準(zhǔn)化設(shè)備坐標(biāo)映射到屏幕坐標(biāo),每個(gè)坐標(biāo)都關(guān)聯(lián)了一個(gè)屏幕上的點(diǎn)。這個(gè)過(guò)程稱為視口變換。
視口變換就是將視景體內(nèi)投影的物體顯示在二維的視口平面上。就是我們?cè)谑褂谜障鄼C(jī)拍攝完成后,進(jìn)行沖洗底片,決定相片的放大與縮小,它相當(dāng)與OpenGL中的視口變換。


視口.jpeg

當(dāng)然這個(gè)步驟也是OpenGL自動(dòng)執(zhí)行的,在頂點(diǎn)著色器處理后的階段完成。

void glViewport(GLint x, GLint y, GLsizei w, GLsizei h)
x, y, 指定視口左下角的窗口坐標(biāo),以像素表示
w, h,指定視口的寬度和高度,這些值必須大于0

從上面圖元裝配的流程圖可以知道:在渲染過(guò)程中,必須存儲(chǔ)2種著?器,分別是頂點(diǎn)著?器、片元著?器。頂點(diǎn)著?器是第?個(gè)著色器、?元著?器是最后?個(gè)。頂點(diǎn)著?器中處理頂點(diǎn)、片元著?器處理像素點(diǎn)顏色。下面我們換一種直觀的方式來(lái)看渲染流程圖:
渲染.png

1.創(chuàng)建頂點(diǎn)。
2.然后通過(guò)頂點(diǎn)著色器渲染。
3.連接信息條,通過(guò)各個(gè)頂點(diǎn)連接成幾何圖形。
4.光柵化:其實(shí)是確定像素點(diǎn)在屏幕上繪制的位置,然后這些片段由片元著色器處理(輸入給片元著色器)。
5.光柵化階段生成每個(gè)片元執(zhí)行這個(gè)著色器。
6.最終呈現(xiàn)出圖形。

5.光柵化:
在頂點(diǎn)變換和圖元裁剪之后,光柵化管線取得單獨(dú)圖元并為該圖元生成對(duì)應(yīng)的片段。每個(gè)片段由屏幕空間中的整數(shù)位置(x, y)標(biāo)識(shí)。

光柵化.png
光柵化是將圖元轉(zhuǎn)化為一組二維片段的過(guò)程:
當(dāng)渲染一個(gè)圖元時(shí),光柵化(Rasterization)階段通常會(huì)造成比原指定頂點(diǎn)更多的片段。
光柵會(huì)根據(jù)每個(gè)片段在圖元上所處相對(duì)位置決定這些片段的位置?;谶@些位置,它會(huì)插值(Interpolate)所有片段著色器的輸入變量。
比如說(shuō),我們有一個(gè)線段,上面的端點(diǎn)是綠色的,下面的端點(diǎn)是藍(lán)色的。如果一個(gè)片段著色器在線段的70%的位置運(yùn)行,它的顏色輸入屬性就會(huì)是一個(gè)綠色和藍(lán)色的線性結(jié)合,更精確地說(shuō)就是30%藍(lán) + 70%綠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容