1. 程式人生 > >學openGL必知道的圖形學知識

學openGL必知道的圖形學知識

OpenGL基本原理

OpenGL是將用數學語言和色彩等資訊描述的三維空間物體通過計算轉換成二維影象並顯示出來的程式庫。

三維空間中的物件被描述成一系列的頂點(用來定義幾何物件)或畫素(用來定義影象)。
OpenGL對資料進行幾個步驟的處理將其轉換成畫素,這些畫素存放幀緩衝區中形成最終需要的圖形。

OpenGL 紋理介紹

OpenGL 中的紋理可以用來表示影象、照片、甚至由一個數學演算法生成的分形資料。每個二維的紋理都由許多小的紋理元素組成。要使用紋理,最常用的方式是直接從一個影象檔案載入資料。其中需要注意的是 OpenGL要求紋理的高度和寬度都必須是2的n次方大小,只有滿足這個條件,這個紋理圖片才是有效的。

比如繪製一面磚牆,就可以用一幅真實的磚牆影象或照片作為紋理貼到一個矩形上,這樣,一面逼真的磚牆就畫好了。如果不用紋理對映的方法,則牆上的每一塊磚都必須作為一個獨立的多邊形來畫。另外,紋理對映能夠保證在變換多邊形時,多邊形上的紋理圖案也隨之變化。例如,以透視投影方式觀察牆面時,離視點遠的磚塊的尺寸就會縮小,而離視點較近的就會大些。此外,紋理對映也常常運用在其他一些領域,如飛行模擬中常把一大片植被的影象對映到一些大多邊形上用以表示地面,或用大理石、木材、布匹等自然物質的影象作為紋理對映到多邊形上表示相應的物體。

最基本的執行紋理對映所需的步驟:
1)定義紋理
2)控制濾波
3)說明對映方式
4)繪製場景,給出頂點的紋理座標和幾何座標。

OpenGL座標系之間的轉換 :

光柵化

光柵化(Rasterize/rasteriztion)。這個詞兒Adobe官方翻譯成柵格化或者畫素化。沒錯,就是把向量圖形轉化成畫素點兒的過程。我們螢幕上顯示的畫面都是由畫素組成,而三維物體都是點線面構成的。要讓點線面,變成能在螢幕上顯示的畫素,就需要Rasterize這個過程。就是從向量的點線面的描述,變成畫素的描述。前面是告訴計算機我有一個圓形,後面就是計算機把圓形轉換成可以顯示的畫素點。這個過程就是Rasterize。

渲染管線

渲染管線(Pipeline)這個翻譯尤其不接地氣,簡直就是直譯(pipe管子line線路)。Pipeline是輸送管道的意思。其實是指三維渲染的過程中顯示卡執行的、從幾何體到最終渲染影象的、資料傳輸處理計算的過程。

著色器

著色器(Shader)這個翻譯的挺好。畫畫的時候我們經常有這麼一個過程:先打線稿,再上色。著色器就是用來做這個工作的。

通常著色器分兩種:
1頂點著色器(vertex shader)這個是告訴電腦如何打線稿的——如何處理頂點、法線等的資料的小程式。
2片面著色器(fragment shader)這個是告訴電腦如何上色的——如何處理光、陰影、遮擋、環境等等對物體表面的影響,最終生成一副影象的小程式。
採用了這兩種著色器小程式 的 資料傳輸處理計算的渲染過程,稱之為 可程式設計管線。

正交投影VS透視投影

在計算機三維影象中,投影可以看作是一種將三維座標變換為二維座標的方法,常用到的有正交投影和透視投影。
正交投影多用於三維健模,這樣不會因為投影而改變物體比例。透視投影則由於和人的視覺系統相似,多用於在二維平面中對三維世界的呈現。

正交投影
投影線垂直於投影面的投影屬於正交投影 ,屬於平行投影的一種。

透視投影
透視投影(Perspective Projection)是為了獲得接近真實三維物體的視覺效果而在二維的紙或者畫布平面上繪圖或者渲染的一種方法,也稱為透檢視[1] 。它具有消失感、距離感、相同大小的形體呈現出有規律的變化等一系列的透視特性,能逼真地反映形體的空間形象。透視投影通常用於動畫、視覺模擬以及其它許多具有真實性反映的方面。

透視除法

視錐體與透視投影矩陣

OpenGL ES 三種類型修飾 uniform attribute varying

1.uniform變數
uniform變數是外部application程式傳遞給(vertex和fragment)shader的變數。因此它是application通過

函式glUniform**()函式賦值的。在(vertex和fragment)shader程式內部,uniform變數就像是C語言裡面

的常量(const ),它不能被shader程式修改。(shader只能用,不能改)

如果uniform變數在vertex和fragment兩者之間宣告方式完全一樣,則它可以在vertex和fragment共享使用。

(相當於一個被vertex和fragment shader共享的全域性變數)

uniform變數一般用來表示:變換矩陣,材質,光照引數和顏色等資訊。

以下是例子:


uniform mat4 viewProjMatrix; //投影+檢視矩陣
uniform mat4 viewMatrix;        //檢視矩陣
uniform vec3 lightPosition;     //光源位置

2.attribute變數
attribute變數是隻能在vertex shader中使用的變數。(它不能在fragment shader中宣告attribute變數,

也不能被fragment shader中使用)

一般用attribute變數來表示一些頂點的資料,如:頂點座標,法線,紋理座標,頂點顏色等。

在application中,一般用函式glBindAttribLocation()來繫結每個attribute變數的位置,然後用函式

glVertexAttribPointer()為每個attribute變數賦值。

以下是例子:

uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
void main(void)
{
gl_Position = u_matViewProjection * a_position;
v_texCoord = a_texCoord0;
}

3.varying變數
varying變數是vertex和fragment shader之間做資料傳遞用的。一般vertex shader修改varying變數的值,

然後fragment shader使用該varying變數的值。因此varying變數在vertex和fragment shader二者之間的聲

明必須是一致的。application不能使用此變數。

以下是例子:

// Vertex shader
uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord; // Varying in vertex shader
void main(void)
{
gl_Position = u_matViewProjection * a_position;
v_texCoord = a_texCoord0;
}


// Fragment shader
precision mediump float;
varying vec2 v_texCoord; // Varying in fragment shader
uniform sampler2D s_baseMap;
uniform sampler2D s_lightMap;
void main()
{
vec4 baseColor;
vec4 lightColor;
baseColor = texture2D(s_baseMap, v_texCoord);
lightColor = texture2D(s_lightMap, v_texCoord);
gl_FragColor = baseColor * (lightColor + 0.25);
}

OpenGL ES著色器語言之變數和資料型別

三角形、條帶與扇面