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扩展的)

找到其片段着色器,代码例如以下:

  1. fixed4 frag (v2f i) : COLOR
  2. {
  3. fixed4 col = tex2D(_MainTex, i.texcoord) * i.color;
  4. return col;
  5. }
fixed4 frag (v2f i) : COLOR
{
fixed4 col = tex2D(_MainTex, i.texcoord) * i.color;
return col;
}

这个片段着色器非常easy,仅仅在“最简单的着色器”上多加了一步,即将从定点着色器中传出的顶点颜色属性乘到了纹理採样得到的像素上。

看到这个代码。就非常easy理解为什么是变暗,而不是变成灰色了

顶点的颜色数据是从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!

这个颜色值能够随意选择。我这里选取纯黑色作为“约定颜色”,片段着色器代码例如以下:

  1. fixed4 frag (v2f i) : COLOR
  2. {
  3. fixed4 col;
  4. if (i.color.r < 0.001)
  5. {
  6. col = tex2D(_MainTex, i.texcoord);
  7. float grey = dot(col.rgb, float3(0.299, 0.587, 0.114));
  8. col.rgb = float3(grey, grey, grey);
  9. }
  10. else
  11. {
  12. col = tex2D(_MainTex, i.texcoord) * i.color;
  13. }
  14. return col;
  15. }
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得到的结果)

这才是我想要的灰色!

Unity图片变灰的方式的更多相关文章

  1. CSS使图片变灰

    为了悼念,各大网站都纷纷将自己的站点颜色调灰,就连图片也一样,到底如何实现的呢,请看下面的代码. 〈img src="http://hovertree.com/hvtimg/201512/f ...

  2. NGUI 图片变灰

    效果图 1.先准备好一个变灰shader.代码如下 Shader "Custom/Gray" { Properties { _MainTex ("Base (RGB), ...

  3. cocos2d-x图片变灰或者变亮

    //根据现有CCSprite,变亮和变灰 CCSprite* FlyLeaf::graylightWithCCSprite(CCSprite* oldSprite,bool isLight) {    ...

  4. c# winform 把彩色图片转换为灰色的图片,变灰,灰度图片,速度很快,safe,unsafe

    把彩色图片转换为灰色的图片,直接用.net接口遍历每个像素点转换的效率非常低,800K的图片65万像素我的电脑要用5分钟,而用了unsafe,速度提高了几千倍,同样的图片只用了0.几秒 附一个常用的遍 ...

  5. unity 图片变纯色填充

    unity自带shader 即可

  6. JAVA彩色图片变灰处理

    File file = new File("F:/firefox.png"); File destFile = new File("F:/pic/" + Sys ...

  7. 图片变灰css3

    -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); -o-filte ...

  8. css3图片变灰

    html{ filter:grayscale(100%); -webkit-filter:grayscale(100%); -moz-filter:grayscale(100%); -ms-filte ...

  9. CSS实现图片变灰色及透明度

    [图片变灰] 每当遇到哀悼日,很多网站快速变灰色,来看看实现方式吧: 方式一,仅支持ie) html{filter:progid:DXImageTransform.Microsoft.BasicIma ...

随机推荐

  1. Tornado异步模式

    先介绍下背景:由于工作需要,前段时间又写了一段爬虫去获取和更新一些数据.之前爬虫主要用Scrapy框架批量爬取一些页面数据,或者用Gevent调用目标站点的接口.偶然看到了Tornado,听说这个框架 ...

  2. iis 服务器而配置php运行环境

    第一步 下载php 下载压缩包就可以了 第二步 解压缩php到某个目录,比如D:\php php目录里面有两个php.ini,一个是php.ini-dist,比较适合开发用:一个是php.ini-re ...

  3. $stylus美化$

    一直在用洛谷 当然不一定是洛谷 其他的网站也可以用 比如说codeforces 还是决定要美化一波 首先去找一个插件 叫做 stylus stylus下载的很多 我不想过多说明. Google和QQ浏 ...

  4. JavaScript--什么是函数

    函数是完成某个特定功能的一组语句.如没有函数,完成任务可能需要五行.十行.甚至更多的代码.这时我们就可以把完成特定功能的代码块放到一个函数里,直接调用这个函数,就省重复输入大量代码的麻烦. 如何定义一 ...

  5. ACM_出题人这样不好吧

    出题人这样不好吧 Time Limit: 2000/1000ms (Java/Others) Problem Description: 作为编协的第一次月赛,肯定是要有防AK(ALL KILL)的题目 ...

  6. 关于jquery $.browser 报错问题

    在调用 jquery 插件时,出现$.browser 报错,原来是jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version 等属性, 取而代之的是 $.su ...

  7. 【技术累积】【点】【java】【30】代理模式

    基础 代理模式是Java常见的设计模式之一.所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象. 什么是代理 参考现实生活中的代理 比如某个品牌的某个省的代理商,作 ...

  8. MyBatis入门3_mapper.xml优化(parameterType简写_NameSpace简写_sql片段_特殊字符处理)_动态SQL

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 优化 1.起别名(一般不用,写全方便查看类出处) 以前 ...

  9. ImageMagick的下载和配置

    2. 新建一个VC++的工程,项目->属性 VC++目录中 包含目录中加入4项,ImageMagick安装路径下的include文件夹,和include里边的三个文件夹. 库目录中加入1项,Im ...

  10. MHA的MySQL高可用方案实战

    功能: 1)master的故障切换(keepalived VIP的飘移) 2)主从复制角色的提升和重新转向 其中master 对外提供写服务,备选master2(实际的slave提供读服务,slave ...