Unity-ShaderLab:舊版紋理組合器
在計(jì)算基本頂點(diǎn)光照之后將應(yīng)用紋理。在 ShaderLab 中使用?SetTexture?命令來完成此操作。
注意:使用片元程序時(shí),SetTexture 命令無效;因?yàn)樵谶@種情況下,像素運(yùn)算在著色器中完整描述。建議現(xiàn)在使用可編程著色器,而不是 SetTexture 命令。
可在固定函數(shù)紋理中實(shí)現(xiàn)舊式組合器效果。您可以在一個(gè)通道中包含多個(gè) SetTexture 命令;所有紋理都按順序應(yīng)用,就像繪畫程序中的圖層一樣。SetTexture 命令必須放在?Pass?的末尾。
語法
分配紋理。TextureName?必須定義為紋理屬性。在?TextureBlock?中定義如何應(yīng)用紋理。
紋理代碼塊控制著應(yīng)用紋理的方式。在紋理代碼塊內(nèi)部,最多可以有兩條命令:combine
?和?constantColor
。
紋理代碼塊?combine
?命令
combine
?src1?* _src2_:將 src1 和 src2 相乘。結(jié)果將比任一個(gè)輸入更暗。
combine
?src1?+ _src2_:將 src1 與 src2 相加。結(jié)果將比任一個(gè)輸入更亮。
combine
?src1?- _src2_:從 src1 減去 src2。
combine
?src1?lerp
?(src2) _src3_:使用 src2 的 Alpha 在 src3 和 src1 之間插值。請(qǐng)注意,插值方向是相反的:當(dāng) Alpha 為 1 時(shí)使用 src1,而當(dāng) Alpha 為 0 時(shí)使用 src3。
combine
?src1?*?src2?+ _src3_:將 src1 與 src2 的 Alpha 分量相乘,然后加 src3。
所有?src?屬性均可為?previous、constant、primary?或?texture?之一。
Previous?表示上一個(gè) SetTexture 的結(jié)果。
Primary?表示光照計(jì)算產(chǎn)生的顏色或者是頂點(diǎn)顏色(如果已綁定)。
Texture?表示由 SetTexture 中?TextureName?指定的紋理的顏色(請(qǐng)參閱上文)。
Constant?表示?ConstantColor?中指定的顏色。
修飾符:
上面指定的公式可以選擇性地跟隨關(guān)鍵字?Double?或?Quad,作用是讓生成的顏色在亮度上乘以 2 或乘以 4。
除了?
lerp
?參數(shù)之外,所有?src?屬性都可以選擇以?one -?開頭,作用是對(duì)生成的顏色取非。所有?src?屬性都可以后跟?alpha,作用是僅采用 Alpha 通道。
紋理代碼塊?constantColor
?命令
ConstantColor color:定義可在 combine 命令中使用的恒定顏色。
Unity 5.0 中刪除的功能
Unity 5.0 之前的版本支持紋理坐標(biāo)變換(通過在紋理代碼塊內(nèi)部使用?matrix
?命令)。如果現(xiàn)在需要此功能,可考慮將著色器重寫為可編程著色器,并在頂點(diǎn)著色器中進(jìn)行 UV 變換。
同樣,5.0 版本中刪除了有符號(hào)的加法 (a+-b
)、乘以有符號(hào)的加法 (a*b+-c
)、先乘后減 (a*b-c
) 和點(diǎn)積(dot3
?或?dot3rgba
)紋理組合模式。如果需要它們,請(qǐng)?jiān)谙袼刂髦羞M(jìn)行數(shù)學(xué)運(yùn)算。
詳細(xì)信息
在片元程序問世之前,較舊的顯卡使用分層的紋理方法。這種方法逐一應(yīng)用紋理,從而修改將寫入屏幕的顏色。對(duì)于每個(gè)紋理,紋理通常與上一個(gè)運(yùn)算的結(jié)果組合。而現(xiàn)在建議使用實(shí)際片元程序。

請(qǐng)注意,每個(gè)紋理階段可能會(huì)也可能不會(huì)被限制為 0 至 1 的范圍,具體取決于平臺(tái)。如果 SetTexture 階段可能生成大于 1.0 的值,這可能會(huì)影響這些階段。
單獨(dú)計(jì)算 Alpha 和顏色
默認(rèn)情況下,組合器公式用于計(jì)算顏色的 RGB 和 Alpha 分量。您也可以選擇指定單獨(dú)的公式進(jìn)行 Alpha 計(jì)算。如下所示:
SetTexture [_MainTex] { combine previous * texture, previous + texture }
在這個(gè)公式中,我們將 RGB 顏色相乘并與 Alpha 相加。
鏡面高光
默認(rèn)情況下,primary?顏色是漫射顏色、環(huán)境顏色和鏡面反射顏色的總和(在光照計(jì)算中定義)。如果在通道選項(xiàng)中指定?SeparateSpecular On,則鏡面反射顏色將在組合器計(jì)算_之后_相加,而不是在之前相加。這是內(nèi)置 VertexLit 著色器的默認(rèn)行為。
圖形硬件支持
支持片元著色器的現(xiàn)代顯卡(桌面端的“著色器模型 2.0”,移動(dòng)設(shè)備端的 OpenGL ES 2.0)支持所有?SetTexture?模式和至少 4 個(gè)紋理階段(其中許多支持 8 個(gè))。如果使用非常舊的硬件(對(duì)于 PC 是指 2003 年之前制造的硬件,對(duì)于移動(dòng)設(shè)備是指早于 iPhone3GS 的硬件),最少可能只有兩個(gè)紋理階段。著色器作者應(yīng)為他們想要支持的顯卡單獨(dú)編寫子著色器。
示例
對(duì)兩個(gè)紋理進(jìn)行 Alpha 混合
這個(gè)簡(jiǎn)短示例需要兩個(gè)紋理。首先它將第一個(gè)組合器設(shè)置為只接受?_MainTex,然后使用?_BlendTex?的 Alpha 通道淡入?_BlendTex?的 RGB 顏色
Alpha 控制的自發(fā)光
此著色器使用?_MainTex?的 Alpha 分量來決定應(yīng)用光照的位置。它通過將紋理應(yīng)用于兩個(gè)階段來實(shí)現(xiàn)這一點(diǎn);在第一階段,紋理的 Alpha 值用于在頂點(diǎn)顏色和純白色之間進(jìn)行混合。在第二階段,與紋理的 RGB 值相乘。
不過,我們可以在這里任意執(zhí)行其他某些操作;不必混合為純白色,我們可以添加自發(fā)光顏色并混合到該顏色。注意使用?ConstantColor?從屬性中獲取 _SolidColor 到紋理混合中。
最后,我們獲取 VertexLit 著色器的所有光照屬性并將其拉入: