「技美之路 第01篇」圖形 1.1 渲染流水線

遊資網發表於2021-05-07
今日起開始分享學習技美之路專欄,文章來源聽課筆記以及業界大佬分享的經驗文章,主要來自CSDN_知乎等。技美路漫長 一定要堅持  開始吧!

一.整體流程

整體流程(渲染管線可分為四個階段)每一個階段的輸出為下一個階段的輸入

「技美之路 第01篇」圖形 1.1 渲染流水線

應用階段:準備的是場景,你的物件的基本資料,比如說場景裡面的物體他們的位置朝向、大小以及物體對應的模型裡邊每一個頂點的位置,法線、切線等等;場景光源的位置朝向和一些基本屬性,還有攝像機的位置朝向等等。這些資料用處在哪裡,進入下一個階段

幾何階段:首先在頂點著色器裡,我們有可能需要計算頂點光照,那麼頂點光照就需要知道光源的位置和朝向以及攝像機的位置和朝向,還有當前頂點的世界位置,通過這些資料來進行計算,曲面細分著色器,需要通過現有的頂點來生成更多的頂點,那麼也需要知道現有頂點在模型裡的位置資訊。幾何著色器,需要通過現有的圖元來做一些幾何方面的操作,生成更多的頂點和圖元比如對現有圖源所在的平面生成法線 那麼同樣需要知道現有圖源的頂點的位置,同樣的幾何階段要為光柵化階段準備資料

比如要幹掉看不到的螢幕以外的頂點,這就是頂點裁剪

還需要把頂點位置從 3D座標空間轉換到2D座標空間,這就是螢幕對映

光柵化階段:拿到對映到2D空間裡的頂點位置,我們要把它組裝成三角形,這就是三角形設定然後還要知道三角形包含了哪些2D空間的畫素點,這就是三角形遍歷最後我們要對這些點使用它們包含的資料來著色,並且為後面的逐片元著色準備資料

逐片元操作:我們的操作物件就變成了光柵化操作輸出的片後設資料,片元可以理解成為螢幕上的某一個畫素點,對於這些片元我們需要進行一系列的測試。比如透明度測試,深度測試和模板測試,通過測試的片元就保留起來,否則就丟棄掉,然後在2D螢幕座標系當中,同一個位置上的畫素點有可能會對應於多個不同的片元,那麼我們可能還需要把這些通過測試的片元的顏色進行一個混合操作,從而得到畫素點最終輸出的顏色,逐片元操作完成以後,我們就得到了一個類似於貼圖的資料儲存在記憶體裡,然後我們對這個資料還可以做一個後處理,可以理解成為影像處理,比如模糊、景深、高光等等,那麼這樣的話渲染管線每個階段之間的關係大概就講清楚了。

二.分階段介紹

「技美之路 第01篇」圖形 1.1 渲染流水線

應用階段

「技美之路 第01篇」圖形 1.1 渲染流水線

在渲染管線中,應用階段是在CPU中進行處理的

「技美之路 第01篇」圖形 1.1 渲染流水線

  • 首先是準備場景,從磁碟或是記憶體上讀取模型或者貼圖資料,將其載入進應用程式中,物件為基本資料:包括不限於場景中的物體的位置,朝向,大小,物體網格資料,頂點位置,UV貼圖,法線,切線等;場景的光源位置朝向,型別,引數屬性等;攝像機位置朝向,模式,視口長寬比等等…

補充:光源和陰影

設定光源:

1.方向光,顏色,方向等
2.點光源:顏色,位置,範圍等
3.聚光源:顏色,位置,方向,內外圓錐角等

設定陰影:

1.是否需要陰影:判斷該光源可見範圍內是否有可投陰影的物體
2.陰影引數:對應光源序號,陰影強度,級聯引數,深度偏移,近平面偏移等

逐光源繪製陰影範圍:

1.近平面偏移
2.逐級聯

