1. 程式人生 > >UnityShader學習筆記1 — — 入門知識整理

UnityShader學習筆記1 — — 入門知識整理

空閑 vertex 相關 發布 rect triangle 節點 image style

註:資料整理自《Unity Shader入門精要》一書

一、渲染流程概念階段:

技術分享圖片

應用階段:(1)準備好場景數據:(如攝像機位置,物體以及光源等)

       (2)粗粒度剔除(Culling):(把不可見物體剔除,不導入下一階段)

       (3)設置每個模型的渲染狀態:(如材質、紋理、shader等),輸出渲染圖元(rendering primitives)(如點、線、三角面等幾何信息)並傳遞至下一階段

幾何階段:(1)在GPU上處理繪制幾何所需要的相關操作(具體操作細分在隨後的GPU流水線中介紹)

       (2)重要操作:把頂點坐標變換到屏幕空間中,再交給光柵器處理

       (3)隨後輸出屏幕空間的二維頂點坐標,每個頂點的深度值、著色信息等至下一階段

光柵化階段:(1)利用上一階段的數據在屏幕上產生像素,並渲染出最終圖像(由逐頂點數據 -> 到逐像素數據

註:這只是概念化的渲染階段,具體硬件上的流程請參考下面的GPU流水線

二、GPU流水線:

技術分享圖片

幾何階段

頂點著色器(Vertex Shader):完成的主要工作有:坐標變換和逐頂點光照

技術分享圖片技術分享圖片

裁剪(Clipping):將不在攝像機範圍內的物體剔除掉

技術分享圖片

屏幕映射(Screen Mapping):

    輸入:上一階段的單位立方體內的三維坐標

     輸出:二維屏幕坐標系(Screen Coordinates),與分辨率有關

     保留Z軸坐標(深度值),與屏幕坐標系構成窗口坐標系(Window Coordinates)

技術分享圖片

技術分享圖片

光柵化階段

光柵化階段有兩個重要目標:

    計算每個圖元覆蓋哪些像素

    替這些像素計算顏色

百科:光柵化(Rasterization)是把頂點數據轉換為片元的過程,具有將圖轉化為一個個柵格組成的圖象的作用

三角形設置(Triangle Setup):

    計算光柵化一個三角網格所需的信息(如坐標信息等)

三角形遍歷(Triangle Traversal)

    檢查每個像素是否被三角形網格所覆蓋,如果是,則生成一個片元(Fragment)

    通過三角網格來判斷覆蓋了哪些像素,並用3個頂點的頂點信息對這些像素插值

      註:片元並不相當於像素,相比於像素還多了很多信息(如坐標,深度值、法線、紋理坐標等)

技術分享圖片

片元著色器(Fragment Shader):

      輸入:上一階段的插值數據

        輸出:顏色值(一個或多個)

技術分享圖片

逐片元操作(Per-Fragment Operations(OpenGL)):

       (Output-Merger(DirectX))

  主要任務:(1)決定每個片元的可見性

        (2)如果一個片元通過所有測試,則把這個片元的顏色值和已儲存在顏色緩沖區中的顏色合並

  模範測試和深度測試是可配置的,通常將片元的模板值/深度值與開發者給定的值進行比較,然後決定是否舍棄該片元

  混合也是可配置的,決定是覆蓋上一次顏色緩沖區中值還是進行合並(如透明效果)        

技術分享圖片

技術分享圖片

技術分享圖片

三、其余補充

技術分享圖片

關於Draw Call

首先DrawCall通俗講就是CPU對GPU發出的一個命令(CPU調用圖像編程的API(如OpenGL和DirectX)以命令GPU開始渲染

大致上的渲染階段:CPU階段:CPU從硬盤中加載數據到顯存中 -> 設置好渲染狀態 -> DrawCall

GPU階段:參考上文第二部分GPU流水線        

技術分享圖片

        

  眾所周知,DrawCall會影響遊戲的幀數,而幀數則是由CPU和GPU兩者中較差的那個決定了瓶頸上限,因此當DrawCall多了以後,如上圖2.19所示,CPU需要一條條發布命令,而GPU由於對圖像的渲染能力很強,可以一次渲染多個三角網格,此時往往就會導致CPU處理速度跟不上無法及時給出命令,而GPU則會處於空閑狀態。

那如何減少DrawCall?

  (1)避免使用大量很小的網格,如果必須使用時可以考慮把他們合並成一張大網格,減少節點數

  (2)避免使用過多的材質

技術分享圖片

UnityShader學習筆記1 — — 入門知識整理