【问题标题】:MTKTextureLoader messes PNG RGB vs BGR formatsMTKTextureLoader 将 PNG RGB 与 BGR 格式混淆
【发布时间】:2019-07-22 10:18:01
【问题描述】:

我正在尝试将我的 OpenGL 代码移植到 Metal one。作为其中的一部分,我需要绘制 PNG 纹理,并且我正在使用 MTKTextureLoader 来加载它们。这是我的管道代码:

texturePipelineDescriptor.vertexFunction = textureVertexFunc;
texturePipelineDescriptor.fragmentFunction = textureFragmentFunc;
texturePipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;

texturePipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
texturePipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
texturePipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
texturePipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;

这是我的加载器代码:

NSData* imageData = [NSData dataWithBytes:imageBuffer length:imageBufferSize];
id<MTLTexture> newMTLTexture = [m_metal_renderer.metalTextureLoader newTextureWithData:imageData options:nil error:&error];

结果如下。整个图像应该是橙色的,就像小部分一样。

如果我改变这一行:

texturePipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;

到这一行:

texturePipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;

我会得到以下结果:

如你所见,图像改变了 R 和 B 通道,当我加载纹理时,在所有这些中

newMTLTexture.pixelFormat = MTLPixelFormatBGRA8Unorm;

无论它们是否正确绘制。 我怀疑 PNG 文件有问题,但在任何 PNG 查看器中它们似乎都是正常的。

任何线索我可以做些什么来解决它?它是 MTLTextureLoader 中的错误吗?还有其他加载PNG图片的方法吗?

附:该软件是为 MacOS 而不是 iOS 编写的。

【问题讨论】:

    标签: objective-c macos metal


    【解决方案1】:

    我发现了问题。似乎一些 PNG 文件以 RGB(24 位)格式存储,而另一些以 RGBA(32 位)格式存储。将图像转换为 32 位格式后,所有颜色都变得正确。

    我希望 MTKTextureLoader 能够处理这个问题,但显然不是。如果有人知道我错过的选项或其他将这些 PNG 正确加载到 Metal 的方法(除了手动添加第 4 个通道),那就太好了!

    【讨论】:

    • 您可以使用 ImageIO 框架使用 CGImageSourceCreateWithData() 加载 PNG 图像吗?另外,请记住,输入数据是 sRGB 而不是纯线性 RGB 数据,因此您应该使用 MTLPixelFormatBGRA8Unorm_sRGB。
    • 使用 CGImageSourceCreateWithData() 加载 PNG - 一直在考虑这个问题,或者使用 pnglib。还没到那个地步。碰巧,你有一个例子吗?至于 MTLPixelFormatBGRA8Unorm_sRGB - 我没有设置格式。 MTKTextureLoader 将其设置为它加载的纹理。将其设置为 texturePipelineDescriptor.colorAttachments[0].pixelFormat 并没有改变任何东西,但不知何故,图像更暗,对比度更高。
    • Re CGImageSourceCreateWithData() 看看Apple docs,用法很简单。您需要分配自己的金属纹理并设置 MTLPixelFormatBGRA8Unorm_sRGB。
    猜你喜欢
    • 2018-10-05
    • 2016-07-17
    • 2015-11-10
    • 2015-08-15
    • 2018-04-03
    • 2015-08-28
    • 1970-01-01
    • 2023-04-09
    • 2018-02-08
    相关资源
    最近更新 更多