計算當前光源+級聯對應的觀察矩陣,投影矩陣,以及對應到陰影貼圖裡的視口區域

繪製到陰影貼圖

  • 加速演算法,粗粒度剔除:處理遮擋的問題,不會看到的,就不渲染,降低渲染成本,提高渲染效能

  • 可見光裁剪:點光和聚光有衰減,聚光錐體有區域;若離相機距離較遠,或者光錐與相機的視錐體不相交,則剔除渲染;
  • 可見場景物體裁剪:遮擋啥的,相關演算法:八叉樹,BSP樹,k-D樹,PVH包圍盒等
  • 說起裁剪就不由想起圖形學裡的經典裁剪演算法:Liang-Barsky演算法,Cohen-Sutherland演算法(編碼裁剪演算法)這兩個演算法是用於將影像裁剪到可見範圍內

  • 設定渲染狀態,準備渲染引數:渲染UI和場景,其引數和模式可能不一樣,通俗解釋:場景中的網格如何被渲染,渲染順序是啥,使用哪個頂點著色器/片元著色器,光源屬性,材質,最後會渲染到哪裡,渲染模式等等…

  • 繪製設定:使用著色器,合批方式(gpu 動態合批)
  • 繪製物體順序:相對相機距離,材質RenderQueue, UICanvas等
  • 渲染目標:FrameBuffer, RenderTexture...
  • 渲染模式:前向渲染(ForwardBase ForwardAdd),延遲渲染

「技美之路 第01篇」圖形 1.1 渲染流水線

  • 呼叫DrawCall,輸出渲染圖元到視訊記憶體:圖元從CPU邁向GPU
  • DrawCall是一個命令,發起方是CPU,接收方是GPU。僅指向一個需要被渲染的圖元(Primitives)列表。

  • 頂點資料:位置,顏色,法線,紋理uv座標,其他頂點資料
  • 其他資料:MVP變換矩陣,紋理貼圖,其他資料

「技美之路 第01篇」圖形 1.1 渲染流水線

幾何階段

  • 頂點著色器(VertexShader):完全可程式設計,實現頂點的空間變換、頂點著色等
  • 曲面細分著色器(TessellationShader):可選著色器,用於細分圖元
  • 幾何著色器(GeometryShader)可選著色器,執行逐圖元著色操作
  • 裁剪(Clipping):將不在相機視野內的頂點裁剪掉,可配置
  • 螢幕對映(ScreenMapping):不可配置和程式設計

「技美之路 第01篇」圖形 1.1 渲染流水線

「技美之路 第01篇」圖形 1.1 渲染流水線

幾何階段,光柵化,逐片元這些操作都是在GPU中進行處理的,那麼在講幾何階段前,我們先聊聊為什麼要用GPU渲染?

答:GPU的特點是並行性較好。當我們在對頂點資料進行處理時,他們雖然資料不同,但光照,幾何運算方式啥都一樣的時候,那麼我們將他們放在GPU的不同工作單元上進行同時執行,速度會更快。

「技美之路 第01篇」圖形 1.1 渲染流水線

頂點著色器:必須完成的一個工作:將頂點座標從模型空間轉換到齊次裁剪空間(投影座標系),同時它還有計算頂點光照的功能,這需要獲取應用階段中光源位置朝向,攝像機位置朝向,當前頂點的世界位置(獲取該位置需知道頂點在模型空間的位置,模型本身的位置旋轉縮放…);

「技美之路 第01篇」圖形 1.1 渲染流水線

頂點著色器-檢視變換:模型座標系--(模型變換) --> 世界座標系--(檢視變換)-->檢視座標系 --(投影變換)-->投影座標系--(視口變換)-->視口座標系 上圖中的前三個變換對應MVP(model view projection)矩陣,在頂點著色器中,頂點從模型座標系轉換到投影座標系,最後一步由Unity幫忙完成

