學(xué)習(xí)Shader(著色器)必須先要了解渲染管線。如果不了解,那么就不能說你了解Shader
Shader分類
頂點(diǎn)著色器
像素著色器
這兩種著色器都是需要通過渲染管線來進(jìn)行工作的!
1-什么是渲染管線?
我們通過屏幕看到的畫面,都是二維的。即便他是3D物體。所以渲染管線就是生成或者渲染一張二維紋理。
2-渲染管線的分類
管線分為固定管線和可編程管線,現(xiàn)在的設(shè)備基本都配備可編程管線的GPU(即顯卡)。
3-什么是渲染管線圖
3D物體從自身的數(shù)據(jù)送入開始到最后呈現(xiàn)在屏幕上的所有歷程。

順著箭頭方向,數(shù)據(jù)一步一步被處理,最后寫到顯示緩沖區(qū)(Framebufffer)




4-渲染管線的組成
4-1:頂點(diǎn)處理
- 通過一系列的坐標(biāo)轉(zhuǎn)換,將模型的頂點(diǎn)在攝像機(jī)前進(jìn)行位移,并最終投影到攝像機(jī)的投影屏幕上

在這個(gè)階段進(jìn)行了坐標(biāo)轉(zhuǎn)換,逐頂點(diǎn)霧化,材質(zhì)屬性和光照屬性處理。
4-2: 面處理
- 面的組裝
一般由引擎來處理。美術(shù)資源其實(shí)就是頂點(diǎn)的集合,根據(jù)索引的順序進(jìn)行面的集合,然后就展示出模型的效果了。


- 面截取
這些集合的面,由于攝像機(jī)的視口大小進(jìn)行刪減頂點(diǎn)。 這種刪減方式大都通過算法進(jìn)行截取

- 面剔除
面的剔除,例如Unity中的正面剔除,反面剔除, 視錐剔除(去掉視錐外的面的部分,如下圖),遮擋剔除(去掉被遮擋的物體)等

通過硬件提供的深度緩存(Depth Buffer/z-buffer)來判斷。

4-3:光柵化
將以向量為基本結(jié)構(gòu)的面轉(zhuǎn)換稱一個(gè)個(gè)點(diǎn)陣形式的像素

使用算法,最普通的就是Bresenhamis算法(特點(diǎn):只使用整數(shù)運(yùn)算,不使用round()函數(shù),適用于線段和圓弧,獲得最優(yōu)化,最接近的結(jié)果。)
4-4:像素處理
對(duì)每個(gè)像素區(qū)域進(jìn)行著色,對(duì)像素貼上貼圖,形成最終的畫面
這里分兩部分
- 輸入:像素的位置,深度,貼圖坐標(biāo),法線,切線,顏色等
- 輸出:每個(gè)像素的顏色,透明度
將通過顯卡完成的像素顏色之,存入顯存中。

4-4:頂點(diǎn)處理
頂點(diǎn)渲染的作用是對(duì)三維圖元的頂點(diǎn)進(jìn)行坐標(biāo)變換和光照計(jì)算,生成可用于渲染到投影空間的頂點(diǎn)坐標(biāo)/顏色和紋理坐標(biāo)。
頂點(diǎn)渲染就是定義了一系列針對(duì) 頂點(diǎn)的渲染指令和渲染語句,當(dāng)Direct3D處理頂點(diǎn)時(shí),會(huì)自動(dòng)使用這些渲染指令和渲染語句對(duì)每一個(gè)頂點(diǎn)逐一進(jìn)行處理,完成頂點(diǎn)數(shù)據(jù)的處理工作。
5-Unity3D中的頂點(diǎn)Shader
Shader "Custom/Leichao886" {
Properties {
_Color ("Main Color", Color) = (1, 1, 1, 1)
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass{
// Dont write to the depth buffer
ZWrite off
// Set up alpha blending
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _Color;
struct v2f{
float4 pos:SV_POSITION;
float4 texcoord : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
// 獲得Unity全局變量(模型坐標(biāo)到世界坐標(biāo)的矩陣) * 拿到頂點(diǎn)
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
return o;
}
half4 frag(v2f i):COLOR0
{
half4 col = _Color * tex2D(_MainTex, i.texcoord.xy);
return col;
}
ENDCG
}
}
FallBack "Diffuse"
}