【小松教你手游开发】【unity实用技能】Unity图片变灰的方式
http://www.tuicool.com/articles/Vruuqme
NGUI中的Button幾乎是最常用到的控件之一,并且可以組合各種組件(比如UIButtonColor,UIButtonOffset,UITweenxx),方便設(shè)置Button的各種狀態(tài)下的屬性,幾乎可以滿足我們的所有需求。
但是對于當Button的isEnabled屬性設(shè)置為false時,根據(jù)設(shè)置的disableColor屬性設(shè)置不可點擊時的顏色時,雖然我們設(shè)置的灰色,但并不是我們想象中的樣子!
設(shè)置的是灰色,實際運行結(jié)果卻還是彩色的,只是暗了一點,并不能夠很好地表現(xiàn)出其“禁用”的狀態(tài)!
1.原理
Unity3D中所有的渲染都是基于Shader的,而Shader綁定在Material上,打開一個NGUI例子中自帶的Material,得到其使用Shader的文件
NGUI中大部分材質(zhì)都使用的Unlit/Transparent Colored(PS:雖然在Unlit下,但并不是Unity3d內(nèi)置的,而是NGUI擴展的)
找到其片段著色器,代碼如下:
fixed4 frag (v2f i) : COLOR { fixed4 col = tex2D(_MainTex, i.texcoord) * i.color; return col; } fixed4 frag (v2f i) : COLOR { fixed4 col = tex2D(_MainTex, i.texcoord) * i.color; return col; }這個片段著色器很簡單,只在“最簡單的著色器”上多加了一步,即將從定點著色器中傳出的頂點顏色屬性乘到了紋理采樣得到的像素上。
看到這個代碼,就很容易理解為什么是變暗,而不是變成灰色了
頂點的顏色數(shù)據(jù)是從UISprite之類的面板中傳遞進來的,其最大值是白色(255,255,255,255),而這里是正交化的,最大值白色對應(yīng)(1.0,1.0,1.0,1.0),這也是默認值,當采樣得到的像素值x1.0,相當于采樣得到的紋理值;如果設(shè)置一個其他的顏色,正交化后肯定會小于1.0,當采樣得到的像素值乘以這個值后,像素值會比之前小,而最小值是(0,0, 0,0)即黑色,也就是說如果設(shè)置一個不是白色的顏色,就會使像素值更接近于黑色,這就是變暗的原因!
2.置灰
NGUI只提供了這樣一種變暗的功能,用來表現(xiàn)其“禁用”的狀態(tài),但是這并不是最好的結(jié)果,如果需要介于黑白之間的灰色紋理,難道非要美術(shù)對每一個可能會被置灰的紋理重新制作一張紋理嗎?
這就更糟了!游戲中紋理是很占空間的,這樣做相當于將UI資源翻了一倍!
還是從Shader方面入手吧!
想象一下,如果在著色器處理之前,傳遞一個bool值,當這個bool值為true時,正常繪制紋理;當這個bool值為false時,繪制灰色紋理。
(Unity3d的Shader中并不支持傳遞bool值,這里只是舉個栗子)
這樣看似很合理,也確實可以實現(xiàn),但是會有一個問題,這個bool值肯定要在頂點著色器階段傳過去,而NGUI提供的“紋理打包”功能(即很多紋理合并成一個Atlas,即節(jié)省空間,還可以有一些其他信息,比如九宮格拉伸的參數(shù)。。。),當這個bool值為false時,這個Atlas中所有的繪制即全部變?yōu)榛疑?#xff0c;這是不符合邏輯的,當然可以每張小圖單獨處理,即相當于損失掉NGUI的“紋理打包”功能
3.解決方案
損失一個顏色值吧,作為“約定”!
選取一個顏色值,作為約定為置灰的標記,當片段著色器檢測到這個顏色值之后,執(zhí)行渲染灰色的shader!
這個顏色值可以任意選擇,我這里選取純黑色作為“約定顏色”,片段著色器代碼如下:
fixed4 frag (v2f i) : COLOR { fixed4 col; if (i.color.r < 0.001) { col = tex2D(_MainTex, i.texcoord); float grey = dot(col.rgb, float3(0.299, 0.587, 0.114)); col.rgb = float3(grey, grey, grey); } else { col = tex2D(_MainTex, i.texcoord) * i.color; } return col; } fixed4 frag (v2f i) : COLOR { fixed4 col; if (i.color.r < 0.001) { col = tex2D(_MainTex, i.texcoord); float grey = dot(col.rgb, float3(0.299, 0.587, 0.114)); col.rgb = float3(grey, grey, grey); } else { col = tex2D(_MainTex, i.texcoord) * i.color; } return col; }其中(0.299,0.587,0.114)為灰度公式的參數(shù)
我復(fù)制了一份NGUI例子的紋理和材質(zhì),將此Shader設(shè)置到材質(zhì)中,渲染效果如圖
(最上面兩個是原始狀態(tài)下的效果,中間兩個是NGUI提供的禁用狀態(tài)效果,最下面兩個分別是修改后Shader渲染同一個Atlas得到的結(jié)果)
這才是我想要的灰色!
轉(zhuǎn)載于:https://blog.51cto.com/13638120/2084960
總結(jié)
以上是生活随笔為你收集整理的【小松教你手游开发】【unity实用技能】Unity图片变灰的方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 直线特征提取算法:IEPF(iterat
- 下一篇: 基于python ttkbootstar