金属RGB到YUV转换计算着色器

4

我试图编写一个Metal计算着色器,将RGB转换为YUV,但是出现了构建错误。

typedef struct {
   float3x3 matrix;
   float3   offset;
} ColorConversion;

  // Compute kernel
 kernel void kernelRGBtoYUV(texture2d<half, access::sample> inputTexture [[ texture(0) ]],
                       texture2d<half, access::write> textureY [[ texture(1) ]],
                       texture2d<half, access::write> textureCbCr [[ texture(2) ]],
                       constant ColorConversion &colorConv [[ buffer(0) ]],
                       uint2 gid [[thread_position_in_grid]])
{
  // Make sure we don't read or write outside of the texture
  if ((gid.x >= inputTexture.get_width()) || (gid.y >= inputTexture.get_height())) {
      return;
  }



  float3 inputColor = float3(inputTexture.read(gid).rgb);

  float3 yuv = colorConv.matrix*inputColor + colorConv.offset;

  half2 uv = half2(yuv.gb);

  textureY.write(half(yuv.x), gid);

  if (gid.x % 2 == 0 && gid.y % 2 == 0) {
      textureCbCr.write(uv, uint2(gid.x / 2, gid.y / 2));
  }
} 

最后一行,即写入textureCbCr时出现错误:
  no matching member function for call to 'write'

我做错了什么?

在这里输入图片描述


这是一个texture2d,在计算着色器中已经声明为参数。 - Deepak Sharma
它应该是rg,仅有两个颜色组件。 - Deepak Sharma
你能否请解释一下如何使用 ColorConversion 结构体?offset 是什么,转换矩阵不是总是相同的吗? - Dalton Sweeney
1
Deepak,你能分享一些工作示例代码吗?我有同样的需求,这会对我很有帮助。 - M P
1个回答

4
根据《Metal Shading Language Specification》规范,texture2d<>的所有重载的write函数的第一个参数都是四元素向量,即使你要写入的纹理元素少于4个也是如此。因此,你可以通过将错误的行替换为以下内容来解决此问题:
textureCbCr.write(half4(yuv.xyzz), uint2(gid.x / 2, gid.y / 2));

在进行写操作时,多余的组件将被屏蔽。


奇怪的是,它适用于一个元素向量但不适用于两个,为什么? - Deepak Sharma
1
也许是因为在 MSL 中,标量可以被隐式转换为向量,但我不确定。 - warrenm
你能否也看一下这个问题 - https://stackoverflow.com/questions/57834241/ciimage-display-mtkview-vs-glkview-performance - Deepak Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接