1. 程式人生 > >OpenGL ES 之OpenGL ES 1.X的渲染管線

OpenGL ES 之OpenGL ES 1.X的渲染管線

本文圖片和內容來自 <Android 3D 遊戲開發技術寶典>
OpenGL ES 是OpenGL三維圖形API的子集,主要針對手機等嵌入式裝置。 OpenGL ES主要分為兩個版本
    • 一個是OpenGL ES1.x,其採用的是固定功能渲染管線,可以由硬體GPU支援或用軟體模擬實現,渲染能力有限,在純軟體模擬情況下效能也較弱。
    • 另一個就是OpenGL ES 2.0,其採用的是可程式設計渲染管線,渲染能力大大提高。OpenGL ES 2.0要求裝置中必須有相應的GPU硬體支援,目前木支援在裝置上用軟體模擬實現。
著色器與渲染管線:
  • OpenGL ES 1.X 的渲染管線
    • 渲染管線有時也稱之為渲染流水線,一般是由顯示卡(GPU)的內部處理圖形訊號的並行處理單元組成。這些並行處理單元兩兩之間是相互獨立的,在不同的GPU上獨立處理單元的數量也有很大差異,一般越高階顯示卡,該單元的數量就越多。
    • 有些沒有GPU硬體的裝置上也有采用軟體模擬實現管線中各個處理單元的情況,效率低下。
    • 渲染流水線
      • 基本處理
        • 該階段設定3D空間中物體的頂點座標、頂點對應的顏色、頂點的紋理座標等屬性並且指定繪製方式,如:點繪製、線段繪製或者三角形繪製等等。
      • 頂點緩衝物件
        • 該部分功能在應用程式中是可選的,對於某些在整個場景中頂點的基本資料不變的情況,可以在初始化階段將頂點資料經過基本處理後送入頂點緩衝物件,在繪製每一幀想要的影象時就省去了頂點資料IO的麻煩,直接從頂點緩衝物件中獲取頂點資料即可。相比於每次繪製時單獨將頂點資料送入GPU的方式,可以在一定程度上節省GPU的IO頻寬,提高渲染效率。
      • 變換和光照
        • 該階段的工作主要是進行頂點變換以及根據程式中設定的光照屬性對頂點進行光照計算。頂點變換的任務是對3D物體的各頂點進行平移、旋轉或者縮放等操作。光照計算的任務是根據程式送入的光源位置、性質、各通道強度、物體的材質等,公式再根據一定的光照數學模型計算各頂點的光照情況。
      • 圖元裝配
        1. 這個階段主要有兩個任務,一個是圖元組裝,另一個是圖元處理。
          1. 所謂圖元組裝是指頂點資料根據設定的繪製方式被結合成完整的圖元。例如,點繪製方式僅需要一個單獨的頂點,此方式下每個頂點為一個圖元;線段繪製方式則需要兩個頂點,此方式下每兩個頂點構成一個圖元;三角形繪製方式下需要三個頂點構成一個圖元。
          2. 圖元處理最重要的工作是裁剪,其任務是消除位於半空間(half-space)之外的部分幾何圖元,這個半空間是由一個剪裁平面所定義的。例如,點剪裁就是簡單的接受或者拒絕頂點,線段或者多邊形剪裁可能需要增加額外的頂點,具體取決於直線或者多邊形與剪裁平面之間的位置關係
          3. 之所以要進行裁剪時因為隨著觀察位置角度的不同,並不總能看到(顯示到裝置螢幕上)特定3D物體某個圖元的全部
          4. 裁剪時,若圖元完全位於視景體以及自定義裁剪平面的內部,則將圖元傳遞到後面的步驟進行處理;如果完全位於視景體或者自定義裁剪平面的外部,則丟棄該圖元;如果其有一部分位於內部,另一部分位於外部,則需要裁剪該圖元。
      • 光柵化
        • 雖然虛擬3D世界中的幾何資訊是三維的,但由於目前用於顯示的裝置都是二維的,因此在真正執行光柵化工作之前,首先要將虛擬3D世界彙總的物體投影到視平面上。根據攝像機位置的不同,同一個3D場景的物體投影到視平面可能會產生不同的效果。
        • 另外,由於虛擬3D世界當中物體的幾何資訊一般採用連續的數學量來表示,因此投影的平面結果也是用連續的數學量表示的。但目前的顯示裝置螢幕都是離散化的,因此還需要將投影的結果離散化。將其分解為一個一個離散化的小單元,這些小單元一般稱之為片元。
        • 其實每個片元都對應幀緩衝中的一個畫素,之所以不直接稱之為畫素是因為3D空間中的物體時可以相互遮擋的。而一個3D場景最終顯示到螢幕上雖然是一個整體,但每個3D物體的每個圖元是獨立處理的。可能出現這種情況,系統先處理的是位於觀察點較遠的圖元,其光柵化成為了一組片元,暫時送入幀緩衝的相對應位置。但後面繼續處理距離觀察點較遠的圖元是也光柵化了一組片元,兩組片元中有對應到幀緩衝中同一個位置的,這時距離近的片元將覆蓋距離遠的片元(如何覆蓋的檢測是在深度檢測階段完成)。因此某片元就不一定能成為最終螢幕上的畫素,稱之為畫素就不準確了,可以理解為候選畫素。
        • 每個片元包含其對應的頂點座標、頂點顏色、頂點紋理座標以及頂點的深度等資訊,這些資訊是系統根據投影前此片元對應的3D空間中的位置及與此片元相關的圖元的各頂點資訊進行插值計算而生成的。
      • 紋理環境和顏色求和
        • 該階段主要兩個任務
        • 一個是紋理取樣任務,根據當前需處理片元的紋理座標及採用的紋理id對應的紋理圖進行紋理取樣,獲取取樣值。所謂紋理取樣就是從紋理圖中某個紋理座標位置獲取的一個顏色值。
        • 另一個是顏色求和,主要是執行顏色的變化,其根據紋理取樣及光照計算等的結果綜合生成需要處理片元的顏色。
        • 該階段主要是根據程式中設定的霧的相關引數,如:顏色、濃度、範圍等,以及某種霧的數學模型來計算當前處理的片元受霧影響後的顏色。
      • Alpha測試
        • 如果程式中啟用的Alpha測試,OpenGL ES會檢查每個片元的Alpha值,只有Alpha值符合測試條件的片元才會進入下一階段,不滿足條件的片元則被丟棄。
      • 剪裁測試
        • 如果程式中啟用了裁剪測試,OpenGL ES 會檢查每個片元在幀緩衝中對應的位置,若對應位置在裁剪視窗中則將此片元送入下一個階段,否則丟棄此片元。
      • 深度測試和模板測試
        • 深度測試是指將輸入片元的深度值與幀緩衝中儲存的對應位置片元的深度值進行比較,若輸入片元的深度值小則將輸入片元送入下一階段準備覆蓋緩衝區中的原片元或與原片元混合,否則丟棄輸入片元。
        • 模板測試的主要功能為將繪製區域限定在一定的範圍內,一般用在湖面倒影、映象等場合。
      • 顏色緩衝混合
        • 若程式開啟了Alpha混合,則根據混合因子將上一階段送來的片元與幀緩衝中對應位置的片元進行Alpha混合;否則送入的片元將覆蓋幀緩衝中對應位置的片元。
      • 抖動
        • 抖動是一種簡單的操作,其允許只使用少量的顏色模擬出更寬的顏色顯示範圍,從而使顏色視覺效果更加地豐富例如,可以使用白色以及黑色模擬出一種過渡的灰色。
        • 但使用抖動也是有固有的缺陷的,那就是會損失一部分解析度,因此對於現在主流的原生顏色就很豐富的顯示裝置一般是不需要抖動的。
        • 當下的一些系統中雖然在API方面支援開啟抖動,但這僅僅是為了API的相容,其可能根本不會去進行實時上的抖動操作。
      • 幀緩衝
        • OpenGL ES中的物體繪製並不是直接在螢幕上進行的,而是預先在幀緩衝中進行繪製,每繪製完一幀在將繪製的結果交換到螢幕上。因此,在每次繪製新的一幀時都需要清除緩衝區中的相關資料,否則有可能產生不正確的繪製效果。
        • 同時需要了解的是為了應對不同方面的需要,幀緩衝是由一套元件組成的,主要包括顏色緩衝、深度緩衝以及模板緩衝,
          • 顏色緩衝用於儲存每個片元的顏色值,每個顏色值包括RGBA四個色彩通道,應用程式執行時在螢幕上看到的就是顏色緩衝中的內容。
          • 深度緩衝用來儲存每個片元的深度值,所謂深度值是指以特定的內部格式來表示的從片元處到觀察點的距離。在啟用深度測試的情況下,新片元想進入幀緩衝是需要將自己的深度值與幀緩衝中對應位置片元的深度值進行比較,若結果小菜有可能計入緩衝,否則被丟棄。
          • 模板緩衝用來儲存每個片元的模板值,供模板測試使用。模板測試是幾種測試用最為靈活和複雜的一種。