【OPENGL】第三篇 着色器基礎(一)


 


 

在這一章,我們會學習什么是着色器(Shader),什么是着色器語言(OpenGL Shading Language-GLSL),以及着色器怎么和OpenGL程序交互。

 


 

首先我們先來看看什么叫着色器。

Shader(着色器)是用來實現圖像渲染的,用來替代固定渲染管線的可編程程序。

着色器替代了傳統的固定渲染管線,可以實現3D圖形學計算中的相關計算,由於其可編程性,可以實現各種各樣的圖像效果而不用受顯卡的固定渲染管線限制。這極大的提高了圖像的畫質。

在上一篇文章( http://www.cnblogs.com/MyGameAndYOU/p/4681710.html )

關於OpenGL的第一個例子中,我們已經接觸過頂點着色器(Vertex Shader)以及片段着色器(Fragment Shader)的相關代碼。另外,有些書籍或者文章也將片段着色器稱為像素着色器(Pixel Shader)

 

話說回來,在我們了解着色器之前,讓我們先了解固定渲染管線(fixed-function pipeline)究竟是什么。

渲染管線,也稱之為渲染流水線,可以理解為工廠的流水線工作,而在這里它的工作是讓計算機把模型通過一系列的處理最終生成圖像的過程,

網上也有人這么描述它:渲染管線是顯示芯片內部處理圖形信號相互獨立的的並行處理單元。頂點管線在GPU中的作用就是處理幾何數據,並將3D數據投射到二維的屏幕上。借用一個網友說的簡單例子來通俗的說明一下頂點管線和像素渲染管線的作用。一個畫家在做畫的時候,都需要先把所畫人或物的輪廓,框架畫出來,這里我們稱之為“構圖”;然后再根據光照進行着色,這里我們稱之為“渲染”。頂點管線和像素渲染管線所起的就是這兩個作用,頂點管線和引擎負責把“輪廓、框架”畫出來,而像素渲染管線和引擎則負責對畫好的“輪廓、框架”根據光照等因素進行着色,構成一幅完整的圖形。渲染管線直接關系到顯卡對畫面的渲染性能。

那為何稱之為固定呢?這是說芯片上一組電路已經固定實現了特定的運算功能,程序能做的只是提供場景數據以及微調運算功能的參數。我們只能通過調用不同的API組合實現特定效果,但是比較死板。

 

那么問題又來了,流水線的處理過程分哪些步驟呢?

關於OpenGL的流水線,大家可以看這里的圖形流水線教程,非常詳細。CSDN博客地址:http://blog.csdn.net/racehorse/article/details/6593719

在這里,我借助前人的經驗,把相關的知識再進一步分享給大家。

 

一個固定渲染管線包括如下功能:

1、頂點變換(Vertex Transformation)

這里的頂點是信息的集合,包含空間中的位置、顏色、法線、紋理坐標等等。主要用於頂點位置變換、對每個頂點計算光照、紋理坐標的生成以及變換

2、圖元組合和光柵化(Primitive Assembly and Rasterization)

該階段處理的是上一個階段輸出的變換后的頂點以及它們的連接信息。連接信息用來描述頂點如何組成圖元(三角形、四邊形等等)。利用在頂點變換階段計算出的數據,結合連接信息計算出片段的數據。(例如,每個頂點包含一個變換后的位置,當它們組成圖元時,就可以用來計算圖元的片斷位置。另一個例子是使用顏色,如果多邊形的每個頂點都有自己的顏色值,那么多邊形內部片斷的顏色值就是各個頂點顏色插值得到的。)另外此階段還負責視錐體(view frustum)的剪裁和背面剔除。

光柵化決定了片斷(fragment),以及圖元的像素位置。這里的片斷是指一塊數據用來更新幀緩存(frame buffer)中特定位置的一個像素。一個片斷除了包含顏色,還有法線和紋理坐標等屬性,這些信息用來計算新的像素顏色值。本階段的輸出包括幀緩存中片段的位置,以及經過插值后的片段信息。

3、片斷紋理化和色彩化(Fragment Texturing and Coloring)

此階段的輸入是經過插值的片段信息。在前一階段已經通過插值計算了紋理坐標和一個顏色值,這個顏色在本階段可以用來和紋理元素進行組合。此外,這一階段還可以進行霧化處理。通常最后的輸出是片斷的顏色值以及深度信息。

4、光柵操作(Raster Operations)

此階段的輸入包括像素位置、片斷深度和顏色值。這個階段對片段進行一系列的測試,包括:剪切測試(scissor test)、Alpha測試、模版測試、深度測試

如果測試成功,則根據當前的混合模式(blend mode)用片段信息來更新像素值。注意混合只能在此階段進行,因為片斷紋理化和顏色化階段不能訪問幀緩存。幀緩存只能在此階段訪問。

 

一幅圖總結固定功能流水線(Visual Summary of the Fixed Functionality)

下圖直觀地總結了上述流水線的各個階段:

該圖的出處http://blog.csdn.net/racehorse/article/details/6593719

 

而在我們即將進行的着色器編程中,上述的流程,有兩個階段被編程替代

1、頂點變換(Vertex Transformation) 這個階段使用頂點着色器實現。

2、片斷紋理化和色彩化(Fragment Texturing and Coloring) 這個階段使用片段着色器實現。

 


 

 

在OpenGL 3.0版本之前(包含3.0),或者使用了兼容模式(compatibility profile)的OpenGL環境下,我們還可以使用之前的固定渲染管線,在不使用着色器的情況下處理幾何與像素數據。

但從3.1版本開始,固定渲染管線從核心模式(core profile)去除,所以如果使用該版本之后的核心模式來編程的話,我們必須使用着色器。

  

GLSL在OpenGL 2.0版本左右發布的(在之前是屬於擴展功能)。與OpenGL與時俱進,它是一種專門為圖形開發設計的編程語言,但我們可以從其身上找到C/C++的影子。

每一個着色器代碼看起來像是一個完整的C程序,同樣有一個main入口函數。但是與C不同的是,着色器的main函數沒有任何參數,在某個着色階段中的輸入和輸出的所有數據都是通過着色器中的特殊全局變量來傳遞的。最重要一點是,不要把它們與應用程序中的全局變量混淆,它們兩者沒有任何關系。

 

#version 430 core
 
in vec4 vPosition
in vec4 vColor;

out vec4 color;

uniform mat4 ModelViewProjectionMatrix;
 
void main(){
    color = vColor;
    gl_Position =  ModelViewProjectionMatrix * vPosition;
}

正如上面的代碼,OpenGL會使用輸入和輸出變量來傳遞着色器所需要的數據,變量的值會在OpenGL每次執行着色器的時候更新。

還有一種是變量是直接從OpenGL應用程序中接收數據的,稱為uniform變量。uniform表示唯一,對所有幾何圖元的值都是一致的,除非應用程序對它執行了更新,否則着色器是並不會影響它的值的變化的。

 


 

在這一小節中,我們主要了解什么是着色器,為什么會出現着色器,它和固定管線有什么區別。另外,還有圖形流水線知識,下一小節,我們會繼續學習GLSL的基本變量以及相關操作。

 

 

2015.08.12

     廣州

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM