OpenGL 渲染管線流程解析

OpenGL 渲染管線流程解析

這張圖對於想要掌握OpenGL的開發者非常重要.而且第一次看也許大家對於它的理解會比較薄. 希望大家能後期能夠多看這個圖. 因為我們在處理任何圖形渲染,都是依據它. 基於OpenGL 封裝的框架都是也都是遵循這個圖的規則.

接下來,我們來了解2個非常重要的端.

客戶端,服務端

這裡的客戶端和服務端並不是我們常說的iOS/安卓並稱為客戶端,後臺稱為服務端.

在這個圖中,管線分為上下2部分,上部分是客戶端,而下半部分則是服務端。

  • 客戶端是存儲在CPU存儲器中的,並且在應用程序中執行,或者在主系統內存的驅動程序中執行。驅動程序會將渲染命令和數組組合起來,發送給服務器執行!(在一臺典型的個人計算機上,服務器就是實際上就是圖形加速卡上的硬件和內存)
  • 服務器 和 客戶機在功能上也是異步的。 它們是各自獨立的軟件塊或硬件塊。我們是希望它們2個端都儘量在不停的工作。客戶端不斷的把數據塊和命令塊組合在一起輸送到緩衝區,然後緩衝區就會發送到服務器執行。
  • 如果服務器停止工作等待客戶機,或者客戶機停止工作來等待服務器做好接受更多的命令和準備,我們把這種情況成為管線停滯

著色器

上圖的Vertex Shader(頂點著色器) 和 Fragment Shader(片段著色器)。

  • 著色器是使用GLSL編寫的程序,看起來與C語言非常類似。 著色器必須從源代碼中編譯和鏈接在一起。最終準備就緒的著色器程序
  • 頂點著色器-->處理從客戶機輸入的數據、應用變換、進行其他的類型的數學運算來計算關照效果、位移、顏色值等等。(**為了渲染共有3個頂點的三角形,頂點著色器將執行3次,也就是為了每個頂點執行一次)在目前的硬件上有多個執行單元同時運行,就意味著所有的3個頂點可以同時進行處理!
  • ==圖上(primitive Assembly== 說明的是:3個頂點已經組合在一起,而三角形已經逐個片段的進行了光柵化。每個片段通過執行 片元著色器 進行填充。片元著色器會輸出我們將屏幕上看到的最終顏色值。

重點!

我們必須在這之前為著色器提供數據,否則什麼都無法實現!

有3種向OpenGL 著色器傳遞渲染數據的方法可供我們選擇

1.屬性

2.uniform 值

3.紋理

屬性、uniform值、紋理、輸出

屬性

屬性:就是對每一個頂點都要作改變的數據元素。實際上,頂點位置本身就是一個屬性。屬性值可以是浮點數、整數、布爾數據。

  • 屬性總是以四維向量的形式進行內部存儲的,即使我們不會使用所有的4個分量。一個頂點位置可能存儲(x,y,z),將佔有4個分量中的3個。
  • 實際上如果是在平面情況下:只要在xy平面上就能繪製,那麼Z分量就會自動設置為0;
  • 屬性還可以是:紋理座標、顏色值、關照計算表面法線
  • 在頂點程序(shader渲染)可以代表你想要的任何意義。因為都是你設定的。
  • 屬性會從本地客戶機內存中複製存儲在圖形硬件中的一個緩衝區上。這些屬性只提供給頂點著色器使用,對於片元著色器木有太大意義。
  • 聲明:這些屬性對每個頂點都要做改變,但並不意味著它們的值不能重複。通常情況下,它們都是不一樣的,但有可能整個數組都是同一值的情況。

Uniform值

屬性是一種對整個批次屬性都取統一值的單一值。它是不變的。通過設置uniform變量就緊接著發送一個圖元批次命令,Uniform變量實際上可以無數次限制地使用,設置一個應用於整個表面的單個顏色值,還可以設置一個時間值。在每次渲染某種類型的頂點動畫時修改它。

  • 注意:這裡的uniform 變量每個批次改變一次,而不是每個頂點改變一次。
  • uniform變量最常見的應用是在頂點渲染中設置變換矩陣
  • 與屬性相同點:可以是浮點值、整數、布爾值
  • 與屬性不同點:頂點著色器和片元著色器都可以使用uniform變量。uniform 變量還可以是標量類型、矢量類型、uniform矩陣。

紋理

傳遞給著色器的第三種數據類型:紋理數據

  • 在頂點著色器、片段著色器中都可以對紋理數據進行採樣和篩選。
  • 典型的應用場景:片段著色器對一個紋理值進行採樣,然後在一個三角形表面應用渲染紋理數據。
  • 紋理數據,不僅僅表現在圖形,很多圖形文件格式都是以無符號字節(每個顏色通道8位)形式對顏色分量進行存儲的。

輸出

在圖表中第四種數據類型是輸出(out);輸出數據是作為一個階段著色器的輸出定義的,二後續階段的著色器則作為輸入定義。

  • 輸出數據可以簡單的從一個階段傳遞到下一個階段,也可以用不同的方式插入。
  • 客戶端的代碼接觸不到這些內部變量我們的OpenGL開發暫時接觸不到。


分享到:


相關文章: