金属计算核尺度图像

时间:2018-04-13 13:13:33

标签: ios opengl-es metal vertex-shader compute-shader

在使用计算着色器时,我对输出纹理中如何应用缩放操作感到有些困惑。例如,

   kernel void testCompute   (texture2d<half, access::read>  inputTexture  [[ texture(0) ]],
                   texture2d<half, access::write> outputTexture [[ texture(1) ]],
                   uint2 gid [[thread_position_in_grid]])
 {
    if ((gid.x >= inputTexture.get_width()) || (gid.y >= inputTexture.get_height())) {
    return;
}

   half4 inputColor = inputTexture.read(gid);

    half4 outputColor = half4(inputColor.r, 0.0, inputColor.b, 1.0);

    outputTexture.write(outputColor, gid);  
}

上面的计算着色器是否假设输入和输出纹理大小相等?如果我使用顶点和片段着色器,我可以使用filter :: linear配置一个采样器,输出纹理根据它的大小进行缩放。我们如何使用Compute着色器实现相同的功能?

1 个答案:

答案 0 :(得分:2)

计算着色器不对纹理做任何假设。

您的应用代码确定计算着色器在调度时运行的网格大小。网格是一个抽象的概念。它不必然与其他任何东西相关。这取决于你如何解释/赋予网格意义。

您在网格中的每个位置调用一次着色器,并且可以将该位置提供给着色器功能,因为您已使用gid参数进行了安排。

由于您编码的方式,您的着色器将位置解释为输入纹理中的坐标(因为您将其传递给read()函数)和输出中的坐标纹理(因为你将它传递给write()函数)。因此,就像当前编写的那样,着色器不会缩放图像。它假定输出纹理至少与输入一样大,它只是将输入复制到输出的左上部分。

如果要执行缩放,通常会使网格成为输出纹理的大小,因此您可以为其中的每个纹素计算一些内容。然后,您必须显式缩放位置以从输入纹理中的相应位置读取。实际上,如果你想要过滤,你需要对输入纹理进行采样,而不仅仅是读取。

要执行位置缩放,可以使用两个纹理的大小。