Shader三大著色器
固定功能管線著色器:Fixed Function Shaders
固定功能管線著色器的關(guān)鍵代碼一般都在Pass的材質(zhì)設(shè)置Material{}和紋理設(shè)置SetTexture{}部分。
表面著色器Surface Shaders
在Unity中,表面著色器的關(guān)鍵代碼用Cg/HLSL語(yǔ)言編寫(xiě),然后嵌在ShaderLab的結(jié)構(gòu)代碼中使用。使用表面著色器,用戶僅需要編寫(xiě)最關(guān)鍵的表面函數(shù),其余周邊代碼將由Unity自動(dòng)生成,包括適配各種光源類(lèi)型、渲染實(shí)時(shí)陰影以及集成到前向/延遲渲染管線中等。
編寫(xiě)表面著色器有幾個(gè)規(guī)則:
1)表面著色器的實(shí)現(xiàn)代碼需要放在CGPROGRAM..ENDCG代碼塊中,而不是Pass結(jié)構(gòu)中,它會(huì)自己編譯到各個(gè)Pass。
2)使用#pragma surface..命令來(lái)指明它是一個(gè)表面著色器。
#pragma surface 表面函數(shù)光照模型[可選參數(shù)]
其中表面函數(shù)用來(lái)說(shuō)明哪個(gè)Cg函數(shù)包含有表面著色器代碼,表面函數(shù)的形式為:
void surf(Input IN,inoutSurfaceOutPut 0)
光照模型可以是內(nèi)置的Lambert和BlinnPhong,或者是自定義的光照模型。
表面函數(shù)的作用是接收輸入的UV或者附加數(shù)據(jù),然后進(jìn)行處理,最后將結(jié)構(gòu)填充到輸出結(jié)構(gòu)體SurfaceOutPut中。
輸入結(jié)構(gòu)體Input一般包含著色器所需的紋理坐標(biāo),紋理坐標(biāo)的命名規(guī)則為uv加紋理名稱(chēng)。另外還可以在輸入結(jié)構(gòu)中設(shè)置一些附加數(shù)據(jù):

SurfaceOut描述了表面的各種參數(shù),它的標(biāo)準(zhǔn)結(jié)構(gòu)為:
將輸入數(shù)據(jù)處理完畢后,將結(jié)果填充到輸出結(jié)構(gòu)體中。
相關(guān)示例:
1、使用內(nèi)置的Lambert光照模型,并設(shè)置表面顏色為白色。
渲染效果如下:

2、在示例1的基礎(chǔ)上添加紋理,代碼如下:
渲染效果如下:

3、在示例2的基礎(chǔ)上添加法線貼圖
渲染效果如下:

4、添加立方體貼圖反射
渲染效果如下:

頂點(diǎn)片段著色器Vertex And Fragment Shaders
頂點(diǎn)片段著色器運(yùn)行于具有可編程渲染管線的硬件上,它包括頂點(diǎn)程序Vertex Programs和片段程序Fragment Programs。當(dāng)在使用頂點(diǎn)程序或片段程序進(jìn)行渲染的時(shí)候,圖形硬件的固定功能管線會(huì)關(guān)閉,具體來(lái)說(shuō)就是編寫(xiě)的頂點(diǎn)程序會(huì)替換掉固定管線中標(biāo)準(zhǔn)的3D變換,光照,紋理坐標(biāo)生成等功能,而片段程序會(huì)替換掉SetTexture命令中的紋理混合模式。因此編寫(xiě)頂點(diǎn)片段著色器需要對(duì)3D變化,光照計(jì)算等有非常透徹的了解,需要寫(xiě)代碼來(lái)替代D3D或者OpenGL原先在固定功能管線中要做的工作。
與表面著色器一樣,頂點(diǎn)片段著色器也需要用Cg/HLSL來(lái)編寫(xiě)核心的實(shí)現(xiàn)代碼,代碼用CGPROGRAM ENDCG語(yǔ)句包圍起來(lái),放在ShaderLab的Pass命令中,形式如下:
頂點(diǎn)著色程序從GPU前端模塊(寄存器)中提取圖元信息(頂點(diǎn)位置、法向量、紋理坐標(biāo)等),并完成頂點(diǎn)坐標(biāo)空間轉(zhuǎn)換、法向量空間轉(zhuǎn)換、光照計(jì)算等操作,最后將計(jì)算好的數(shù)據(jù)傳送到指定寄存器中;然后片斷著色程序從中獲取需要的數(shù)據(jù),通常為“紋理坐標(biāo)、光照信息等”,并根據(jù)這些信息以及從應(yīng)用程序傳遞的紋理信息(如果有的話)進(jìn)行每個(gè)片斷的顏色計(jì)算,最后將處理后的數(shù)據(jù)送光柵操作模塊。
頂點(diǎn)著色器和像素著色器的數(shù)據(jù)處理流程

在應(yīng)用程序中設(shè)定的圖元信息(頂點(diǎn)位置坐標(biāo)、顏色、紋理坐標(biāo)等)傳遞到vertex buffer中;紋理信息傳遞到texture buffer中。其中虛線表示目前還沒(méi)有實(shí)現(xiàn)的數(shù)據(jù)傳遞。當(dāng)前的頂點(diǎn)程序還不能處理紋理信息,紋理信息只能在片斷程序中讀入。
頂點(diǎn)著色程序與片斷著色程序通常是同時(shí)存在,相互配合,前者的輸出作為后者的輸入。不過(guò),也可以只有頂點(diǎn)著色程序。如果只有頂點(diǎn)著色程序,那么只對(duì)輸入的頂點(diǎn)進(jìn)行操作,而頂點(diǎn)內(nèi)部的點(diǎn)則按照硬件默認(rèn)的方式自動(dòng)插值。例如,輸入一個(gè)三角面片,頂點(diǎn)著色程序?qū)ζ溥M(jìn)行phong光照計(jì)算,只計(jì)算三個(gè)頂點(diǎn)的光照顏色,而三角面片內(nèi)部點(diǎn)的顏色按照硬件默認(rèn)的算法(Gourand明暗處理或者快速phong明暗處理)進(jìn)行插值,如果圖形硬件比較先進(jìn),默認(rèn)的處理算法較好(快速phong明暗處理),則效果也會(huì)較好;如果圖形硬件使用Gourand明暗處理算法,則會(huì)出現(xiàn)馬赫帶效應(yīng)(條帶化)。
而片斷著色程序是對(duì)每個(gè)片斷進(jìn)行獨(dú)立的顏色計(jì)算,并且算法由自己編寫(xiě),不但可控性好,而且可以達(dá)到更好的效果。
由于GPU對(duì)數(shù)據(jù)進(jìn)行并行處理,所以每個(gè)數(shù)據(jù)都會(huì)執(zhí)行一次shader程序程序。即,每個(gè)頂點(diǎn)數(shù)據(jù)都會(huì)執(zhí)行一次頂點(diǎn)程序;每個(gè)片段都會(huì)執(zhí)行一次片段程序。
片段就是所有三維頂點(diǎn)在光柵化之后的數(shù)據(jù)集合,這些數(shù)據(jù)沒(méi)有經(jīng)過(guò)深度值比較,而屏幕顯示的像素是經(jīng)過(guò)深度比較的。
頂點(diǎn)片段著色器中編譯命令的一些說(shuō)明:


下面是一些頂點(diǎn)片段著色器的例子:
1)根據(jù)法線方向設(shè)置模型表面顏色

2)根據(jù)切線方向設(shè)置模型表面顏色。

出處:https://www.cnblogs.com/tgycoder/p/4785553.html