了解Unity Shader
# Shader編程語言
Shader是一段代碼,運(yùn)行在GPU的程序,目前主流的有三種語言:基于OpenGL的OpenGL Shading Language,簡稱GLSL?;贒irectX的High Level Shading Language,簡稱HLSL。還有NVIDIA公司的C for Graphic,簡稱Cg語言。
GLSL與HLSL分別是基于OpenGL和Direct3D的接口,兩者不能混用。
由于GLSL爭斗良久,所以需要研發(fā)一種新的語言,那么Cg也就應(yīng)運(yùn)而生了,它與OpenGL、Direct3D不是同一層次的語言,而是他們的上層。
Cg是真正的跨平臺,可根據(jù)不同的平臺編譯成相應(yīng)的語言,由NVIDIA公司和微軟公司相互協(xié)作開發(fā),在語法上達(dá)到了一致,也導(dǎo)致了Cg與HLSL的語法極其相似。下面我們在介紹時一般會這樣寫Cg/HLSL。
# Unity Shader
Shader編程語言有GLSL、HLSL、Cg等
在Unity中我們只需要編寫一份Shader程序,Unity最終會根據(jù)不同的平臺來編繹成不同的著色器語言。
官方的建議是用Cg/HLSL來編寫,當(dāng)然也可以使用GLSL,主要是因為Cg/HLSL有更好的跨平臺性,更傾向于使用Cg/HLSL來編寫Shader程序。
Unity Shader嚴(yán)格來說并不是傳統(tǒng)上的Shader,而是Unity自身封裝后的一種便于書寫的Shader,又稱為ShaderLab。
# 圖形管線
在編寫Shader程序前,我們先來看看渲染管線。
我們通過計算機(jī)看到的一張圖片,是計算機(jī)需要從一系列的頂點數(shù)據(jù)、紋理等信息出發(fā),把這些信息最終轉(zhuǎn)換成一張人眼可以看到的圖像。
那么這張圖像是否可以編程,修改它的最終展示呢?答案是肯定的,我們可以通過Shader編程最終修改圖像的顯示。
如何通過Shader編程來實現(xiàn)?要先了解渲染流程,了解在渲染流程那部分我們是可編程控制的。
渲染流程分成3個階段:應(yīng)用階段(Application Stage)、幾何階段(Geometry Stage)、光柵化階段(Rasterizer Stage)。
應(yīng)用階段(Application Stage)主要由CPU來完成,幾何階段(Geometry Stage)、光柵化階段(Rasterizer Stage)由GPU來完成,我們主要講后面兩個階段。

在整個渲染流程中,有兩部分是我們可以編程控制的,那便是頂點著色器、片元著色器。
## 頂點著色器
頂點著色器(Vertex Shader)是完全可編程的,它通常用于實現(xiàn)頂點的空間變換、頂點著色等功能。而像素的其他部分由線性插值的方式來實現(xiàn)。
頂點著色器(Vertex Shader)是流水線的第一個階段,它的輸入來自于CPU。頂點著色器的處理單位是頂點,也就是說,輸入進(jìn)來的每個頂點都會調(diào)用一次頂點著色器。頂點著色器本身不可以創(chuàng)建或者銷毀任何頂點,而且無法得到頂點與頂點之間的關(guān)系。例如,我們無法得知兩個頂點是否屬于同一個三角網(wǎng)格。但正是因為這樣的相互獨立性,GPU可以利用本身的特性并行化處理每一個頂點,這意味著這一階段的處理速度會很快。頂點著色器需要完成的工作主要有:坐標(biāo)變換和逐頂點光照。
## 片元著色器
片元著色器(Fragment Shader),則是完全可編程的,它用于實現(xiàn)逐片元(Per-Fragment)的著色操作。這個更像是對每一個像素點進(jìn)行操作,所以對比頂點著色器更加消耗性能。