本文提出了有符号距离场(Signed Distance Fields,SDFs)作为一种快速解决方案,以实现Valve独立于分辨率的字体渲染。

我已经可以使用Valve解决方案,但是我想保持转角处的清晰度。 Valve指出,他们的方法可以通过使用第二个纹理通道与基本纹理通道“与”来实现锐角,但缺乏解释如何生成第二个通道。

实际上,本文遗漏了许多实现细节。

我想知道你们中是否有人可以向我指出获得具有尖角的SDF字体渲染的方向。

评论

事实上,亚当已经在shadertoy上发布了源代码。这是链接:shadertoy.com/view/ltXSDB

你让我兴奋。他确实将bezier内容发布在shadertoy上,但未将纹理距离字段内容发布!

@AlanWolfe我认为他只是为通过程序设置贝塞尔曲线所做的。我不确定将其集成到ttf render lib中所需的工作。有空的时候我来看一下。

看起来他在实际存储和检索纹理距离方面有一些魔力。在没有纹理的情况下,shadertoy示例缺少方程式的该部分。

参加聚会有点晚,但是来自reddit的这个较旧的主题提供了大量有关提高基于SDF渲染的清晰度的方法的信息:reddit.com/r/gamedev/comments/2879jd/…

#1 楼

亚当·西蒙斯(Adam Simmons)在这方面做了一些有趣的工作。我具体不知道他是如何实现的,但是他的基于SDF的矢量渲染是我在Valve以外的实践中所见过最清晰的。 http://twitter.com/adamjsimmons/status/611677036545863680

评论


$ \ begingroup $
当然,我并没有全部的细节,但是在我看来,这个人只是使​​用伪距场来代替常规场,这在2006年Qin,McCool的论文中已经得到证明。和Kaplan,“实时纹理映射矢量字形”,在Valve文件中也有提及。它仅影响轮廓的斜角,无助于改善角的外观。我怀疑它看起来很锐利的原因是因为他使用了不切实际的大距离场纹理。我可能是错的。
$ \ endgroup $
– Detheroc
16 Mar 7 '16 at 12:21

#2 楼

编辑:请查看我的其他答案,并提供具体解决方案。

一年多以前,我的硕士论文实际上已经解决了这个确切的问题。在Valve论文中,他们表明您可以AND两个距离场来实现这一点,只要您只有一个凸角即可。对于凹角,还需要“或”运算。这个家伙实际上开发了一些模糊的系统,可以使用四个纹理通道在两个操作之间进行切换。

但是,有一种更简单的操作可以根据情况简化AND和OR的操作,这就是我论文的主要思想是:中位数为三。因此,基本上,您可以使用完全可互换的三个通道(理想的RGB通道),并使用中值运算将它们组合起来(从三个通道中选择中间值)。

以适应抗锯齿,我们不仅使用布尔值,还使用浮点值,并且AND运算变为最小值,而OR运算成两个值的最大值。三个的中位数确实可以做到:如果a 渲染过程仍然非常简单。整个片段着色器(包括抗锯齿)可以看起来像这样:但是,您将必须实现中值函数,只需执行4分钟/最大操作即可。

当然,现在的问题是,如何建立这样的三通道距离场?这是棘手的部分。我一开始采用的最明显的方法是将输入形状/字形分解为三个分量,然后从每个分量中生成常规距离场。分解的规则并不那么复杂。首先,在3个通道中至少有2个位于内部的区域。然后,如果您将其想象为RGB颜色通道,则凸角必须由辅助颜色制成,并且其两个主要成分继续向外延伸。凹角是相反的:两个辅助色围住它们共同的主色,并且两个边向内连续的位置之间的楔形是白色。我还发现一些填充是必要的,否则会碰触两个原色或两个副色以避免伪影(例如,在图片中“ N”的中间笔画中)。是程序根据我的论文生成的示例分解:



但是这种方法有一些缺点。其中之一是特殊效果(例如轮廓和阴影)将不再正常工作。 Fortunatelly,我还想出了第二种更为优雅的方法,它可以直接生成距离场,甚至支持所有图形效果。它也包含在我的论文中,也已经有1年多的历史了。我现在不打算提供更多详细信息,因为我目前正在写一篇详细描述第二种技术的论文,但是一旦完成,我将在此处发布。无论如何,这是质量差异的一个例子。每张图像的纹理分辨率都相同,但是左边的使用常规纹理,中间的使用普通距离场,右边的使用我的三通道距离场。性能开销只是采样RGB纹理与单色纹理之间的区别。



评论


$ \ begingroup $
伟大的第一答案,欢迎来到Computer Graphics SE! :)您的论文可以公开发表吗? (或者是在完成所述论文之后?)如果这样的话,链接到该文档也可能非常有帮助。
$ \ endgroup $
–马丁·恩德(Martin Ender)
16 Mar 7 '16 at 13:57

$ \ begingroup $
应该是公开可用的,但是学校似乎还没有提出来。无论如何,我不希望现在就散布它,因为我正在写的文章将真正更好地解释重要部分并集中于如何实现它,并且它应该很快完成。
$ \ endgroup $
– Detheroc
16 Mar 7 '16 at 14:26



$ \ begingroup $
@Detheroc完成本文后,请在此处和gamedev Q上进行通知。解释对我来说还不是100%清晰。我建议逐步在图像中显示构图。
$ \ endgroup $
–工程师
16 Mar 7 '16 at 15:09



$ \ begingroup $
希望能够复制您当前的结果,即使它们不如您将来的结果好,也可以+1共享您可以分享的所有细节。非常令人兴奋。您是否考虑过任何一种技术在射线行进(球面跟踪)中的应用?在体积纹理或类似纹理中...
$ \ endgroup $
–艾伦·沃尔夫(Alan Wolfe)
16 Mar 7 '16 at 19:36

$ \ begingroup $
论文可在此处公开获得:dspace.cvut.cz/bitstream/handle/10467/62770/…
$ \ endgroup $
–罗曼·盖伊
16-4-28的22:00



#3 楼

很抱歉,等待时间很长,但是很明显,尽管我已答应的文章已基本完成,但发布过程仍需要一些时间。因此,我改用我的新多通道距离场构造算法msdfgen准备了一个开源程序,您可以立即试用。

它可在GitHub上找到:https:// github .com / Chlumsky / msdfgen

(我是新来的,所以请告诉我存储库是否有问题。)与更大的单色距离场相比,这里是质量差异的预告片。但是,它确实取决于特定的字体,我不会说它总是值得额外的数据。




#4 楼

挺有意思!我是阀门签名定距纸的作者。抱歉,实现细节有点稀疏。
我仅将两个通道的示例作为以后的工作-我没有生成器。我想过要生成一个高分辨率的sdf,然后根据sdf的倾斜角度进行分段是一种合理的策略。但是永远都不要这么做。
对于您的应用所需的放大倍数,任何多通道方案都必须权衡使用具有相同内存占用的更高分辨率的单通道数据。

#5 楼

我绝不是这个主题的专家,但是,如果您使用双向滤镜,定向双三次滤镜而不是标准双线性滤镜,则至少在理论上可以在单色伪SDF中保留尖角。除了节省内存的明显好处外,您还可以为多色SDF贴花设置多个通道。分别用于“水平距离”和“垂直距离”,并使用“差拉普拉斯(DoL)”能量金字塔压缩纹理,这样就不会记录冗余信息。不能通过数组集寻址对六角形采样的纹理进行实验。想法。我将在短时间内获得我的信息/想法的所有相关文章链接。