【问题标题】:Copy Metal frame buffer to MTLTexture with different Pixel Format将金属帧缓冲区复制到具有不同像素格式的 MTLTexture
【发布时间】:2020-03-23 05:43:01
【问题描述】:

我需要将屏幕像素抓取到纹理中以执行后期处理。 以前,我一直在使用 BlitCommandEncoder 从纹理复制到纹理。源纹理是 MTLDrawable 纹理,放到我的目标纹理上。它们都有相同的 MTLPixelFormatBGRA8Unorm,所以一切正常。

但是,现在我需要使用 MTLPixelFormatRGBA16Float 的帧缓冲区颜色附件纹理进行 HDR 渲染。所以,当我抓取屏幕像素时,我实际上是从这个颜色附件纹理而不是 Drawable 纹理中抓取的。我收到了这个错误:

[MTLDebugBlitCommandEncoder internalValidateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:]:447: 断言失败 [sourceTexture pixelFormat](MTLPixelFormatRGBA16Float) 必须等于 [destinationTexture pixelFormat](MTLPixelFormatBGRA8Unorm)

我认为我不需要将目标纹理更改为 RGBA16Float 格式?因为那会占用双倍的内存。一个具有该格式的全屏纹理(颜色附件)应该足以让 HDR 正常工作?

还有其他方法可以成功执行这种复制吗? 在 openGL 上使用 glCopyTexImage2D 复制时没有错误

【问题讨论】:

  • 好吧,如果您不想使用 16 位浮点数,则需要添加渲染通道以转换为您想要使用的任何像素格式。我不确定我是否理解您所说的“一个全屏纹理......对于 HDR 来说应该足够了”。 HDR 以不同的像素格式和位深度表示,但我认为您通常需要每个颜色通道至少 10 位,因此您可能需要考虑 MTLPixelFormatRGB10A2Unorm 之类的东西。
  • @ldoogy ok 将尝试添加渲染通道。我正在使用 MTLPixelFormatRGBA16Float 来渲染超过 1.0 的颜色范围 Unorm 被限制在 0 到 1 之间。
  • 我建议您对所有渲染纹理都使用 sRGB,这样可以避免将 16 位半像素的内存加倍,并且不会因渲染为线性 RGB 而失去精度。加上 blit 就可以了。
  • @MoDJ 可以渲染颜色范围 > 1.0 吗?目前我在使用 GLES 2 时遇到一个问题,即“GL_RGBA16F”是一个未声明的标识符。(对于 Android,因为这是一个跨平台应用程序)

标签: ios graphics metal blit


【解决方案1】:

Metal 在渲染过程中会自动从源格式转换为目标格式。所以你可以只做一个无操作渲染传递来执行转换。

或者,如果您想避免样板的无操作渲染代码,您可以使用基本相同的MPSImageConversion 性能着色器。

【讨论】:

  • 感谢您提供的建议方法。将尝试渲染通道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-05
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
  • 1970-01-01
相关资源
最近更新 更多