Skia 或 Direct2D 如何使用 GPU 渲染线条或多边形?
Posted
技术标签:
【中文标题】Skia 或 Direct2D 如何使用 GPU 渲染线条或多边形?【英文标题】:How does Skia or Direct2D render lines or polygons with GPU? 【发布时间】:2021-11-18 14:27:13 【问题描述】:这是一个了解GPU加速渲染2d矢量图形原理的题。
使用 Skia 或 Direct2D,您可以绘制例如圆角矩形、贝塞尔曲线、多边形,还有一些像模糊的效果。
Skia / Direct2D 提供基于 CPU 和 GPU 的渲染。
对于 CPU 渲染,我可以或多或少地想象如何,例如渲染一个圆角矩形。我已经见过很多不同的线条渲染算法了。
但对于 GPU,我没有太多线索。
圆角矩形是由三角形组成的吗? 圆角矩形是否完全由野生像素着色器绘制?有没有一些基本的例子可以告诉我这些事情是如何工作的基本原理?
(可能在Skia的源代码中也可以找到解决方案,但我担心它会如此复杂/通用,以至于像我这样的菜鸟什么都看不懂。)
【问题讨论】:
发现了一些东西:reddit.com/r/GraphicsProgramming/comments/93t3a0/… 【参考方案1】:对于 direct2d,没有源代码,但由于它在后台使用 d3d10/11,因此很容易看到它在 Renderdoc 的幕后做了什么。
基本上,d2d 倾向于通过尝试将任何几何类型放入单个缓冲区来最小化绘制调用,而skia 则根据形状类型具有一些专用的着色器集。
因此,例如,如果您绘制贝塞尔路径,Skia 将尽可能尝试使用镶嵌着色器(如果您渲染的前一个元素是矩形,则需要新的绘制调用),因为您更改了管道状态。
另一方面,D2D 倾向于在 cpu 上进行镶嵌,并推送到一些顶点缓冲区,并且只有在您更改画笔类型时才切换绘制调用(如果您从一种纯色画笔更改为另一种,它可以保持相同的着色器,所以它不会切换),或者当缓冲区已满时,或者如果你从形状切换到文本(因为它需要发送纹理图集)。
请注意,在细分贝塞尔路径时,D2D 在使生成的几何图形不自相交方面做得非常好(因此即使在一些复杂的自相交路径上,Alpha 混合也能正常工作)。
在圆角矩形的情况下,它的作用相同,只是镶嵌成三角形。
这允许它在很大程度上最小化绘制调用,并允许在非 msaa 表面上进行抗锯齿(这是在网格级别完成的,带有一些带有 alpha 的小三角形)。它的缺点是它不使用太多硬件功能,并且发出的几何图形可能非常高,即使对于看似简单的形状也是如此)。
由于 d2d 更喜欢使用三角形条带或三角形列表,它在绘制简单的三角形列表时可以做一些非常有趣的事情。
对于文本,d2d 使用实例化并为每个字符绘制一个实例四边形,它也擅长批量处理,因此如果您连续多次调用某些绘制文本函数,它会尝试将其合并为单个调用嗯。
【讨论】:
哇!我会接受这个作为答案,因为它有很多详细的信息。 (我将不得不对某些术语进行一些研究,但这是一个很好的起点)谢谢!以上是关于Skia 或 Direct2D 如何使用 GPU 渲染线条或多边形?的主要内容,如果未能解决你的问题,请参考以下文章
Skia 和 Android Paint 绘图对象及其使用或文档