您現在的位置是:首頁 > 單機遊戲首頁單機遊戲

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

簡介這個函式其實就是對接下來要做什麼進行一下宣告,也就是在要做下一步之前告訴計算機我要對“什麼”進行操作了,這個“什麼”在glMatrixMode的“()”裡的選項(引數)有3種模式: GL_PROJECTION 投影, GL_MODELVIE

頂點光照技術是什麼

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

0。 動機

首先申明,我是拓幻科技圖形處理工程師,自己接觸OpenGL,圖形影象等方面也有六年多了,很多人其實並不瞭解這方面,也不瞭解如何系統地去學,我覺得基於我碩士時期的課程和經驗給大家。這些資料和經驗也得感謝我的老師,來自普渡大學的終生教授邁克 貝利(Mike Bailey)。 以此連載OpenGL學習教程,藉助公司知乎給大家講解,一起學習一下,不對之處,歡迎大家指出討論。

所有渲染工作都離不開OpenGL, 著色器(Shader)這些,如果你和我一樣對圖形處理比較感興趣的話,可能你和當初的我有著同樣的困惑:如何開始?OpenGL有一些官方的手冊和文件,但是一來內容比較分散,二來學習階梯稍微陡峭了些而且晦澀難懂。這對於之前完全沒有接觸過有關內容的新人來說是相當不友好的。這些內容說是教程,倒不如說是一份我對於圖形學課程或者專案的經驗總結,希望能夠幫到有需要的人。

所以,本“教程”的物件是

總的來說是新接觸圖形學OpenGL開發的人:也許你知道什麼是OpenGL,什麼是Shader,也會使用別人的Shader,但是僅限於知道一些基本的名詞。想要系統性學習OpenGL,Shader開發的開發者,但是之前並沒有圖形學開發的經驗。

1。 計算機圖形學簡史

1。1 1950s

在1950s,剛出現筆式繪圖儀和計算機示波器。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

1。2 1960s

在1960s,出現最初代的向量顯示器和一些最初的互動式裝置。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

在1960s,還有一個很著名的專案,計算機圖形學之父 Ivan的SketchPad Project。感興趣的同學可以搜一下伊凡·蘇澤蘭去了解一下,他的偉大就不多說了。

1。3 1970s

在1970s,出現直視儲存管,彩色光柵顯示器等,並且召開了SIGGRAPH大會。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

1。4 1980s

在1980s,出現模擬飛行渲染技術。著名動畫廠商皮克斯(Pixar)成立。1984年英偉達的創始人從我的母校畢業,?,感謝他為我的母校計算機學院捐的樓和實驗室。

1。5 1990s

在1980s,在硬體上可以進行紋理對映,並且OpenGL也出現。侏羅紀公園,玩具總動員也是這個年代的產物。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

1。6 2000s

在2000s,圖形學發展尤為重要,出現了著色器shaders和OpenGL-ES。這是下面一切的基礎。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

2。 圖形處理和圖形渲染管線技術

2。1 圖形處理

圖形處理分為幾何造型(3D Geometric Models),動畫,光照,紋理,表面資訊,影象儲存和顯示幾大塊。關係如下圖所示。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

其中3D幾何模型經過一些對映方法,應用材質性質等處理後可以進行渲染。

3D動畫是進行一些物體運動的設計,捕捉和計算。

紋理資訊包括掃描影象紋理,程式計算所得紋理和手繪紋理等。

表面資訊包括Alpha-Blended透明效果,反射,折射和散射資訊的計算。下圖是這四種狀態。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

光照包含光源種類(點光源point,方向光源directional和聚光燈光源spot),光源位置資訊,光源顏色,強度資訊。

2。2 圖形渲染管線

圖形渲染管線可以大致理解為定點資料經過定點變換後進入圖元裝配,並進行紋理對映、片元處理、光照等操作後,進行光柵化並輸出倒幀緩衝裡。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

具體在頂點變換時其實過程還是比較複雜的,不能一筆帶過。

比如最初送進來的是模型座標系(Model Coodinates)座標資訊,經過模型變換(Model Transform)後變為世界座標(World Coodinates)。模型變換透過對模型執行平移(translation)、縮放(scale)、旋轉(rotation)、映象(reflection)、錯切(shear)等操作,來調整模型的過程。透過模型變換,我們可以按照合理方式指定場景中物體的位置等資訊。

