javascript之WebGL 中更好的文本质量
我正在寻找一种在 WebGL 中绘制更好质量(任意)文本的方法。目前我在 2D Canvas 上使用位图字体渲染并将它们块传输到 WebGL 上下文中。
此处描述了此方法 http://delphic.me.uk/webgltext.html
这是我现在知道的在 WebGL 中绘制任意 unicode 文本的唯一解决方案。这种方法的问题是这些是位图字体,在较小的字体大小上看起来块状。我主要使用 18 的字体大小,与桌面质量字体相比,结果非常块状。
我知道threeJS有一个字体库可以生成更好看的文本,但是我不想使用threeJS,因为我有自己的包装器,它可以很好地满足我的需要并且不想增加threeJS的额外开销。
那么如何在 WebGL 中创建质量更好的文本呢?是否有在 Javascript 中提取文本形状以提高质量的方法?
请您参考如下方法:
在使用 Fonts 一段时间后,我可以看到 6 种在 WebGL 中做字体的方法,各有优缺点:
字体作为几何体
好处
缺点
Canvas
这也称为“按需动态纹理”。仅将文本字形渲染到(屏幕外) Canvas 并将其作为 WebGL 纹理 blit 到屏幕上,如下所述: http://delphic.me.uk/webgltext.html
好处
缺点
游戏帝国时代 III 使用这种方法。
位图字体
如果您希望为有限的字符集和固定的字符大小(游戏)提供最高速度和最佳质量,最好创建自己的位图,其中包含要使用的字符,并根据需要将它们 blit 到屏幕上。你可以在互联网上找到很多这样的字符位图。
这既快速又简单,但限制了您可以使用的语言和字符,但您不会介意例如在游戏中。
好处:
缺点
有符号距离字段字体
Valve 的 Chris Green 写了一本关于使用符号距离场制作纹理的“书”。您需要阅读 2007 年 SIGGRAPH 白皮书 "Improved Alpha-Tested Magnification for Vector Textures and Special Effects
通常字体纹理图集看起来像 this . SDF 纹理看起来 like .是的,当“按原样”渲染时,SDF 纹理图集看起来很模糊。那是因为 8 位 channel 已被编码为:
好处:
缺点:
smoothstep()
和 fwidth()
由于人们在纹理空间而不是屏幕空间中进行插值,导致质量较差的缩放结果。 WebGL 的 fwidth()
也无济于事使用错误的常量。 总而言之,如果您有多种字体,那么 SDF 字体在大小(只需要 1 个)和质量(在小号和大号下看起来都很棒)方面都是一个巨大的胜利
如何创建 SDF 纹理
现在有一个易于使用的 npm 模块,可以生成 SDF 纹理和元数据 available here .
自卫队演示
GPU 上的字体
人们正在探索在 GPU 上存储三次曲线,并通过让智能片段着色器完成所有繁重的渲染工作来完全绕过纹理。
此 blog有截至 2017 年 2 月的字体渲染摘要。
好处
缺点
GPU 字体演示
Canvas 叠加
对于我当前的项目,我使用 HTML5 2D Canvas 来渲染文本和其他 2D 基元,并使用 WebgGL Canvas 上的透明度将其覆盖。我对由此产生的速度感到惊讶,它在速度和质量方面击败了这里描述的所有其他方法,非常好。
只要您的文本是静态 2D 并且您不需要任何 3D 转换,这就是我的建议。在我的项目中,这比我以前使用的方法(Font as Geometry)快大约 2 倍。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。