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;
}
这个片段着色器非常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!
这个颜色值能够随意选择。我这里选取纯黑色作为“约定颜色”,片段着色器代码例如以下:
- 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得到的结果)
这才是我想要的灰色!
Unity图片变灰的方式的更多相关文章
- CSS使图片变灰
为了悼念,各大网站都纷纷将自己的站点颜色调灰,就连图片也一样,到底如何实现的呢,请看下面的代码. 〈img src="http://hovertree.com/hvtimg/201512/f ...
- NGUI 图片变灰
效果图 1.先准备好一个变灰shader.代码如下 Shader "Custom/Gray" { Properties { _MainTex ("Base (RGB), ...
- cocos2d-x图片变灰或者变亮
//根据现有CCSprite,变亮和变灰 CCSprite* FlyLeaf::graylightWithCCSprite(CCSprite* oldSprite,bool isLight) { ...
- c# winform 把彩色图片转换为灰色的图片,变灰,灰度图片,速度很快,safe,unsafe
把彩色图片转换为灰色的图片,直接用.net接口遍历每个像素点转换的效率非常低,800K的图片65万像素我的电脑要用5分钟,而用了unsafe,速度提高了几千倍,同样的图片只用了0.几秒 附一个常用的遍 ...
- unity 图片变纯色填充
unity自带shader 即可
- JAVA彩色图片变灰处理
File file = new File("F:/firefox.png"); File destFile = new File("F:/pic/" + Sys ...
- 图片变灰css3
-webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); -o-filte ...
- css3图片变灰
html{ filter:grayscale(100%); -webkit-filter:grayscale(100%); -moz-filter:grayscale(100%); -ms-filte ...
- CSS实现图片变灰色及透明度
[图片变灰] 每当遇到哀悼日,很多网站快速变灰色,来看看实现方式吧: 方式一,仅支持ie) html{filter:progid:DXImageTransform.Microsoft.BasicIma ...
随机推荐
- Akka源码分析-Actor发消息
前面两篇文章简单介绍了ActorSystem.actor以及dispatcher和mailbox的创建,下面我们就来看一下actor发消息的内部机制. val system = ActorSystem ...
- QT 制作串口调试小助手----(小白篇)
一.成品图展示 简介:因zigbee实验,制作一个相对简易版的上位机,接收来自zigbee无线传感采集的温湿度.光照等数据. 并且将数据部分描绘成实时动态折线统计图. 二.主要功能介绍 主要使用QT自 ...
- Patch 21352635 - Database Patch Set Update 11.2.0.4.8
一.CPU和PSU 近日,将数据库从9.2.0.6升级到11.2.0.4后,发现11.2.0.4通过DBLINK访问其他的9i库时发生ORA-02072错误,通过Google找到解决方案,即升级到PS ...
- [转]Linux命令之iconv
转自:http://lorna8023.blog.51cto.com/777608/420313 用途说明 iconv命令是用来转换文件的编码方式的(Convert encoding of given ...
- Unity实现屏幕抖动效果(通过Camera Viewpoint实现)
由于游戏死亡时一般都需要屏幕抖一下下. 所以百度了下相关写法,发现方法很多~~~ 找来找去,找到个简单粗暴地,啥都不需要,一个脚本拖动到Camera上就可以了 略微修改了一点点,share一下 usi ...
- 表格对象的获取和更改(原生js)
表格对象的获取 var oT = document.getElementById("tb"); //获取head console.log(oT.tHead); console.lo ...
- android ormlite 清空表
delete from TableName; //清空数据 update sqlite_sequence SET seq = where name ='TableName';//自增长ID为0 Sam ...
- CSS——层叠性
层叠性:浏览器渲染是从上而下的,当多个样式作用于同一个(同一类)标签时,样式发生了冲突,总是执行后边的代码(后边代码层叠前边的代码).和标签调用选择器的顺序没有关系. <!DOCTYPE htm ...
- 【sqli-labs】 less46 GET -Error based -Numeric -Order By Clause(GET型基于错误的数字型Order By从句注入)
http://192.168.136.128/sqli-labs-master/Less-46/?sort=1 sort=4时出现报错 说明参数是添加在order by 之后 错误信息没有屏蔽,直接使 ...
- Linux 之CentOS7使用firewalld打开关闭防火墙与端口
一.firewalld的基本使用 启动: systemctl start firewalld 关闭: systemctl stop firewalld 查看状态: systemctl status f ...