這裡插一段對模型變換的解釋。我們為什麼需要模型變換?我們在OpenGL中透過定義一組頂點來定義一個模型,或者透過其他3D建模軟體事先建好模型然後匯入到OpenGL中。頂點屬性定義了模型。那麼如果我們要在一個場景中不同位置、不同的比例、不同角度顯示同一個模型怎麼辦?如果繼續以類似的頂點屬性資料定義同一個模型,調整它滿足上述需求的話,不僅浪費顯示卡記憶體,而且效率很低。所以,我們定義的模型根據需要可以進行放大、縮小等操作來不同比例顯示,可以透過平移來放在不同位置,可以透過旋轉來按不同角度顯示。這種方式就是執行模型變換。

世界座標(World Coodinates)經過視變換(View Transform)後得到眼座標系(Eye Coodinates)。OpenGL成像採用的是虛擬相機模型,但這個相機並不存在。在現實生活中,我們透過移動相機來拍照,而在OpenGL中我們透過以相反方式調整物體,讓物體以適當方式呈現出來。

在世界座標系中,對於頂點進行頂點光照處理(Per-vertex Lighting)後,進行投影變換(Projection Transform),得到裁剪座標系(Clip Coodinates)。這部分內容後期再著重介紹。

之後經過透視除法或者也可以叫做(Homegeneous Division)得到規範化裝置座標系(Noramlized Deviced Coodinates)座標資訊。這些座標資訊經過視口變換(Viewport Transform)後得到最終螢幕座標系(Screen Coodinates)座標資訊。視口變換主要是將視景體內投影的物體顯示到二維的視口平面上。在計算機圖形學中,它的定義是將經過幾何變換, 投影變換和裁剪變換後的物體顯示於螢幕指定區域內。就好比照片拍好了,要確定照片的大小,放大照片還是縮小照片,也就是把圖形畫下來,是要佔據整個螢幕還是螢幕的一部分。注意和視變換(View Transform)區別開。

這些過程便是頂點變換全過程。之後繼續進行最初我們講的光柵化,片元處理,紋理處理,片源光照等處理後進行光柵處理,最後輸出到幀緩衝(Framebuffer)中去。

下圖為全管線流程圖:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

OpenGL渲染管線流程圖

到此為止就已經將前期知識都講解完畢,請務必記號管線渲染技術流程圖,很重要,很重要,很重要,說三遍!

3。 OpenGL圖形程式設計

我想現在你已經徹底對圖形學懵了對吧,各種座標,各種變換,各種不知道幹什麼用的名詞。沒關係,先了解一下,現在進入OpenGL 圖形程式設計。

3。1 幾何 vs。 拓撲

假設原始圖形如下圖所示:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

如果改變幾何,就是改變頂點位置,比如我們移動頂點3的位置到下圖所示位置:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

幾何改變

這個時候圖形的幾何形狀發生改變,但頂點連線順序卻仍然相同,為1-2-3-4-1。

拓撲變化則是不變化頂點位置,變換連線方式,比如由1-2-3-4-1變為1-2-4-3-1:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

拓撲改變

總結來講,幾何就是描述事物在哪兒,比如座標位置等,拓撲就是這些事物的連線方式是怎樣。

瞭解了這兩個概念,後邊在OpenGL程式設計時會用到。

3。2 3D座標系

3D座標系分為左手座標系和右手座標系,具體情況如下圖所示:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

我們後期講解都是基於右手座標系的。至於為什麼,我的老師當初是這樣解釋的:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

就是這麼任性,辛普森用的,我們也要用,哈哈哈~

上一節我們提到過模型變換時有旋轉操作,那麼在座標系中,旋轉的方向是怎樣呢?比如旋轉90度,到底向左是正還是右是正呢?我們可以用右手法則來進行正方向判斷:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

圖中所示就是右手座標系中旋轉正方向。

3。3 3D繪製

下面到程式碼講解。最基礎的圖形學,總要先畫最基礎的圖形吧,那麼現在來看以下程式碼:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

看到glBegin括號裡GL_LINE_STRIP了嗎?顧名思義,畫的是一條連線。glVertex3f是用來繪製頂點,座標為括號裡的值,這裡我們畫了v0,v1,v2,v3,v4 四個頂點,並將其按照順序連線成以v0為首,v4為尾的一條線段。

我們改變括號裡的引數,那麼就可以畫出不同的圖形。對照表如下所示:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

