使用 MTLPixelFormat.rgba16Float 会导致随机舍入错误

问题描述 投票:0回答:1

我正在使用 Metal 计算管道渲染到

CAMetalLayer
的可绘制对象中,并且由于合成过程中出现一些明显的舍入错误,不断遇到非整数像素格式的问题,导致图像出现轻微的噪声。

具体来说,我想将图层配置为使用

.rgba16Float
,但在使用定点
.bgr[a]10_xr[_srgb]
像素格式时,噪声也很明显。使用整数格式(例如默认的
.bgra8Unorm
)始终会给出预期的结果。

这是一个小型的演示项目,通过并排比较来说明我的意思。两个框都由

CAMetalLayer
支持,每个像素都填充有
float4(0.5f, 0.5f, 0.5f, 1.0f)
,左侧框使用
.bgra8Unorm
,右侧框使用
.rgba16Float
。使用例如检查生成的 UI数字色度计显示,只有左框填充了纯色,而右框则出现了一些小波动。

我觉得这相当令人惊讶。即使着色器只写入一个常量值,如何会出现这种空间不均匀性?我是不是抱错了?这是苹果的错误吗?是否有可能保证与当前 API 的空间一致的舍入行为?

如果有人能够提供有关此现象的一些背景信息,我将不胜感激。这显然不是一个大问题,但它仍然让我烦恼。

编辑

Metal 允许通过

-ftexture-write-rounding-mode
编译器标志为纹理写入指定显式舍入模式,可能的选项为
native
(默认)、
rte
(舍入到最接近的偶数)和
rtz
(舍入到零) 。我在演示应用程序中尝试了所有三个,但不幸的是它没有任何区别。 (我认为这是有道理的,因为我认为问题似乎在于着色器完成写入纹理后应用于纹理的任何逻辑。)

swift metal rounding-error pixelformat cametallayer
1个回答
0
投票

系统要显示图像,最终只能显示

.bgra8Unorm
.bgra8Unorm_srgb
。因此,您将强制系统从
.rgba16Float
转换为
.bgra8Unorm
(这是不受支持的),并放弃对转换的任何控制。

您仍然可以让 Metal 与

.rgba16Float
一起工作,但显示必须是 8 位 uints。

根据

CAMetalLayer
注释:

开放类 CAMetalLayer : CALayer {

/* This property controls the pixel format of the MTLTexture objects.
* The two supported values are MTLPixelFormatBGRA8Unorm and
* MTLPixelFormatBGRA8Unorm_sRGB. */

打开var PixelFormat:MTLPixelFormat

非常清楚

.rgba16Float
不支持。

© www.soinside.com 2019 - 2024. All rights reserved.