【Unity Shaders】Transparency —— 使用alpha通道创建透明效果
本系列主要參考《Unity Shaders and Effects Cookbook》一書(shū)(感謝原書(shū)作者),同一時(shí)候會(huì)加上一點(diǎn)個(gè)人理解或拓展。
這里是本書(shū)全部的插圖。這里是本書(shū)所需的代碼和資源(當(dāng)然你也能夠從官網(wǎng)下載)。
========================================== 切割線==========================================
寫(xiě)在前面
從這篇開(kāi)始是一個(gè)全新的章節(jié):透明效果(Transparency)。之前在制作LOGO閃光效果的時(shí)候就一直調(diào)不出來(lái)背景透明。就是那個(gè)時(shí)候決定要學(xué)一下Shader的基礎(chǔ)知識(shí),不求成為多么厲害的大神。僅僅望對(duì)渲染的內(nèi)部原理有些許了解~
開(kāi)始正文。
在我們學(xué)習(xí)怎樣編寫(xiě)透明的Surface Shader的開(kāi)始,我們須要理解應(yīng)該包括哪些代碼使得我們能夠開(kāi)啟透明效果。
Unity再一次大方地為我們提供了一些內(nèi)置參數(shù),我們能夠通過(guò)包括這些參數(shù)來(lái)高速得到透明效果。
這是通過(guò)在Shader的#pragma聲明中加入alpha參數(shù)來(lái)實(shí)現(xiàn)的。這句話告訴Unity我們想要在Shader中使用透明度。但當(dāng)我們?cè)趧?chuàng)建透明Shaders時(shí),須要細(xì)致考慮一些事情。那就是代碼中元素的繪制順序。這篇文章將會(huì)講述一些基本問(wèn)題,來(lái)得到一個(gè)非常easy的透明物體。
在以下的章節(jié)中,將會(huì)解說(shuō)其它有關(guān)透明度的問(wèn)題。
準(zhǔn)備工作
和曾經(jīng)一樣,我們須要?jiǎng)?chuàng)建一個(gè)新的場(chǎng)景。
創(chuàng)建一個(gè)新的場(chǎng)景,加入一個(gè)平行光以及一個(gè)球體(Sphere)。
創(chuàng)建一個(gè)新的Shader和新的Material。能夠命名為SimpleAlpha。把Shader賦給Material后,再把該Material賦給第一步中的球體。最后,我們須要一張貼圖作為控制隱私,來(lái)控制哪些部分是透明的。哪些部分是不透明的。下圖是我們用到的貼圖。這張貼圖僅包括單純的RGB和白色(自帶資源中沒(méi)有。能夠自己畫(huà),非常easy)。我們使用它的RGB通道作為一個(gè)取值為0或1的透明度值。
實(shí)現(xiàn)
這篇Shader非常easy。
在Properties塊中加入一個(gè)新的property,這使得我們能夠全局控制透明度。
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TransVal ("Transparency Value", Range(0,1)) = 0.5
}
改變渲染隊(duì)列:
Tags { "Queue"="Transparent" }
解釋:這一步非常重要,原書(shū)中沒(méi)有加入這一句實(shí)際是錯(cuò)誤的。
然后,我們?cè)?pragma聲明中加入一個(gè)新的參數(shù):alpha參數(shù)。
CGPROGRAM #pragma surface surf Lambert alpha
解釋:再解釋一遍上面這句聲明的意思。使用名為surf的Surface Function,使用內(nèi)置的Lambert光照函數(shù)。開(kāi)啟透明通道。
最后,在surf()函數(shù)中加入控制透明度的代碼。
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.b * _TransVal;
}
完整代碼例如以下:
Shader "Custom/SimpleAlpha" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TransVal ("Transparency Value", Range(0,1)) = 0.5
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Transparent"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert alpha
sampler2D _MainTex;
float _TransVal;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.b * _TransVal;
}
ENDCG
}
FallBack "Diffuse"
}
假設(shè)沒(méi)有透明效果。例如以下所看到的:
最后效果例如以下(從左到右分別相應(yīng)了o.Alpha = c.r * _TransVal, o.Alpha = c.g * _TransVal,o.Alpha = c.b * _TransVal):<img src="http://img.blog.csdn.net/20140605155109187?
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FuZHljYXQxOTky/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
解釋
你能夠看到。使用Unity的Surface Shaders得到透明效果是非常easy的。
這類Shader依賴三個(gè)元素:正確設(shè)置Shader渲染隊(duì)列,#pragma聲明中的alpha參數(shù),以及在SurfaceOutput結(jié)構(gòu)體中的Alpha值。
Tags{"Queue"="Transparent"}一步將決定半透明物體和不透明物體之間正確的渲染關(guān)系,假設(shè)沒(méi)有正確設(shè)置,那么非常有可能就會(huì)出現(xiàn)后面的物體跑到了透明物體的前面。詳細(xì)解釋能夠參見(jiàn)這篇文章。
一旦我們?cè)?pragma聲明中加入了alpha參數(shù)。這就告訴了Unity:嘿,接下來(lái)你要同意我渲染一個(gè)透明的surface。然后,我們就僅僅須要逐像素地使用一個(gè)取值范圍為0到1的值來(lái)填充SurfaceOutput結(jié)構(gòu)體中的O.Alpha值。
從顏色角度講(這里的顏色指一個(gè)灰度值,由于透明度能夠用一個(gè)單通道的灰度值來(lái)表示),一個(gè)為1的透明度,即白色,將會(huì)產(chǎn)出一個(gè)全然不透明的效果。而0值,即黑色,表示一個(gè)全然透明的效果。
這就解釋了上述的效果。
比如,當(dāng)我們使用例如以下語(yǔ)句控制透明度:
o.Alpha = c.r * _TransVal
則貼圖中除了紅色部分以及白色部分(白色的RGB通道值均為1)其R通道的值為1。其余(綠色和藍(lán)色部分)均為0。因此僅僅有紅色和白色的部分才不透明。
雖然關(guān)于透明度有非常多東西,但我們要知道,上述是其最主要的實(shí)現(xiàn)。
在以下的章節(jié)中,我們將開(kāi)始怎樣在實(shí)時(shí)渲染中使用alpha通道或者半透明的Shader。
總結(jié)
以上是生活随笔為你收集整理的【Unity Shaders】Transparency —— 使用alpha通道创建透明效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 转-SQL 2005修改系统表
- 下一篇: http切换到https