我想使用具有多个渲染目标的片段着色器从 RGB 输入输出 YCbCr 数据,其中 Y 数据写入一个纹理,CbCr 写入另一个较小的纹理(由于色度子采样)。对这个答案的评论似乎表明这是可能的(甚至是首选方法),但我似乎不知道如何实现。
我知道我可以通过从片段返回结构并在设置渲染管道时添加多个颜色附件来渲染到多个目标(请参阅下面的代码片段)。然而,当我这样做时,最终渲染区域似乎只对应于较小的纹理,这意味着 Y 纹理不能完全由片段填充。即使渲染区域对应于较大的纹理,鉴于渲染目标具有不同的大小,我不太明白片段的两个输出如何正确解析为每个纹理。我缺少什么?我必须在光栅化阶段做一些特别的事情吗?
struct Output {
float y [[ color(0) ]];
float2 cbCr [[ color(1) ]];
};
fragment Output example(texture2d<float, access::read> rgbInput [[ texture(0) ]], ...)
{
Output out;
// Populate data...
return out;
}
let descriptor = MTLRenderPassDescriptor()
descriptor.colorAttachments[0].texture = yTexture // full-size texture
descriptor.colorAttachments[1].texture = cbCrTexture // smaller texture
... // Set up the rest of the render pass as usual
您不能将不同大小的渲染目标绑定到同一渲染通道。这是不可能用
MTLRenderCommandEncoder
做到的。它要求所有渲染目标具有相同的大小。从调度片段着色器的角度来考虑。如果您有一个 1000x1000 渲染目标和一个 500x500 渲染目标,您将如何运行片段着色器?在 1000x1000 的网格中?但是,如何为渲染目标 2. 500x500 选择四个输出值之一呢?但随后您只需将相同的输出放大四倍到 1000x1000 渲染目标即可。