日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【小松教你手游开发】【unity实用技能】Unity图片变灰的方式

發布時間:2023/12/31 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【小松教你手游开发】【unity实用技能】Unity图片变灰的方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.tuicool.com/articles/Vruuqme

NGUI中的Button幾乎是最常用到的控件之一,并且可以組合各種組件(比如UIButtonColor,UIButtonOffset,UITweenxx),方便設置Button的各種狀態下的屬性,幾乎可以滿足我們的所有需求。

但是對于當Button的isEnabled屬性設置為false時,根據設置的disableColor屬性設置不可點擊時的顏色時,雖然我們設置的灰色,但并不是我們想象中的樣子!

設置的是灰色,實際運行結果卻還是彩色的,只是暗了一點,并不能夠很好地表現出其“禁用”的狀態!

1.原理

Unity3D中所有的渲染都是基于Shader的,而Shader綁定在Material上,打開一個NGUI例子中自帶的Material,得到其使用Shader的文件

NGUI中大部分材質都使用的Unlit/Transparent Colored(PS:雖然在Unlit下,但并不是Unity3d內置的,而是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; }

這個片段著色器很簡單,只在“最簡單的著色器”上多加了一步,即將從定點著色器中傳出的頂點顏色屬性乘到了紋理采樣得到的像素上。

看到這個代碼,就很容易理解為什么是變暗,而不是變成灰色了

頂點的顏色數據是從UISprite之類的面板中傳遞進來的,其最大值是白色(255,255,255,255),而這里是正交化的,最大值白色對應(1.0,1.0,1.0,1.0),這也是默認值,當采樣得到的像素值x1.0,相當于采樣得到的紋理值;如果設置一個其他的顏色,正交化后肯定會小于1.0,當采樣得到的像素值乘以這個值后,像素值會比之前小,而最小值是(0,0, 0,0)即黑色,也就是說如果設置一個不是白色的顏色,就會使像素值更接近于黑色,這就是變暗的原因!

2.置灰

NGUI只提供了這樣一種變暗的功能,用來表現其“禁用”的狀態,但是這并不是最好的結果,如果需要介于黑白之間的灰色紋理,難道非要美術對每一個可能會被置灰的紋理重新制作一張紋理嗎?

這就更糟了!游戲中紋理是很占空間的,這樣做相當于將UI資源翻了一倍!

還是從Shader方面入手吧!

想象一下,如果在著色器處理之前,傳遞一個bool值,當這個bool值為true時,正常繪制紋理;當這個bool值為false時,繪制灰色紋理。

(Unity3d的Shader中并不支持傳遞bool值,這里只是舉個栗子)

這樣看似很合理,也確實可以實現,但是會有一個問題,這個bool值肯定要在頂點著色器階段傳過去,而NGUI提供的“紋理打包”功能(即很多紋理合并成一個Atlas,即節省空間,還可以有一些其他信息,比如九宮格拉伸的參數。。。),當這個bool值為false時,這個Atlas中所有的繪制即全部變為灰色,這是不符合邏輯的,當然可以每張小圖單獨處理,即相當于損失掉NGUI的“紋理打包”功能

3.解決方案

損失一個顏色值吧,作為“約定”!

選取一個顏色值,作為約定為置灰的標記,當片段著色器檢測到這個顏色值之后,執行渲染灰色的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)為灰度公式的參數

我復制了一份NGUI例子的紋理和材質,將此Shader設置到材質中,渲染效果如圖

(最上面兩個是原始狀態下的效果,中間兩個是NGUI提供的禁用狀態效果,最下面兩個分別是修改后Shader渲染同一個Atlas得到的結果)

這才是我想要的灰色!

轉載于:https://blog.51cto.com/13638120/2084960

總結

以上是生活随笔為你收集整理的【小松教你手游开发】【unity实用技能】Unity图片变灰的方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。