渲染原理

這是我在《游戲架構(gòu)-核心技術(shù)與面試精粹》看的,記錄一下~

啥玩意是渲染?
游戲圖像的繪制被稱為渲染

啥玩意是渲染管線?
表示繪制到游戲視圖的過程中,一個(gè)模型文件的數(shù)據(jù)經(jīng)過了哪些轉(zhuǎn)換步驟
通常指的是GPU流水線,不包含CPU部分

CPU主要是準(zhǔn)備好頂點(diǎn)、貼圖、法線、燈光方向、顏色等東西之后,告訴GPU
GPU接收到數(shù)據(jù)后,就要對(duì)其處理最終顯示到屏幕上

因?yàn)槠聊皇?D畫面,模型是3D資源,必然有一部操作,就是將3D轉(zhuǎn)化為2D。
這個(gè)操作之前被稱為頂點(diǎn)階段(幾何階段),主要是處理3D模型數(shù)據(jù)
之后被稱為片元階段(光柵化階段),處理2D像素?cái)?shù)據(jù)

1.頂點(diǎn)著色器(Vertex Shader)
如下所示:

#pragma vertex vert
struct v2f
{
  float4 pos : SV_POSITION;
  fixed4 color : COLOR;
};
v2f vert (appdata_base v)
{
  //vertex operation
}

每個(gè)頂點(diǎn)都會(huì)調(diào)用一次這個(gè)函數(shù),并轉(zhuǎn)化為這個(gè)函數(shù)的輸出,這些輸出被稱為圖元(Primitive)
一般可以在這里改變頂點(diǎn)或者法線相關(guān)信息

2.曲面細(xì)分(Tessellation Shader)
是OpenGL 4.0新加入的特性,很多設(shè)備還不支持
主要的作用是可以優(yōu)化曲面,eg:使曲面更平滑

3.幾何著色器(Gemoetry Shader)
幾何著色器的輸入輸出都是圖元(Primitive),不是頂點(diǎn)
可以將簡單的圖元擴(kuò)展成更為復(fù)雜的形式

4.變化回執(zhí)(Transform Feedback)
是在OpenGL 3.0之后加入的特性
可以將圖元存放到 Transform Feedback Buffer中,并可以決定是否按照先前的流程光柵化
主要特性:在下一幀渲染時(shí),可以得到上一幀圖元的數(shù)據(jù),對(duì)于定量變化的情況,可以節(jié)省掉流水線之前的步驟
(常被用于粒子系統(tǒng) or 角色的頭發(fā))

5.裁剪(Clipping)
圖元會(huì)根據(jù)視域的平截頭體(Frustums)做可見性判斷
區(qū)域外的定點(diǎn)會(huì)被舍棄,與這個(gè)定點(diǎn)連線的三角形的邊會(huì)與平截體求交點(diǎn),這些交點(diǎn)就變成裁剪后的新頂點(diǎn)

6.屏幕映射(Screen Transform)
圖元的坐標(biāo)從齊次裁剪空間變換到屏幕空間

7.圖元裝配(Primitive Assembly)
頂點(diǎn)會(huì)被轉(zhuǎn)化成基礎(chǔ)圖元,供后續(xù)步驟使用
三角形的朝向剔除(Face Culling)是在這個(gè)階段完成的

8.光柵化(Rasterization)
三角形會(huì)經(jīng)歷兩個(gè)步驟:
1.三角形會(huì)被轉(zhuǎn)化成片段
2.會(huì)遍歷三角形,獲取頂點(diǎn)屬性進(jìn)行插值,在每個(gè)像素點(diǎn)上產(chǎn)生一個(gè)插值

如果開啟了多重采樣抗鋸齒(Multisample Antialiasing,MSAA),此處就會(huì)對(duì)每個(gè)像素進(jìn)行多次采樣,產(chǎn)生多個(gè)偏遠(yuǎn),最后在混合,以達(dá)到抗鋸齒的效果

9.提前深度測試(Early Depth Test)
檢查片元的深度,如果不需要顯示則丟棄它
可以在片元著色器運(yùn)行之前去掉不合理的值,減少運(yùn)算的消耗
但是與后續(xù)的透明測試有沖突,如果在后續(xù)的透明度測試中失敗,這步深度測試也不應(yīng)該將其通過
有些GPU會(huì)判斷是否有此類沖突,如果有就跳過(有一定消耗)

10.片元著色器(Fragment Shader)
可以自定義光照計(jì)算、讀取貼圖顏色、設(shè)置透明度等
輸入是光柵化后得到的片元數(shù)據(jù),輸出值也為片元數(shù)據(jù)
Unity中會(huì)把函數(shù)返回值寫為運(yùn)算后的顏色

fixed4 frag (v2f i) : SV_TARGET
{
  //do framgent operation
}

11.逐片元操作(Pre-Sample Operation)
這個(gè)階段:主要是先測試后混合

測試共經(jīng)歷了4個(gè)測試:
他們的作用都是確定一個(gè)像素是否應(yīng)該顯示

1.裁切測試(Scissor Test)
通過區(qū)域判斷的,與基于頂點(diǎn)的 Clipping 階段不同

2.透明測試(Alpha Test)
透明度達(dá)不到,就不繪制

AlphaTest Greater 0.5

3.模板測試(Stencil Test)
通過緩沖區(qū)來進(jìn)行像素比較,與ColorBuffer或DepthBUffer,StencilBuffer是一個(gè)8位圖像,每個(gè)像素保存一個(gè)無符號(hào)整型

Stencil
{
  Ref 2
  Comp equal
  Pass Keep
  ZFail decrWrap
}

//也就是,通過按位與的操作比較兩側(cè)結(jié)果

if((RefValue & readMask) comparisonFunction (StencilBUfferValue * readMask))
{
  pass;
}
else
{
  discard;
}

4.深度測試(Depth Test)
通過深度緩沖區(qū)的比較,判斷是否應(yīng)該繪制像素
需要先制定深度寫入規(guī)則,然后再指定比較規(guī)則
分別對(duì)應(yīng)Unity的 ZWrtie 和 ZTest
(深度寫入不透明物體默認(rèn)打開,透明物體默認(rèn)關(guān)閉,測試方法默認(rèn)是小于等于)

混合階段主要有2個(gè)階段:
1.混合(Blending)
通過測試的顏色與ColorBuffer中顏色的疊加方式
混合有多種疊加方式,一般會(huì)使用RGBA的值作為計(jì)算因子,采用插值的方式進(jìn)行線性計(jì)算

Blend SrcAlpha OneMinusSrcAlpha

2.寫入遮罩(Write Mask)
主要是顏色遮罩(Color Mask),在最終繪制時(shí),對(duì)顏色進(jìn)行過濾

ColorMask RG

so,
經(jīng)過上面所有的步驟后,最終這個(gè)像素會(huì)被繪制到顏色緩沖區(qū),并被顯示到屏幕上

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容