三維圖形渲染管線就是將三維場景轉化為一幅二維圖像的過程。
圖像中物體所處位置及外形由其幾何數據和攝像機的位置共同決定,物體外表是受到其材質屬性、光源、紋理及著色模型所影響。
管線過程由3個大的階段組成:
Application(應用程序階段):運行在CPU上,能被開發者完全控制,該過程所做操作包括:
① 準備場景數據
加載模型:Mesh、Material、Shader、Texture(硬盤 --> 內存 --> 顯存)
攝像機(位置、朝向、視錐體)
② 裁剪和剔除 :視錐裁剪、背面剔除、遮擋剔除 (Occlusion Culling)
③ 計算模型視圖矩陣
④ 設置渲染狀態(RenderState)
渲染管線內部維護著一些狀態值。在我們調用渲染API函數進行繪制之前我們需要設置這些狀態值。
這些狀態值指導GPU如何渲染我們傳遞到顯存的模型和紋理數據。我們稱這些狀態值為“渲染狀態(Render States) ”。
渲染狀態包括Shader、Texture、Material、Light內部定義的各種狀態等
最后,發起DrawCall調用
Geometry(幾何階段):負責與每個渲染圖元打交道,進行逐頂點、逐多邊形的操作。
其重要任務是把頂點坐標變換到帶有深度的屏幕空間中,再交給光柵器進行處理。
可進一步分割成:模型視圖變換,頂點著色,[曲面細分],[幾何著色],投影,裁剪及屏幕映射
模型變換:將模型從模型空間變換到世界空間
視圖變換:將各個模型從世界空間變換到眼空間(攝像機處于原點)
通常會把這兩個變換矩陣結合成modelview矩陣,并將這個過程稱之為模型視圖變換
頂點著色器:主要功能是修改頂點屬性。如:通過傳入模型視圖矩陣(MVP)進行頂點空間變換(位置屬性)、逐頂點光照(顏色屬性)、紋理坐標變換(uv屬性)等
頂點著色器的處理單元是頂點,也就是說,輸入進來的每個頂點都會調用一次頂點著色器。
頂點著色器只能對輸入頂點的相關屬性進行修改、創建和忽略,不可以創建或銷毀任何頂點,而且無法得到頂點與頂點間的關系。
輸入一般是一個變換矩陣和一個相對坐標;輸出為眼空間中的坐標及每個頂點所附帶的其他屬性,如顏色、紋理坐標
曲面細分著色器:用于細分圖元,分為3個階段。
Control Shader,負責把控后續階段的初始化操作,例如細化程度(可編程)
處理Control階段的輸出,細化Patch數據(不可編程)
Evaluation Shader的輸入為Patch數據;輸出數據為頂點著色器所應輸出的數據,但是是批量的(可編程)
幾何著色器:輸入是1個圖元,輸出是N個圖元(N>=0)
通過Shader程序可以指定Geometry Shader對頂點信息進行增減。還有,因為實際增減的是圖元頂點,所以對各種的線段、多邊形、粒子等圖元也可以進行增減。
利用Geometry Shader的各種方法被創造出來,因為可以自由的生成多邊形,那么就可以在地面上生長出草的多邊形,或者讓3D角色生長出毛發等是最基本的使用方法。
在游戲中,還可以把不需要做邏輯交互處理的例如火花等特效的表現,使用Geometry Shader來生成。
注:Geometry Shader通常是在display driver中實現的,也就是說其實是由CPU負責計算,當重新返回GPU的VS時,對流水線的影響很大,所以Geometry Shader的實際效能并不高,甚至是非常低
投影:分為透視投影與正交投影;在眼空間將模型從三維空間投影到二維平面(D3D投影平面為z=1.0,OpenGL為z=-1.0;為了便于理解,可將其定義為視景體近裁截面)
注:上圖為眼空間,D3D為左手系,OpenGL為右手系
投影完成后,會得到歸一化的設備坐標(Normalized Device Coordinates,NDC),方便下一步進行硬件裁剪
歸一化x、y分量到[-1.0, 1.0]
歸一化z深度值(D3D:[0.0, 1.0] OpenGL:[-1.0, 1.0])注:近裁截面為最小深度、遠裁截面為最大深度;
裁剪:將那些不在攝像機視野內的頂點裁剪掉,并剔除某些三角圖元面片
屏幕映射:將每個圖元的x、y坐標從NDC轉換到屏幕空間
注:D3D將屏幕左上角作為原點,x軸向右,y軸向下;OpenGL將屏幕左下角作為原點,x軸向右,y軸向上
Rasterizer(光柵化):對上個階段得到的圖元各頂點進行插值(z深度值、法線方向、紋理坐標、顏色等)來產生屏幕上的像素,并渲染出最終的圖像。
光柵化的任務主要是決定每個渲染圖元中的哪些像素應該被繪制在屏幕上
三角形設置:對三個頂點插值計算三角形邊上的像素
三角形遍歷:掃描三角形邊上的像素來插值計算整個三角形內的像素
片元著色器:逐片元的進行著色計算(即逐像素光照)。該階段可以完成很多重要的渲染技術 如:紋理采樣
逐像素、逐頂點光照差異性主要體現在對于非精細模型,在執行逐頂點光照時,由于點距較大,在進行顏色線性插值的過程中,無法精細平滑過渡,導致效果變差。
另外逐像素光照可以在渲染時添加并不存在的表面細節。如通過bump貼圖或normal貼圖,在原本平坦的表面表現出近似的凹凸效果。
當然,逐像素的計算量要比逐頂點要大
逐片元操作:有時也被稱為光柵操作(raster operations ,ROP)或混合操作(blend operations),通過設置來淘汰一些不合格的片元以及如何合并問題
如果一個片元通過了所有的測試,新生成的片元才能和顏色緩沖區中已存在的像素顏色進行Alpha混合,并寫入顏色緩沖區
? Alpha測試:
注1:并非所有顯卡都支持Alpha測試特性,使用前需要檢查顯卡是否有該能力
注2:由于大量片元會在該階段舍棄,Alpha測試可提高含大量透明物件場景的性能
? 模板測試:
注1:若建立模板緩沖區為8bits,則模板值的范圍為:[0, 255]的整數;其初始值為清理模板緩沖區的所設置的值
注2:若在模板測試時,關閉了深度測試,則深度測試始終通過
? 深度測試:
注1:深度值范圍(D3D:[0.0, 1.0] OpenGL:[-1.0, 1.0]),建立深度緩沖區位數越多,則深度值的精度就會越高;其初始值為清理深度緩沖區的所設置的值
注2:關閉了深度測試,意味著該片元始終通過深度測試
? Alpha混合:
FrameBuffer(幀緩沖)
幀緩沖器(frame buffer):在顯卡中硬件實現,用于存放渲染的最終結果。分為:單緩沖、雙緩沖(double buffering)、三重緩沖(Triple Buffering)
單緩沖:各個物體的渲染會直接畫在屏幕上,效率比較低,由于能看到中間繪制過程,會導致屏幕不斷閃爍。一般只用于顯示非動態的圖像
雙緩沖(double buffering):繪制是在一個后備緩沖器(backbuffer)中以離屏的方式進行的。一旦在后備緩沖器中完成繪制,
通過交換指令(D3為Present、OpenGL為SwapBuffer)就可將后備緩沖器中的內容與已經在屏幕上顯示過的前臺緩沖器(frontbuffer)中的內容進行交換,使得一個完整的幀顯示在屏幕上。
完成交換后,后備緩沖器變為前臺緩沖區,而前臺緩沖區變為后備緩沖區,為下一幀的繪制工作提前做好準備。
我們將前后緩沖區功能互換的行為成為提交(Presenting)。
由于只是將前臺緩沖區的指針和后備緩沖區的指針做一個簡單的交換,提交是一個運行速度很快的操作。
// OpenGL單緩沖glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glFlush(); //單緩沖的刷新模式;// OpenGL雙緩沖glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutSwapBuffers(); //雙緩沖的刷新模式;
三重緩沖(triple buffering):一個前臺緩沖區,兩個后備緩沖區。
在開啟了VSync垂直同步時,若游戲的FPS低于顯示器刷新頻率,三重緩沖可緩解卡頓現象,然而由于存在2個后備緩沖區,三重緩沖會導致畫面有一幀的延遲。(見下文說明)
顯示器
以CRT顯示器為例(液晶顯示器原理類似),CRT的電子槍從左到右,從上到下進行逐行掃描,掃描完成后顯示器就呈現一幀畫面,隨后電子槍回到初始位置繼續下一次掃描。
為了把顯示器的顯示過程和系統的視頻控制器進行同步,顯示器(或者其他硬件)會用硬件時鐘產生一系列的定時信號。
當電子槍換到新的一行,準備進行掃描時,顯示器會發出一個水平同步信號(horizonal synchronization),簡稱 HSync;
而當一幀畫面繪制完成后,電子槍回復到原位,準備畫下一幀前,顯示器會發出一個垂直同步信號(vertical synchronization),簡稱 VSync。
顯示器通常以固定頻率(如60HZ)進行刷新,這個刷新率就是 VSync 信號產生的頻率。
將顯卡與顯示器的刷新頻率通過一個稱為VSync的信號同步起來,保證顯示器上顯示的是一幀完整的畫面,來解決Tearing(撕裂)現象(多幀畫面同時繪制在顯示器上)。
假設游戲的FPS是100,顯示器的刷新頻率是75Hz,顯卡將比顯示器快1/3;這意味著,在1個顯示器刷新周期內,顯卡將寫入4/3的幀數據,也就是說,下一幀的1/3覆蓋在前一幀之上;
當然,隨著系統運行,1/3這個比例會發生變化,1/3,2/3,1,1/3,循環;這種幀與幀之間的不完全覆蓋重合現象就是撕裂現象。
D3DPRESENT_PARAMETERS md3dPP;md3dPP.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // 開啟垂直同步
當開啟了垂直同步,若游戲FPS高于顯示器刷新頻率時,顯卡會將一部分時間浪費在等待上,顯卡必須等待VSync信號的到來才能將繪制好的畫面推送給顯示器,這也使得游戲的最大FPS下降為顯示器的刷新頻率
這避免了顯卡做一些無用的工作,降低顯卡的功耗;然而,VSync技術也有缺點,會導致玩家輸入的響應出現延遲;另外,若游戲的FPS低于顯示器刷新頻率,那么系統的FPS將迅速下降為顯示器刷新頻率的分數倍上,加劇畫面卡頓(Shutter)
Triple Buffering(三重緩沖)可以緩解這一問題,示意圖如下:
然而,從上圖可以看出由于存在2個后備緩沖區,三重緩沖會導致畫面有一幀的延遲。
-
cpu
+關注
關注
68文章
10890瀏覽量
212407 -
攝像機
+關注
關注
3文章
1611瀏覽量
60169 -
三維
+關注
關注
1文章
511瀏覽量
29010
原文標題:三維圖形渲染管線
文章出處:【微信號:Imgtec,微信公眾號:Imagination Tech】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論