注意,在gl_Begin和gl_End中間是所繪製使用的頂點。比如現在畫兩個三角形,那麼在畫第一個三角形時,頂點使用v0, v1,v2,那麼gl_Begin和gl_End程式碼中間需要新增的就是繪製的就是v0, v1,v2 的頂點程式碼,對應第二個三角形再加的就是第二個三角形頂點的繪製程式碼。

在這裡我們再結合圖形幾何和拓撲的概念理解一下,圖形的幾何發生改變其實改變的是頂點座標位置,也就是glVertex3f函式中引數的值。拓撲發生改變其實是gl_Begin和gl_End中間夾著的頂點程式碼的順序,比如先畫v0, 再畫v1,最後畫v2 ,還是先畫v1, 再畫v2,最後畫v0 。

下面解釋一下第一行:glColor函式。我們可以看到這裡它的三個引數我是用r,g,b代替的。那麼rgb是什麼呢?r是red 紅,g是green 綠,b是blue 藍。小學學過,光的三原色,由他們可以組合出任意顏色。需要提到的是在OpenGL glColor中,顏色rgb的範圍都是在0~1之間不會小於0,也不會大於1。 0代表程度無,1代表程度最深。顏色疊加圖我這裡就不多做介紹了,上過小學中學美術的都該知道。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

OK。到目前為止,你已經能夠用最簡單的OpenGL程式碼繪製最簡單的圖形,甚至改變顏色啦。

又來提醒你,剛剛我們提到過模型變換還記得嗎?我們透過平移,旋轉,縮放來實現模型變換。那麼我們如何使用OpenGL進行平移,旋轉,縮放呢?

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

答案在這裡:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

下面我們來具體講解,程式碼如下:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

首先來看第一句,glMatrixModel()函式。這個函式其實就是對接下來要做什麼進行一下宣告,也就是在要做下一步之前告訴計算機我要對“什麼”進行操作了,這個“什麼”在glMatrixMode的“()”裡的選項(引數)有3種模式: GL_PROJECTION 投影, GL_MODELVIEW 模型檢視, GL_TEXTURE 紋理。 這裡我們要做的是對模型檢視的改變,所以引數是GL_MODELVIEW。待會兒我們再講剩下的兩個。

看下glTranslatef(), glRotatef()和glScalef()這三個函式。三個函式都末尾帶有f,所以引數都是GLfloat型,也有末尾改成d的,引數就是GLdouble型。

首先glTranslatef()函式,三個引數的意思是沿著x,y,z軸平移的分量。

glRotatef()函式,第一個引數為旋轉角度,後面三個引數表示沿著從(0,0,0)到(x,y,z)的向量方向旋轉。再明確一點其實就是,x,y,z表達的意思並不是座標點,而是要圍繞哪個座標軸旋轉。還記得剛剛的右手法則嗎?從座標(0,0,0)即原點,引出一條線到(x,y,z),用右手握住這條線。假設xyz為(1,0,0),右手大拇指指向(0,0,0)至(1,0,0)的方向才握。另外四個手指的彎曲指向即是物體旋轉方向。為什麼是右手握住,而不是左手呢?因為OpenGL遵循的是右手法則。到這兒你就理解我為什麼先給各位說座標系和右手法則的事情了,如果剛剛你沒認真看,現在看一下,再理解這一段。

最後一個glScalef(),三個引數就是x,y,z軸放大縮小的倍數。

重點是執行順序問題,順序是按照由下至上的順序來的,也就是程式碼圖中123的順序來的。順序看似是沒有區別的,事實上區別很大。

看這個例子就知道為什麼順序會影響最終繪製結果了:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

現在為止講完第一個glMatrixModel(GL_MODELVIEW)。下一個就是glMatrixModel(GL_PROJECTION)。如果引數是GL_PROJECTION,這個是投影的意思,就是要對投影相關進行操作,進行投影變換,也就是把物體投影到一個平面上,就像我們照相一樣,把3維物體投到2維的平面上。這樣,接下來的語句可以是跟透視相關的函式。

我們這裡介紹兩個函式:

glOrtho( xl, xr, yb, yt, zn, zf );

gluPerspective( fovy, aspect, zn, zf );

第一個函式glOrtho是正交投影或平行投影,第二個gluPerspective是透視投影。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

先說第一個glOrtho。建立一個平行視景體(就是一個長方體空間區域)。實際上這個函式的操作是建立一個正射投影矩陣,並且用這個矩陣乘以當前矩陣。只有在視景體裡的物體才能顯示出來,最後兩個引數改成0,0後,視景體深度沒有了,整個視景體都被壓成個平面了,當然就顯示不正確了。

