【Unity Shaders】Transparency —— 使用alpha通道创建透明效果
本系列主要參考《Unity Shaders and Effects Cookbook》一書(感謝原書作者),同一時候會加上一點個人理解或拓展。
這里是本書全部的插圖。這里是本書所需的代碼和資源(當然你也能夠從官網下載)。
========================================== 切割線==========================================
寫在前面
從這篇開始是一個全新的章節:透明效果(Transparency)。之前在制作LOGO閃光效果的時候就一直調不出來背景透明。就是那個時候決定要學一下Shader的基礎知識,不求成為多么厲害的大神。僅僅望對渲染的內部原理有些許了解~
開始正文。
在我們學習怎樣編寫透明的Surface Shader的開始,我們須要理解應該包括哪些代碼使得我們能夠開啟透明效果。
Unity再一次大方地為我們提供了一些內置參數,我們能夠通過包括這些參數來高速得到透明效果。
這是通過在Shader的#pragma聲明中加入alpha參數來實現的。這句話告訴Unity我們想要在Shader中使用透明度。但當我們在創建透明Shaders時,須要細致考慮一些事情。那就是代碼中元素的繪制順序。這篇文章將會講述一些基本問題,來得到一個非常easy的透明物體。
在以下的章節中,將會解說其它有關透明度的問題。
準備工作
和曾經一樣,我們須要創建一個新的場景。
創建一個新的場景,加入一個平行光以及一個球體(Sphere)。
創建一個新的Shader和新的Material。能夠命名為SimpleAlpha。把Shader賦給Material后,再把該Material賦給第一步中的球體。最后,我們須要一張貼圖作為控制隱私,來控制哪些部分是透明的。哪些部分是不透明的。下圖是我們用到的貼圖。這張貼圖僅包括單純的RGB和白色(自帶資源中沒有。能夠自己畫,非常easy)。我們使用它的RGB通道作為一個取值為0或1的透明度值。
實現
這篇Shader非常easy。
在Properties塊中加入一個新的property,這使得我們能夠全局控制透明度。
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TransVal ("Transparency Value", Range(0,1)) = 0.5
}
改變渲染隊列:
Tags { "Queue"="Transparent" }
解釋:這一步非常重要,原書中沒有加入這一句實際是錯誤的。
然后,我們在#pragma聲明中加入一個新的參數:alpha參數。
CGPROGRAM #pragma surface surf Lambert alpha
解釋:再解釋一遍上面這句聲明的意思。使用名為surf的Surface Function,使用內置的Lambert光照函數。開啟透明通道。
最后,在surf()函數中加入控制透明度的代碼。
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"
}
假設沒有透明效果。例如以下所看到的:
最后效果例如以下(從左到右分別相應了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依賴三個元素:正確設置Shader渲染隊列,#pragma聲明中的alpha參數,以及在SurfaceOutput結構體中的Alpha值。
Tags{"Queue"="Transparent"}一步將決定半透明物體和不透明物體之間正確的渲染關系,假設沒有正確設置,那么非常有可能就會出現后面的物體跑到了透明物體的前面。詳細解釋能夠參見這篇文章。
一旦我們在#pragma聲明中加入了alpha參數。這就告訴了Unity:嘿,接下來你要同意我渲染一個透明的surface。然后,我們就僅僅須要逐像素地使用一個取值范圍為0到1的值來填充SurfaceOutput結構體中的O.Alpha值。
從顏色角度講(這里的顏色指一個灰度值,由于透明度能夠用一個單通道的灰度值來表示),一個為1的透明度,即白色,將會產出一個全然不透明的效果。而0值,即黑色,表示一個全然透明的效果。
這就解釋了上述的效果。
比如,當我們使用例如以下語句控制透明度:
o.Alpha = c.r * _TransVal
則貼圖中除了紅色部分以及白色部分(白色的RGB通道值均為1)其R通道的值為1。其余(綠色和藍色部分)均為0。因此僅僅有紅色和白色的部分才不透明。
雖然關于透明度有非常多東西,但我們要知道,上述是其最主要的實現。
在以下的章節中,我們將開始怎樣在實時渲染中使用alpha通道或者半透明的Shader。
總結
以上是生活随笔為你收集整理的【Unity Shaders】Transparency —— 使用alpha通道创建透明效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转-SQL 2005修改系统表
- 下一篇: http切换到https