如何理解OpenGL中著色器,渲染管線,光柵化等概念?

新手,沒有圖形學基礎。直接看看OpenGL編程指南,不太理解這幾個概念。求講其本質。


卧槽,前些日子看這幾個概念就十分想吐槽,這麼難理解的概念竊以為純屬翻譯的不夠接地氣。

————

首先,光柵化(Rasterize/rasteriztion)。

這個詞兒Adobe官方翻譯成柵格化或者像素化。沒錯,就是把矢量圖形轉化成像素點兒的過程。我們屏幕上顯示的畫面都是由像素組成,而三維物體都是點線面構成的。要讓點線面,變成能在屏幕上顯示的像素,就需要Rasterize這個過程。就是從矢量的點線面的描述,變成像素的描述。

如下圖,這是一個放大了1200%的屏幕,前面是告訴計算機我有一個圓形,後面就是計算機把圓形轉換成可以顯示的像素點。這個過程就是Rasterize。

————

渲染管線(Pipeline)

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

————

著色器(Shader)

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

通常著色器分兩種:

1頂點著色器(vertex shader)這個是告訴電腦如何打線稿的——如何處理頂點、法線等的數據的小程序。

2片面著色器(fragment shader)這個是告訴電腦如何上色的——如何處理光、陰影、遮擋、環境等等對物體表面的影響,最終生成一副圖像的小程序。

採用了這兩種著色器小程序 數據傳輸處理計算的渲染過程,稱之為 可編程管線。

————

以上,希望能讓樓主理解這些拗口的概念。


通俗點說,你告訴GL我要畫條線,然後告訴他線兩個端點的坐標是(0,0)和(0,10),那麼GL自動腦補出中間10個點的坐標,這個過程就叫光冊化,腦補的方法叫線性差值.

複雜點,現在我要畫個三角形,給他三個頂點的坐標,它會計算出裡面所有像素的坐標.

再複雜點,我不只給頂點坐標了,我告訴他(0,0)點是白色,(0,10)點是黑色,那麼光冊化就自動計算出中間10個點每個點的顏色,自動做過渡的效果.這個計算方法還是線性差值.

繼續通俗,線性差值也沒啥,小學算數罷了,誰都會. 不懂就自己計算如上10個點的坐標,計算過程就是線性差值. 沒錯,就這麼簡單.

著色器分兩個部分,一個頂點,一個片斷,中間就是光冊化.

也就是先頂點處理,計算出每個頂點的坐標,顏色,紋理坐標等等,也可以是任何其它千奇百怪的東西(壽命,溫度,身高,婚否,飯量………). 然後經過光冊化,給他們差值.最後片斷階段,你會獲得每個像素的坐標,顏色,紋理,壽命,溫度……

初學階段,你可以把片斷(fragment)理解成像素,其實意思差別不大,等你GL入門了,自然就理解這倆詞有啥區別了(ps:最討厭那些拽詞的,明明意思差不多,為了自己裝逼就非說倆詞怎麼怎麼不一樣,一點不考慮初學者的感受)

==========================

額,這段解釋有重要錯誤,有空我再修改………sorry


您可以參考:Graphics Pipeline或者圖形處理器架構(GPU Architecture)與圖形管線(Graphics Pipeline)入門裡的PDF。或者我試著用簡單直白的話語為您解釋一遍,或許專業性不強,如果能幫到您理解也不錯。

您提到的這幾個詞語,都和渲染管線相關,渲染管線的英文pipeline,可能翻譯成渲染流水線更好。您可以將其當成一個函數,函數內的實現又分為多個模塊。

pipeline(param)

{

param_a = function_a(param);

param_b = function_b(param_a);

......

return param_x;

}

你可以把以上這個函數畫成流程圖,實際上dx的手冊里就是畫流程圖了。有輸入,中間有很多模塊按順序處理最後輸出,你可以把渲染管線的輸出當成一個顏色的二維數組,返回給顯示器。

而其中的著色器 光柵化就是其中 function_xx內部使用到的實現細節,有時候我們使用這些名詞來表示function_xx這個結構本身。