第二個函式gluPerspective。建立一個表示對稱透視檢視平截頭體的矩陣,並把它與當前矩陣相乘。fovy是YZ平面上視野的角度,範圍0-180°。好的取值範圍一般是50-100°。aspect是這個平截頭體的縱橫比,也就是寬度除於高度。near和far值分別是觀察點與近側裁剪平面以及遠側裁剪平面的距離(沿Z軸負方向)這兩個值都是正的。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

到此講完第二個glMatrixModel(GL_PROJECTION)。第三個GL_TEXTURE暫時各位先記著,等講到紋理時再詳細闡述。

程式碼現在可以擴充成以下程式碼了:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

現在也就是已經做過模型變換,投影變換了,還缺視變換和視口變換。下面我們就來做這兩組變換。

介紹一個函式:

gluLookAt( ex, ey, ez, lx, ly, lz, ux, uy, uz );

這個函式第一組eyex, eyey,eyez 相機在世界座標的位置,第二組centerx,centery,centerz 相機鏡頭對準的物體在世界座標的位置,第三組upx,upy,upz 相機向上的方向在世界座標中的方向。你把相機想象成為你自己的腦袋:第一組資料就是腦袋的位置,第二組資料就是眼睛看的物體的位置,第三組就是頭頂朝向的方向(因為你可以歪著頭看同一個物體)。這個就是進行視變換的。

再介紹一個函式:

glViewport( ixl, iyb, idx, idy );

呼叫glViewPort函式來決定視見區域,告訴OpenGL應把渲染之後的圖形繪製在窗體的哪個部位。當視見區域是整個窗體時,OpenGL將把渲染結果繪製到整個視窗。這個函式進行視口變換。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

這個函式前兩個函式是指定視口的左下角位置的,一般為0,0。WindowsGDI中的視窗座標(0,0)是左上角,而OpenGL所定義的(0,0)是左下角。所以這個函式在這個圖中是定義左上角的。後兩個引數就是寬度和高度。

這一節結束前再介紹一組有用的函式:

glPushMatrix()和glPopmatirx()

假設我們想要繪製太陽系,中間是太陽,靜止不動,地球圍繞太陽旋轉,月亮圍繞地球旋轉。

我們首先將座標系移動到太陽的位置,繪製太陽,再將座標系移動到地球的位置,繪製地球,然後將座標系移動到月亮的位置,繪製月亮;如果還有金星、木星、火星呢,他們也都是以太陽為中心旋轉,這樣子,我們可以繪製完月亮之後再將座標系回退到繪製地球的時候的座標系,移動相應的位置,繪製金星,然後再回退或者移動新位置繪製木星。這樣的操作不但麻煩,而且容易出錯。

那怎麼辦最好呢,其實就是繪製地球、金星、木星、火星等的時候以太陽為座標原點,在繪製地球之前先把當前的模型檢視矩陣壓入堆疊中儲存下來(glPushMatirx),這樣你在進行變換就不會影響到堆疊中的矩陣,這個時候將座標系移動到地球的位置繪製地球,繪製完成之後將模型檢視矩陣堆疊中的棧頂矩陣(就是我們剛才儲存的矩陣)彈出(glPopMatrix),恢復原來的座標系,再壓入堆疊,繪製金星,再彈出。

基本上這一講已經結束了。各位對OpenGL該有個了大致的思路,並且也想嘗試些一些程式碼了吧。那就動手吧,下期我會將我的github放出來,供大家看一些示例程式碼。

最後放出一些和本講有關的,但不影響大家學習OpenGL的小知識,有興趣的瞭解下,沒興趣的略過吧。

你只知道有紅綠藍三個顏色疊加出別的顏色,所以glcolor引數是rgb。不知道還可以由白光透過減法減出各種顏色吧。

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

在管線技術流程圖裡,提到個名詞叫光柵化,可能很多人不明白。光柵化就是把頂點資料轉換為片元的過程。片元中的每一個元素對應於幀緩衝區中的一個畫素。那麼頂點怎麼轉換為片元的呢?如下圖,英語好的自己看吧:

拓幻圖形學工程師教學手冊(第一講)|一字一字敲出OpenGL學習教程

對於fragment processing,在學習了shader之後,你會更加了解透過shader你做了很多你自己的fragment processing。

Top