曲面細分著色器:通過現有頂點生成更多的頂點,需獲取頂點在模型中的位置資訊

它是一個可選著色器,使用頂點著色器輸出的頂點,按照一定規則演算法生成更多頂點,將現有的網格和圖元細分(其效果類似於MAYA中的“平滑”效果,模型圓滑了但面數增大了)

幾何著色器(基於圖元):通過現有的圖元做些幾何方面操作,生成更多頂點和圖元,比如對現有圖元所在平面生成法線,需獲取現有圖元頂點位置

圖元是啥?

答:可以為頂點,線段,倆頂點,三角形...基礎的幾何圖形

投影:將3D空間投到2D空間

「技美之路 第01篇」圖形 1.1 渲染流水線

對於頂點在裁剪空間裡的位置,xyzw進行透視除法:xyz除以w完成投影。使其從投影座標系轉換到標準裝置座標系(NDC);

由於正交和透視視角下w值不同,故而呈現效果不同,正交顯得像截圖,透視則近大遠小

頂點裁剪:消去螢幕外的頂點;

不在相機視野內的物體不需要被處理。一個圖元和相機視野有3種關係:

完全在視野內:繼續傳遞給下一階段
部分在視野內:需要進行裁剪(Clipping),使用新的頂點來代替
完全在視野外:不會向下傳遞

「技美之路 第01篇」圖形 1.1 渲染流水線

- 投影裡又說要進行除法操作,當xyz超過-1~1範圍,則判斷其不在範圍內,

捨棄進行經典的圖形學裁剪演算法;

- 投影和頂點裁剪在《Shader入門精要》中都是歸屬於裁剪一節中,這個操作過程無法由程式碼控制,是硬體上固定操作,但可以自定裁剪操作進行配置

- 裝置座標系在opengl和DirectX中不一樣,opengl xyz三維度取值範圍都是-1~1,DirectX只有xy是-1~1,z為0~1

螢幕對映:

將頂點位置從3D座標空間轉換到2D座標空間;

螢幕對映(ScreenMapping)的任務是把每個圖元x和y座標轉換到螢幕座標系(ScreenCoordinates)。不處理z座標。opengl和DirectX原點不同,opengl左下方,DirectX左上方

「技美之路 第01篇」圖形 1.1 渲染流水線

按照《Shader入門精要》所言:螢幕對映任務是把每個圖元的x和y座標轉換到螢幕座標系。

如應用階段為幾何階段準備資料一樣,幾何階段同樣會為光柵化階段準備資料

光刪化階段

三角形設定:拿到對映於2D空間裡的頂點位置,組裝成三角形;

三角形遍歷:尋找被三角形覆蓋的所有畫素的過程,知曉包含哪些2D空間畫素點

《Shader入門精要》:三角形遍歷階段將檢查每個畫素是否被一個三角網格所覆蓋,若覆蓋,則生成一個片元。

片元非畫素,它是包含很多狀態的集合,這些狀態用於計算每個畫素的最終顏色,這些狀態包含不限於,螢幕座標,深度資訊,從幾何階段輸出的頂點資訊,法線,紋理座標等。螢幕同一個畫素位置可能有對應多個三角形的不同片元(如兩片重疊的交集)

抗鋸齒(MSAA):

1.SSAA:

渲染到一個解析度放大n倍的buffer:螢幕解析度1024x1024,渲染得到buffer可為2048x2048,放大四倍,對其取樣後再輸出螢幕

對方打n倍的buffer下采樣

2.MSAA

只有它發生在光柵化階段

計算多個覆蓋樣本:覆蓋測試看子取樣點是否在三角形以內,遮擋測試看這個子取樣度的深度和,即與深度快取中數值進行比較,看能否通過,若能通過兩測試,則說明取樣點屬於三角形,得到覆蓋資訊並儲存,用於之後的著色混合

3.FXAA/TXAA

後處理技術


逐片元操作

「技美之路 第01篇」圖形 1.1 渲染流水線

