一种新型的字体渲染方式
2017-01-16 15:00
169 查看
新的方式,其实一点也不新,其实是一种称为signd distance field的矢量图保存和渲染方法。
早在二零零几年,就已经有一些游戏应用了这种技术,而他用于字体渲染也被发掘多时。
但是这个世界,技术成果转化的速度总是很慢很慢,这个优势明显的技术一直没有普及开来。
我们先来说说矢量和位图的区别:
一个汉字,人眼看起来就是一个形状
这是位图,是上面那个汉子用位图存储方式放大后的一个局部
再来看看矢量化放大的效果
瞎子也能明白,矢量是适合缩放的。
现在游戏中,因为大量使用位图字体,而位图字体并不适合缩放,于是如果要用不同大小
位图放大后都是这个屌样子。
这也是为什么我们要引入signddistancefield,他是一种矢量表示法。
用位图,表示矢量,表示方法我随便一说,你随便一听,并不是太有所谓。因为我会给你一套东西,你能照猫画虎用起来。
还是这张图,把他存成一个很小的像素图,只不过每个像素存的不是颜色,而是离边的最短距离。
现在白色部分,在形状内,存为负值,黑色部分,在形状外,存为正值。
请忽略我拙略的绘图技巧。
这样保存后的图片,你可能会问我,一个像素分量是0~255,咋存正负,我会告诉你,128当零,行不行。
这个细节不深究,让我们换个方法来表示,本质上是为了区分边的内外。比如我设定颜色255在形状内最深的地方,127是形状边,0是离形状最远的地方,当然我们也不需要离边太远的数据,可以让离边超出一定距离的数据全是255和零,只有在边附近,有过度。
这是一个文字用signeddistancefield表示法保存后的结果。
如我们所言,255是离边最远,在形状内的部分,外边的纯透明部分,是alpha为零里边最远的部分。
这样的表示法,在还原成形状的时候,我们只要判断 >就行了,>127的部分画出来,就是原来的形状
>200的部分画出来,是个向内收缩的形状。
>100的部分画出来,是个向外扩张的形状。
我们如果要做描边,可以在shader里写个if
比如>127纯白 100-127 黑色。
你可能会发现一个问题,这种情况只有透明不透明,两种情况。
这个问题可以解决,往下看
而且因为源数据是离边的距离,两个像素的插值就是当前像素离边的距离。
这个信息是线性的,插值数据不会偏离太远,抗缩放性能非常好。
第一步,把图片或者字体保存为signeddistancefield
因为SDF实际上已经是应用很多的技术,所以工具并不缺乏。
我就找到了两个。
http://www.gamedev.net/topic/491938-signed-distance-bitmap-font-tool/
我们简称他BFTool,我很喜欢这个工具,因为很小巧,几百k,还包括源码和测试字体和图片。
还有龚敏敏的KLAYGE里面也提供了一个字体保存为signeddistancefield的工具
不过这玩意从他的一堆c++代码里剥出来要花点功夫。
我们这里就介绍一下BFTool
先下载这个工具
http://www.lonesock.net/files/SDFont.zip
他没有图形界面,but,whocare
找到这个文件
可以把一张png 或者一个ttf拖上去
然后输入一些参数,就会生成啦。
先找张图片
比如这个,至少1024以上
让我们把他输出成32*32的sdf图像
你可能无法期待这32*32个像素可以输出什么像样的效果。
来吧,见证奇迹的时刻到了。
这就是32*32的SDF图像还原出的效果,还顺便做了描边
更粗的描边
向内描边
使用的shader关键代码如下
http://code.taobao.org/p/fightbeta/src/trunk/dfbitmap/
很简单,就是ifif,描边没有任何开销,不过去狗牙要多几次采样。(这地方是我考虑不周到)
后来考虑了一下,不用多次采样,将距离多分几段插插值,不用额外采样就能完美去狗牙
注,这张图是展示去狗牙效果,是128分辨率的,和上面的不一致。
能明白我再说什么的人自然明白。
你已经看到了32*32的SDF图像能做到什么,如果你把文字生成为32*32的足够精细了。
一张2048的贴图,可以放4000个32*32的文字。
而且抗缩放,大小字号一图搞定。
只要把一个ttf字库拖入sdfont.exe
给他参数,你就能得到一张sdf图片,和一张字符uv描述文件
加油吧,骚年。
早在二零零几年,就已经有一些游戏应用了这种技术,而他用于字体渲染也被发掘多时。
但是这个世界,技术成果转化的速度总是很慢很慢,这个优势明显的技术一直没有普及开来。
1.矢量的优势
我们先来说说矢量和位图的区别:一个汉字,人眼看起来就是一个形状
这是位图,是上面那个汉子用位图存储方式放大后的一个局部
再来看看矢量化放大的效果
瞎子也能明白,矢量是适合缩放的。
现在游戏中,因为大量使用位图字体,而位图字体并不适合缩放,于是如果要用不同大小
位图放大后都是这个屌样子。
2.Signeddistancefield表示法
这也是为什么我们要引入signddistancefield,他是一种矢量表示法。用位图,表示矢量,表示方法我随便一说,你随便一听,并不是太有所谓。因为我会给你一套东西,你能照猫画虎用起来。
还是这张图,把他存成一个很小的像素图,只不过每个像素存的不是颜色,而是离边的最短距离。
现在白色部分,在形状内,存为负值,黑色部分,在形状外,存为正值。
请忽略我拙略的绘图技巧。
这样保存后的图片,你可能会问我,一个像素分量是0~255,咋存正负,我会告诉你,128当零,行不行。
这个细节不深究,让我们换个方法来表示,本质上是为了区分边的内外。比如我设定颜色255在形状内最深的地方,127是形状边,0是离形状最远的地方,当然我们也不需要离边太远的数据,可以让离边超出一定距离的数据全是255和零,只有在边附近,有过度。
这是一个文字用signeddistancefield表示法保存后的结果。
如我们所言,255是离边最远,在形状内的部分,外边的纯透明部分,是alpha为零里边最远的部分。
这样的表示法,在还原成形状的时候,我们只要判断 >就行了,>127的部分画出来,就是原来的形状
>200的部分画出来,是个向内收缩的形状。
>100的部分画出来,是个向外扩张的形状。
我们如果要做描边,可以在shader里写个if
比如>127纯白 100-127 黑色。
你可能会发现一个问题,这种情况只有透明不透明,两种情况。
这个问题可以解决,往下看
而且因为源数据是离边的距离,两个像素的插值就是当前像素离边的距离。
这个信息是线性的,插值数据不会偏离太远,抗缩放性能非常好。
3.实战SignedDistanceField
第一步,把图片或者字体保存为signeddistancefield因为SDF实际上已经是应用很多的技术,所以工具并不缺乏。
我就找到了两个。
http://www.gamedev.net/topic/491938-signed-distance-bitmap-font-tool/
我们简称他BFTool,我很喜欢这个工具,因为很小巧,几百k,还包括源码和测试字体和图片。
还有龚敏敏的KLAYGE里面也提供了一个字体保存为signeddistancefield的工具
不过这玩意从他的一堆c++代码里剥出来要花点功夫。
我们这里就介绍一下BFTool
先下载这个工具
http://www.lonesock.net/files/SDFont.zip
他没有图形界面,but,whocare
找到这个文件
可以把一张png 或者一个ttf拖上去
然后输入一些参数,就会生成啦。
先找张图片
比如这个,至少1024以上
让我们把他输出成32*32的sdf图像
你可能无法期待这32*32个像素可以输出什么像样的效果。
来吧,见证奇迹的时刻到了。
这就是32*32的SDF图像还原出的效果,还顺便做了描边
更粗的描边
向内描边
使用的shader关键代码如下
http://code.taobao.org/p/fightbeta/src/trunk/dfbitmap/
很简单,就是ifif,描边没有任何开销,不过去狗牙要多几次采样。(这地方是我考虑不周到)
后来考虑了一下,不用多次采样,将距离多分几段插插值,不用额外采样就能完美去狗牙
注,这张图是展示去狗牙效果,是128分辨率的,和上面的不一致。
能明白我再说什么的人自然明白。
4.关于字体
你已经看到了32*32的SDF图像能做到什么,如果你把文字生成为32*32的足够精细了。一张2048的贴图,可以放4000个32*32的文字。
而且抗缩放,大小字号一图搞定。
只要把一个ttf字库拖入sdfont.exe
给他参数,你就能得到一张sdf图片,和一张字符uv描述文件
加油吧,骚年。
相关文章推荐
- 讲一讲一种新型的字体渲染方式
- 讲一讲一种新型的字体渲染方式
- 新型字体渲染方式
- 一种针对JAVA漏洞的新型恶意攻击方式
- fedora使用mac osx字体和渲染方式
- fvf采用另外一种方式渲染
- 一种基于矩形块的颜色渲染方式实现二维数据可视化
- 一种比较有效的测试和开发的配合方式 [ 光影人像 东海陈光剑 的博客 ]
- 一种可以避免数据迁移的分库分表scale-out扩容方式 - 李占卫 - 博客园
- 换一种方式去思考--microsoft for win server03
- java中写构造函数的另外一种方式
- 分享一种便利的短信方式 潇湘
- 这个冬天一种极具逼格的取暖方式,挂幅名画做暖气#关爱南方人#丨钛空智慧星球推荐
- 单链表的创建、插入、删除;创建采用两种不同的方式:一种是从表头到表尾,另一种是从表尾到表头!
- 在ASP.NET MVC实现购物车,尝试一种不同于平常的购物车显示方式
- Zabbix监控nginx性能的另外一种方式
- 【PhotoShop】【ARkit】3d模型单独渲染阴影的一种方法给ARKIT用
- rsync实现免密码操作的一种实现方式
- 续 一种生成报表的另类方式--Excel
- Android studio中TextView改变字体的两种方式(如仿宋、隶书)