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图片变灰的方式相关推荐

  1. mtk 帧同步_【小松教你手游开发】【面试必读(编程基础)】网络游戏同步方式(帧同步和状态同步)...

    在做网络游戏的时候首先要做的是选择一种同步方式来使用,网上的文章都是说帧同步与状态同步的选择,但是又经常讲的模糊不清,我大概整理了一下,并且有一种我们现在项目用的网络同步方式 状态同步 状态同步就有好 ...

  2. 【小松教你手游开发】【unity实用技能】InvalidOperationException: ou

    InvalidOperationException: out of sync 在unity开发中出现这个bug. 在网上查了下是在迭代器中直接修改引起的.c#是不允许你在迭代器中直接修改. 改了一下确 ...

  3. 【小松教你手游开发】【unity实用技能】网游同步技术

    http://www.skywind.me/blog/archives/1343 转自http://www.skywind.me/blog/archives/1343 实时动作游戏在近年来得到迅猛的发 ...

  4. 【小松教你手游开发】【unity实用技能】unity游戏移植到WindowsPhone8平台上的一些...

    最近在移植u3d的游戏到WindowsPhone8上,WindowsPhone有多蛋疼就不说,移植的过程中还各种问题,稍稍总结一下 1.WindowsPhone账号在电脑上注册不要在手机上.手机上我就 ...

  5. 【小松教你手游开发】【unity实用技能】计算目标物体是否在自己的扇形视野范围...

    在做游戏开发中经常会需要到计算扇形的视野或者是受击范围的时候. 其实这个分为两部分, 第一部分是在扇形距离范围内(也就是不考虑角度,其实是圆形范围内) 第二部分是扇形角度范围内 第一部分很简单,Vec ...

  6. 【小松教你手游开发】【unity实用技能】给每个GameObject的打开关闭加上一个渐变...

    在游戏开发中,经常会因为直接将GameObject,setActive的方式打开关闭,这种方式效果太过生硬而给它加上一个Tween 可能是AlphaTween或者ScaleTween. 再加上一个Pl ...

  7. 【小松教你手游开发】【unity实用技能】u3d 层次问题总结

    首先的首先,NGUI区分前后层次关系是用Depth值.已经跟z轴值无关 首先因为我自己用的是NGUI,所以我的u3d层次问题也就是NGUI的层次问题 先确定UI渲染顺序,Camera>UIPan ...

  8. 【小松教你手游开发】【unity系统模块开发】Unity5.5.2UI打包AssetBundle

    之前已经有几篇文章写打包AssetBundle,但毕竟没有实际在项目中写过都写的比较浅. 刚好最近项目更新Unity5.5.2就顺便由我来更新ui打包流程 这里就把这次的经验写一下 这里还是稍微解释一 ...

  9. 【小松教你手游开发】【面试必读(编程基础)】堆和栈的区别(转过无数次的文章)...

    一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其 操作方式类似于数据结构中的栈 ...

最新文章

  1. TestNG如何disable一些case
  2. SAP云解决方案和企业本地部署(On-Premise)混合架构下的安全认证权限管理
  3. java 原子long_java中long和double类型操作的非原子性探究
  4. 华中数控系统与高创驱动器EtherCat通讯设置及控制参数
  5. HOG特征提取(一)
  6. C++程序设计课程设计报告
  7. Cesium设置三维球的视角和位置(中心点)
  8. 错误: 找不到或无法加载主类的解决办法
  9. 解决windows自带远程桌面无法打开某些软件(模拟器等)
  10. java indexeddb_HTML5之IndexedDB使用详解
  11. WIFI基本知识整理
  12. XOR Specia-LIS-t
  13. 玩家退坑,市场退热,盲盒经济还能坚挺多久?
  14. 使用FLuke福禄克MicroScanner2 POE(MS-POE)检测以太网供电
  15. Android 12小时制/24小时制获取方式及转换
  16. 系统架构师论文-论计算机网络的安全性设计(证券网络交易系统)
  17. ERP与PLM之间的关系
  18. plt.rcParams参数设置
  19. Unity发布小游戏(二):申请云服务
  20. 使用stata完成毕业实证论文的基础操作(上)

热门文章

  1. 考研计算机专业复试英语问答,考研复试:英语口语常问的16个问题 附回答模板...
  2. 关于考试管理系统的实现
  3. 为什么计算机处理打不开,为什么电脑ps安装成功打不开怎么办
  4. 文件第一列(或某一列)作为索引 -- Pandas
  5. 数一独有:多元函数积分学中的基本公式及其应用
  6. 第六篇:走近ConcurrentHashMap(基于JDK1.8)
  7. 【011】17GRE-自动根据艾宾浩斯曲线铺排学习计划
  8. 优学院思想道德修养与法律基础试题及答案
  9. python的认识PPT
  10. 合江长江公路大桥飞燕式系杆拱桥首节主拱成功吊装