決定可見性:

模板測試(StencilTest):將片元位置的模板值,和參考值進行比較

深度測試(DepthTest):將片元的深度值,和深度緩衝區的深度值進行比較

合併顏色。對於不透明物體,可以關閉混合,用片元著色器得到的顏色值覆蓋顏色緩衝區的畫素值。對於半透明物體,要混合。

如果在執行片元著色器之前就進行這些測試,可以提高GPU效能,早點知道那些片元會被捨棄。深度測試提前執行的技術Early-Z。透明度測試會導致禁用提前測試,使效能下降。

為了避免我們看到正在進行光柵化的圖元,GPU會使用雙重緩衝(DoubleBuffering)。渲染在幕後,在後置緩衝(BackBuffer)中,一旦完成,GPU會交換後置緩衝區和前置緩衝(FrontBuffer)的內容。

後處理

Bloom,HDR,FXAA,景深,邊緣檢測,徑向模糊

什麼是OpenGL/DirectX

OpenGL/DirectX影像應用程式設計介面。執行在CPU上的應用程式->呼叫OpenGL/DirectX等圖形介面,將資料存在視訊記憶體,

發出DrawCall->顯示卡驅動翻譯成GPU能理解的程式碼。

「技美之路 第01篇」圖形 1.1 渲染流水線

什麼是HLSL、GLSL、CG

著色語言(ShadingLanguage):

DirectX的HLSL(HighLevelShadingLanguage)

OpenGL的GLSL(OpenGLShadingLanguage)

NVIDIA的CG(C for Graphic)

在UnityShader中,可以選擇使用哪種,但有所區別。

什麼是DrawCall

DrawCall,CPU呼叫影像程式設計介面,以命令GPU進行渲染的操作。

問題一:CPU和GPU是如何實現並行工作的?

命令緩衝區(CommandBuffer),讓CPU和GPU可以並行工作。CPU向其中新增命令,GPU從中讀取命令,新增和讀取的過程是相互獨立的。

「技美之路 第01篇」圖形 1.1 渲染流水線

問題二:為什麼DrawCall多了會影響幀率?

GPU渲染能力很強,速度往往快於CPU提交命令的速度。如果DrawCall的數量太多,CPU會耗費大量時間造成過載。

「技美之路 第01篇」圖形 1.1 渲染流水線

問題三:如何減少DrawCall?

這裡討論批處理方法(Batching)。把很多小的DrawCall合併成一個大的DrawCall,更適合合併靜態的物體,因為只需合併一次。

「技美之路 第01篇」圖形 1.1 渲染流水線

為了減少DrawCall的開銷,需要注意:

避免使用大量很小的網格,合併小網格

避免使用過多的材質,儘量在不同網格之間共用同一個材質

什麼是固定管線渲染

固定函式的流水線(Fixed-Function Pipeline),簡稱為固定管線,只給開發者一些配置操作。隨著時代的發展,可程式設計渲染管線應運而生,如頂點著色器、片元著色器。

那麼,你明白什麼是Shader了嗎

Shader所在階段,就是渲染流水線的一部分:

GPU流水線上一些可高度程式設計的階段,由著色器編譯出來的最終程式碼會在GPU上執行

有一些特定型別的著色器,如頂點著色器、片元著色器

依靠著色器我們可以控制流水線中的渲染細節

相關閱讀:
「技美之路 第02篇」圖形 1.2.1 向量基礎

文獻地址:感謝作者無私分享
CSDN:古守音
https://blog.csdn.net/qq_43210334/article/details/114646000
知乎:天劍行風
https://zhuanlan.zhihu.com/p/346384550
參考《Shader入門精要》·馮樂樂女神著
B站視訊 “技術美術百人計劃”·霜狼_may

來源:Game藝視界
原文:https://mp.weixin.qq.com/s/qbTAGtATracbyI4W_HPjxw

相關文章