對於圖形 api的使用者來說,為了能正確顯示圖像,往往要對整個pipeline的過程,順序有了解。一簡單流程如下:

管線程序段輸入=&>頂點著色器=&>光柵化=&>像素著色器=&>屏幕顏色

(上一個函數的)輸出 傳遞給=&> (下一個函數作為)輸入

下面簡單舉例過程幫助您理解:

使用opengl時,我們需要提供vertex buffer object index buffer object (vertex element array),也就是模型數據。您可以把這個模型數據當做pipeline的輸入param。接下來就開始了管線內部流程。

您輸入的模型數據,會把頂點數組(vbo)中的每個點拆開,單獨一個點當做參數輸入到頂點著色器里,你可以把頂點著色器看成一個叫做vertex_shader()的函數,把整個過程想像成

for_each(v in vbo){ vertex_shader(v); },或者一個多線程處理。

處理完後,你的頂點會附著上一些通用信息,比如紋理uv之類的,你可以把一個頂點當做一個struct;管線會根據vbo ibo 拼成多個三角形,把這些三角形送入光柵化過程,三角形會被打散成一個個的小像素。

這些像素會唄當做參數傳入像素著色器,過程和頂點著色器類似。

對於可編程管線來說,vertexshader pixelshader(opengl里叫fragment shader 片段著色器)這兩個函數,也需要在渲染前通過api設置好,你可以想像成在把你的函數安裝到顯卡上處理著色器的模塊里去。

這個流程的模塊,是會隨著版本升級而有一些變化的。對於opengl來說,早期固定管線的內容,國內能接觸到的教程,更多強調的是每個模塊如何使用,怎麼調用api,而忽略了管線模塊的順序這些說明,同時讀者也會忽略管線模塊輸入輸出這些令人困擾的內容。

可編程管線的教程又略微有點滯後。比起使用directx的初學者來說,可能對管線的概念更模糊一些。

directx在幫助手冊里就能看到每個版本的管線內容。opengl現在文檔已經慢慢完善,您可以看看官網上的手冊和wiki。

您說的 著色器屬於可編程管線的內容。對於可編程管線的內容,還是好好了解整個管線的內容再動手使用api比較好。每個具體的內容,樓上各位大神已經描述得很詳細了。

手機排版感人,希望對您有幫助。


我覺得百度百科講的挺好的,大概意思都講到了。

光柵化:光柵化_百度百科 (注意看配圖)

渲染管線:OpenGL: 渲染管線理論 (這個就不放百科了,廢話多)

著色器:著色器_百度百科

百度覺得不好,就 Google。

OpenGL Rendering Pipeline__Google連接中


整個流程是為了輸出圖形,屏幕上顯示的圖形就是每一個像素有不同的顏色,那我們要做的就是設置所有的像素的值。

上面這個東西整個就是渲染管線,他的工作流程就是把頂點數據傳入頂點著色器,opengl會裝配成圖元,變成3D物體,就像第一張圖那樣中的場景,近截面和遠截面中間這個部分就叫做視口,顯示的圖形就是這部分中的物體,超出的物體會被忽略掉,然後經過投影,歸一化等操作(矩陣變換)將圖形顯示到屏幕上,經過投影變換,然後經過光柵化轉變成像素圖形,再經過片段著色器給像素染色,最後的測試會決定你同一個位置的物體到底哪一個可以顯示在屏幕上以及顏色的混合。你可以看看這篇http://mp.weixin.qq.com/s/NoQRro0RYpN9ddac69aMJg

還有http://learnopengl.com這個還有中文網站

我說錯的地方望糾正和指導


直接看代碼吧,比較好理解

GitHub - zxx43/Software-Render: 軟體渲染器


推薦閱讀:

什麼類型的人需要學習 OpenGL?
想用C++實現一個軟體渲染器,類似DX和OpenGL,除了《3D遊戲編程大師技巧》,或者什麼網站推薦?
現階段應該怎麼學習計算機圖形學呢?
計算機圖形學是否已經進入瓶頸期?
為什麼高解析度屏幕在使用低解析度時無法做到點對點映射?

TAG:OpenGL | C | 計算機圖形學 | DirectX |