首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MetalKit视图MTKView显示模糊笔画并推断它们指定的路径/大小

MetalKit视图MTKView显示模糊笔画并推断它们指定的路径/大小
EN

Stack Overflow用户
提问于 2022-05-02 11:38:21
回答 2查看 155关注 0票数 1

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

代码语言:javascript
复制
Origin:

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

Size:

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

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

代码语言:javascript
复制
constexpr sampler textureSampler(mag_filter::nearest,
                                 min_filter::nearest);

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

知道怎么做到这一点吗?MetalKit是否会在此过程中失去十进制精度?我怎样才能使正方形边缘锋利?

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

任何线索在这里都会非常有用!很感激你!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-20 11:41:10

我终于想出了办法。这是几件事的结合。

  1. 这些小方块(这里命名为像素)超出了它们的预期界限,因为它们被反别名了。由于我使用CGContext连接CPU和GPU内存(从这里采取的策略),所以我必须添加以下代码(两行都是!):
代码语言:javascript
复制
context.setShouldAntialias(false)
context.setAllowsAntialiasing(false)
  1. 由于CALayer放大滤光器而不是金属放大镜,像素在放大时变得模糊。解决办法很简单:
代码语言:javascript
复制
layer.magnificationFilter = .nearest // Disables pixel interpolation when zooming in
  1. 最后但并非最不重要的一点是,像素坐标(和大小)与底层像素完美的棋盘不匹配,因为我画的像素实际上是CGRects (context.addRects()),而那些CGRects的宽度/高度过于精确,通常小于1.00 (尽管在最初的问题中并非如此,但在绘制单个像素时,浮点并不是一件事情--没有半像素这样的东西)。因此,解决这一问题的方法是使用一个画布,该画布具有所需的确切像素数,并且我所绘制的所有CGRects都具有1x1pt大小。这样,它不仅表现得更好(因为不会一直都有浮点计算),而且它总是像素完美的。

请参见下面的最终结果(使用UIScrollView将此视图放大150次):

希望这对外面的人有帮助!感谢大家的贡献!

票数 1
EN

Stack Overflow用户

发布于 2022-05-06 16:22:48

我建议您调试通过着色器看起来不正确的片段,您将能够检查每个输出片段正在做什么计算,以及它是否意外。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72086130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档