如何将参数传递给 Metal CIWarpKernel?

How to pass arguments to Metal CIWarpKernel?

我有一个简单的金属 CIWarpKernel:

    float2 MyWarp(destination dest, float offset)
    {
        return float2(dest.coord().x + offset, dest.coord().y);
    }

和:

class MyWarpFilter : CIFilter
{
    var inputImage: CIImage?
    var inputOffset: Float = 100.0

    static var kernel: CIWarpKernel =
    { () -> CIWarpKernel in
        let url = Bundle.main.url(forResource: "MyWarp", withExtension: "ci.metallib")!
        let data = try! Data(contentsOf: url)
        return try! CIWarpKernel(functionName: "MyWarp", fromMetalLibraryData: data) <== ERROR
    }()

    override var outputImage : CIImage?
    {
        get
        {
            guard let input = inputImage else { return nil }

            let roiCallback: CIKernelROICallback =
            { _, rect -> CGRect in
                return CGRect(x: rect.minX, y: rect.minY, width: input.extent.width, height: input.extent.height)
            }

            let arguments: [Any] = [inputOffset]

            return MyWarpFilter.kernel.apply(extent: input.extent,
                                             roiCallback: roiCallback,
                                             image: input, arguments: arguments)
        }
    }
}

当我 运行 这样做时,我得到以下 运行 时间错误(在上面用 <== ERROR 指示的行):

Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Foundation._GenericObjCError.nilError

如果我删除第二个 MyWarp() 参数,运行 具有 arguments: [] 的过滤器并且具有硬编码的偏移量,则没有错误(并且过滤器通过偏移量平移图像).

将参数传递给 CIWarpKernel 我做错了什么?

运行 你的代码与 iOS Simulator 14.4/Xcode 12.4,我收到以下错误: (不确定我做错了什么或者这只是运行时版本的问题。)

Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=CIKernel Code=4 "(null)" UserInfo={CINonLocalizedDescriptionKey=If specified, destination must be the last parameter of a CIKernel function.}

所以,至少,你可能需要将参数 destination dest 移到最后:

    float2 MyWarp(float offset, destination dest)
    {
        return float2(dest.coord().x + offset, dest.coord().y);
    }

Metal Shading Language for Core Image Kernels

destination A kernel parameter type that allows access to the position of the pixel currently being computed. This parameter, which is required for CIWarpKernel and optional for CIColorKernel and CIKernel, must be the last parameter to a kernel function.