【发布时间】:2019-02-07 08:12:27
【问题描述】:
假设我想开发一个画图应用并需要实现一个画笔引擎。对于光栅画笔,您基本上需要在具有给定间距的触摸位置上标记纹理。
-- 任务:将小图像(画笔笔尖)合成到大图像上。
我决定首先在 CG 中构建一个原型,使用 CGContext 来渲染图章,结果发现即使在合并触摸和合适大小的画布(CGContext 输出大小)的情况下,它的性能也相当不错。
但是,由于我需要在非常大的纹理上绘画(8000x6000 会很棒),所以我决定给金属一个机会。我知道这个任务对于有金属背景的人来说可能是微不足道的,但我是这个领域的新手。因此,我尝试使用 CIFilters(Metal backed)在画布上合成画笔并将其显示在自定义 MetalImageView:GTKView 中。
我认为将画布和画笔作为 CIImages 并在金属层中显示它们已经比简单的 CG 实现更高效。但事实并非如此。 CIFilter 方法渲染整个画布的每个印章(在:点),无论在 CG 中我只是在该点周围刷新一个小矩形。
现在,如果我可以更改计算的范围,我想我可以使用 CIFilter 完成此操作。我不知道 Core Image 是否可以做到这一点,但我敢肯定,对于有经验的人来说,使用金属真的很容易。
-- 问题:考虑到 CG 在引擎盖下运行 Metal,纯金属实现能否比 CG 更快地冲压图像?如果是这样,多快?是否值得学习如何去做,还是我应该更好地花时间改进 CG 实现?
请注意,我要求的是光栅画笔,而不是带有 Bezier 路径的矢量画笔,它更容易编码并且运行速度更快,但不能使用纹理画笔。
非常感谢任何帮助。
【问题讨论】:
-
CoreImage 不是 Metal,您描述的实现完全取决于核心图像过滤器的实现方式。 Metal 是一个低级的绘图 API,我可以告诉你它比其他方法快得多。但是,您是在将苹果与橙子进行比较。
-
感谢您的回复。核心图像过滤器是用金属着色语言编写的核心图像内核的包装器。如果我错了,请纠正我,但是在 Metal 中编写自定义 CIKernel 并从子类 CIFilter 调用它,获取生成的 CIImage,然后使用 CIContext 渲染到子类 MTKView 不被视为“Metal”?
-
是的,CoreImage API 与 Metal 不同。区别很容易看出,因为您可以在 Metal 中实现低级方法,并且即使是巨大的缓冲区也能正常工作。但是,在 CoreImage 之上实施相同的方法,您可能会看到大量的性能问题。这是一个示例,它在您描述的 Metal 类型的调用之上显示了确切 CoreImage 的源代码,并且性能很糟糕。 stackoverflow.com/questions/54431826/…
-
当然,“直接”Metal 方法应该更快,但我认为与同样基于 Metal 并在 GPU 上工作的其他 API 不会有很大的不同。我必须同意你的观点,如果我想要获得最佳性能,无论如何我都应该使用最好的工具来完成这项工作。我想是时候正确地学习金属了。你能为我的任务指出任何相关的金属教程吗?我见过他们中的大多数人试图用 3D 完成事情。我只想将空白画布或图像加载到 MTLTexture 上,并在其上标记另一个纹理。谢谢!!
标签: performance core-graphics metal