Ngui Shader Transparent Colored (Packed)和BMFont
来源:互联网 发布:域名注册时间查询 编辑:程序博客网 时间:2024/06/06 13:56
最近工作需要,为扩展Ngui的功能,需要自己实现一种效果,所以就打算先了解了解Ngui自带的shader,发现一般像Unlit - Dynamic Font,Unlit - Dynamic Font (AlphaClip),Unlit - Dynamic Font (SoftClip)这样都有三种配套的shader,但是Transparent Colored系列的却不止三个,还有Unlit - Transparent Colored (Packed),我就对比的看了一些它和Unlit - Transparent Colored的区别,区别也就在片段着色器的那几行代码,看过来看过去也没有看明白。。。。也没搜索到代码里哪里用到了这个packed的shader
好,那就上在网上搜搜吧,然后找到了一些关于制作ngui字体的教程http://www.unitymanual.com/blog-13559-220.html,提到了创建材质时使用带packed的shader,我就按照这个教程随便测试了一下,但发现其他的shader也可以,比如Unlit - Transparent Colored 。最后还发现使用Unlit - Transparent Colored (Packed)shader的时候,UILabel使用渐变色效果还会出现问题。
同时在网上发现其他类似这样的教程,而且貌似也只有在字体相关方面的时候Unlit - Transparent Colored (Packed)才会被提到,于是,我就开始在NGUIText里去找找看了,好了,废话说完了,切入正题
先看看Unlit/Transparent Colored (Packed)内容
Shader "Unlit/Transparent Colored (Packed)"{Properties{_MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}//纹理}SubShader{LOD 200Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent"}Pass{Cull OffLighting OffZWrite OffOffset -1, -1Fog { Mode Off }ColorMask RGBBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;half4 _MainTex_ST;//定义顶点程序输入struct appdata_t{float4 vertex : POSITION;half4 color : COLOR;float2 texcoord : TEXCOORD0;};//定义片段程序输入struct v2f{float4 vertex : POSITION;half4 color : COLOR;float2 texcoord : TEXCOORD0;};v2f vert (appdata_t v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.color = v.color;o.texcoord = v.texcoord;return o;}half4 frag (v2f IN) : COLOR{//关键在下面half4 mask = tex2D(_MainTex, IN.texcoord);half4 mixed = saturate(ceil(IN.color - 0.5));//这句是对顶点颜色各个分量四舍五入//单看下面这句不知所云,为什么是0.51,-0.49是什么意思??//和上面一句加在一起简化下来就是一个分段函数,设顶点颜色为x, //col=2.04x; (当x>=0 且 x < 0.5)//col = 2.04x -0.5/0.49; (当x >= 0.5 且 x <= 1)half4 col = saturate((mixed * 0.51 - IN.color) / -0.49);//下面操作什么意思??不懂。。。不急,慢慢来mask *= mixed;col.a *= mask.r + mask.g + mask.b + mask.a;return col;}ENDCG}}Fallback Off}在看完上面的shader的时候,我实在是不知道是干什么用的,好吧,看看NGUIText中有没相面的东西
突然发现了这几行代码
else{// Packed fonts come as alpha masks in each of the RGBA channels.// In order to use it we need to use a special shader.//// Limitations:// - Effects (drop shadow, outline) will not work.// - Should not be a part of the atlas (eastern fonts rarely are anyway).// - Lower color precisionColor col = uc;col *= 0.49f;switch (glyph.channel){case 1: col.b += 0.51f; break;case 2: col.g += 0.51f; break;case 4: col.r += 0.51f; break;case 8: col.a += 0.51f; break;}Color32 c = col;for (int j = 0, jmax = (bold ? 16 : 4); j < jmax; ++j)cols.Add(c);}
先将顶点颜色乘以0.49,然后根据字形的channel信息,选择给某个通道值加上0.51,为什么要这么做呢?channel又是什么呢?
几经折腾,终于找到了答案,原来,当我们使用Bitmap Font Generator工具为文字生成图片时,因为文字的信息只需要一个颜色通道就能存储下来,所以,可以在生成图片的时候在不同的通道写入不同的信息。具体参考http://www.angelcode.com/products/bmfont/doc/file_format.html#tags
导出的同时,还会导出一个txt文件,存储着图片和文字的一些信息,这里只列举一些
对应下图中的chnl value
说明每个通道可以存放不同的信息
导出文本中
char id=32 x=206 y=79 width=1 height=1 xoffset=0 yoffset=15 xadvance=4 page=0 chnl=15
最后一个参数解释如下
所以Ngui的做法很巧妙,如过使用了packed的功能,则需要把使用了哪个通道这个数据告诉shader,所有就有了下面
Color col = uc;col *= 0.49f;switch (glyph.channel){case 1: col.b += 0.51f; break;case 2: col.g += 0.51f; break;case 4: col.r += 0.51f; break;case 8: col.a += 0.51f; break;}Color32 c = col;for (int j = 0, jmax = (bold ? 16 : 4); j < jmax; ++j)cols.Add(c);上面的意思是先将顶点颜色乘以0.49,然后,使用了哪个通道,就把哪个通道值加上0.51
所以,传到GPU中,使用了packed的纹理的字的顶点颜色肯定是三个分量小于0.5,字形使用了的通道值大于0.5,比如,渲染一个颜色值为(0.2,0.3,0.4,0.5)的文字,
而字体纹理只用到了R通道,则,Ngui会将顶点颜色设置为(0.2*0.49+0.51,0.3*0.49,0.4*0.49,0.5*0.49)= (0.608,0.147,0.196,0.245),这里就是将所有通道值缩小一半,字体使用的通道再加上0.51,这样保证了原来顶点颜色的信息,同时也标示出了哪个通道时字体纹理使用的,即大于0.5的那个通道。
在来看shader
half4 frag (v2f IN) : COLOR{half4 mask = tex2D(_MainTex, IN.texcoord);half4 mixed = saturate(ceil(IN.color - 0.5));half4 col = saturate((mixed * 0.51 - IN.color) / -0.49);mask *= mixed;col.a *= mask.r + mask.g + mask.b + mask.a;return col;}首先mask取得片段对应纹理的颜色,但这个我们只使用其中一个通道
mixed会将顶点颜色四舍五入,所以就只会剩下一个通道值为1,其他的为0,上述的例子到这里就变成了(1,0,0,0)
然后我们的顶点颜色需要还原回来,所以half4 col = saturate((mixed * 0.51 - IN.color) / -0.49);,即col就是我们之前的顶点颜色,即(0.2,0.3,0.4,0.5)
然后mask*=mixed;,将纹理的其他值设置为0,只保留需要的通道值,即R分量值
最后,我们将字形信息通过顶点颜色的alpha分量表现出来,因为我们不知道用了哪个分量,但是mask中只有一个分量是非0的字形信息,其他的分量都置为了0,所以都加到了最终颜色的alpha分量
最终,我们用一个通道渲染出了我们设置的颜色的字体,但是却没有将通道的选择作为单独的变量传递给shader,所以我感觉Ngui的这种做法挺巧妙的
- Ngui Shader Transparent Colored (Packed)和BMFont
- Shader Learing(Transparent Shader篇)
- NGUI BMFont字体制作流程
- BMfont生成NGUI自定义中文字体
- 使用BMFont制作NGUI用的中文字体
- 使用BmFont制作NGUI的图片字体
- [Shader]对NGUI的UISprite和UITexture进行裁剪
- [Shader]对NGUI的UISprite和UITexture进行裁剪
- [Shader]NGUI与灰化
- Unity NGUI灰化Shader
- UNlit/Transparent 不发光透明shader
- unity3d 内部Transparent (透明)shader 代码
- The transparent shader receiving the shadow.
- Record和Packed record
- 【Unity Shader】简单Transparent shader的三种实现
- unity 3d中使用BMFont制作NGUI清晰字体
- unity NGUI中使用bmfont制作的字体图集
- unity 3d中使用BMFont制作NGUI清晰字体
- 编程算法 - 最好牛线(Best Cow Line) 代码(C)
- Buffer Pool Extension For 2014
- linux下tomcat使用apr连接器(含openssl)完整过程
- 简单消息协议
- 最全的Android源码目录结构详解
- Ngui Shader Transparent Colored (Packed)和BMFont
- dsssssssssssssss
- php——学习笔记,变量声明以及3种赋值方式
- android国际化
- Vim简明教程【CoolShell】
- 浅谈ANR及如何分析解决ANR
- excel中批量生成图表的脚本
- XML in ASP.NET
- 错误:Unsupported major.minor version 51.0(jdk版本错误)