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. 微信小程序压缩图片并上传到服务器(拿去即用)

    这里注意一下,图片压缩后的宽度是画布宽度的一半 canvasToTempFilePath 创建画布的时候会有一定的时间延迟容易失败,这里加setTimeout来缓冲一下 这是单张图片压缩,多张的压缩暂 ...

  2. $CF1141A Game 23$

    这题很简单啊 可以用\(DFS\)来打 毕竟是 \(2^x*3^y=m 输出x+y啊\) 这是最简单的做法 #include <bits/stdc++.h> using namespace ...

  3. docker容器如何安装vim

    mv /etc/apt/sources.list /etc/apt/sources.list.bak && \     echo "deb http://mirrors.16 ...

  4. SharePoint通过IP地址访问

    问题:SP站点通过计算机名称可以访问,但不能通过IP地址访问 解决方案:打开SharePoint2010管理中心>应用程序管理>配置备用访问映射>编辑公用 URL 备用访问映射集:选 ...

  5. Unity相机平滑跟随

    简介 unity中经常会用到固定视角的相机跟随,然后百度发现大家都是自己写的,然后偶也写咯一个,分享一下 PS: 由于刚学C#不久,才发现delegate这个东东,也不知道对性能影响大不大,但是看MS ...

  6. Linq学习(四)-联合查询

    一.本将主要介绍 Union.Concat.Intersect.Except的使用操作 1.Union 查询昵称中带有Friend和带有Lee的用户 Linq (from a in Blog_User ...

  7. 跨平台键鼠共享软件synergy使用

    如果共享的机子都是win系统的话,也可以使用 无界鼠标. 这里主要讲跨平台通用的synergy.下载地址:http://synergy-project.org/ 注意1:最好下载同一位数,同一版本的. ...

  8. canvas杂记

    canvas杂记 canvas标签 <canvas width=600 height=400></canvas> //1. 拿到画布 var canvas = document ...

  9. html5——背景

    背景大小 background-size: % %;//宽 高 background-size: 100px 100px;//宽 高 background-size: cover;//覆盖,图片会完全 ...

  10. atom 插件安装【转载】

    http://www.cnblogs.com/20145221GQ/p/5334762.html 问题: 输入apm install后,可能一直没有响应,要强行退. 不知道安装的时候可不可以打开ato ...