繁体   English   中英

MetalKit 视图 MTKView 显示模糊的笔划并推断其指定的路径/大小

[英]MetalKit view MTKView showing blurry stroke and extrapolating their designated path/size

我正在尝试使用 MetalKit 绘制正方形。 每个正方形都有一个原点和一个大小,如下所示:

Origin:

▿ (204.5746214852199, 62.83450704225352)
  - x : 204.5746214852199
  - y : 62.83450704225352

Size:

▿ (1.4612472963229992, 1.4612676056338028)
  - width : 1.4612472963229992
  - height : 1.4612676056338028

问题是,当 MetalKit 绘制这些时,每个正方形都以不同的奇怪方式绘制,超出了正方形的预期面积和形状(见下图) - 是的,每个红色簇应该代表一个 1x1 的正方形下面那些灰色方块的大小相同。 此外,它的边界也很模糊(这是放大的图像)。 我正在使用这个采样器:

constexpr sampler textureSampler(mag_filter::nearest,
                                 min_filter::nearest);

带有一些红色像素的灰度像素板

在上图中,灰度正方形是每个红色正方形应该适合的位置(它们的边界和确切位置)。

任何线索如何实现这一目标? MetalKit 会不会一直丢失小数精度? 如何使正方形边缘锋利?

这是我的顶点函数和位置结构: https ://github.com/s1ddok/MetalCoreGraphics/blob/d32c680a156548e20e9e9deb06e14cc260bcdea1/MetalCoreGraphics/Shaders.metal#L12-L30

任何线索在这里都会非常有帮助! 欣赏它!

根据Metal Shader Language Specification ,Metal 以单精度浮点格式存储 Vertex 的位置值。

类型 描述
漂浮 一个 32 位浮点数。 浮点数据类型必须符合 IEEE 754 单精度存储格式。

这适用于可以精确表示的小值,但由于浮点舍入误差,精度会随着值的增加而降低。 因此,远离原点渲染的 Actor 定位不准确(它们稍微放错了位置)。

我建议您通过https://developer.apple.com/documentation/metal/developing_and_debugging_metal_shaders调试看起来不正确的片段您将能够检查每个输出片段正在执行什么计算以及它是否是意外的。

我最终能够弄清楚事情。 这是几件事的结合。

  1. 小方块(这里命名为像素)超出了它们的预期范围,因为它们正在被抗锯齿。 由于我使用CGContext来桥接 CPU 和 GPU 内存( 从这里采取的策略),我必须添加以下代码(两行!):
context.setShouldAntialias(false)
context.setAllowsAntialiasing(false)
  1. 由于 CALayer 放大滤镜而不是 Metal 的放大,像素在放大时模糊。 解决方案非常简单:
layer.magnificationFilter = .nearest // Disables pixel interpolation when zooming in
  1. 最后但并非最不重要的一点是,像素坐标(和大小)与底层像素完美的棋盘不匹配,因为我绘制的像素实际上是CGRectscontext.addRects() ),而那些 CGRects 也有 -精确的宽度/高度,通常小于 1.00(即使在原始问题中不是这种情况,它也有浮点,这在绘制单个像素时并不是一个真正的东西 - 没有半个像素这样的东西)。 因此,解决方案是使用具有所需像素确切数量的画布,并让我正在绘制的所有 CGRect 大小为 1x1pt。 这样,它不仅性能更高(因为不会一直进行浮点计算),而且它始终是像素完美的。

看下面的最终结果(这个视图使用UIScrollView放大了 150 倍):

最后结果

希望这可以帮助那里的人! 感谢所有贡献的人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM