ios - 如何使用 Metal 自定义计算着色器并获得非常流畅的性能?

标签 ios swift metal metal-performance-shaders

我正在尝试使用苹果提供的默认 MPSKernal 滤镜和自定义 compute Shaders 通过 Metal 应用实时相机滤镜。

在计算着色器中,我使用 MPSImageGaussianBlur 进行了就地编码 代码在这里

func encode(to commandBuffer: MTLCommandBuffer, sourceTexture: MTLTexture, destinationTexture: MTLTexture, cropRect: MTLRegion = MTLRegion.init(), offset : CGPoint) {

    let blur = MPSImageGaussianBlur(device: device, sigma: 0)
    blur.clipRect = cropRect
    blur.offset = MPSOffset(x: Int(offset.x), y: Int(offset.y), z: 0)

    let threadsPerThreadgroup = MTLSizeMake(4, 4, 1)
    let threadgroupsPerGrid = MTLSizeMake(sourceTexture.width / threadsPerThreadgroup.width, sourceTexture.height / threadsPerThreadgroup.height, 1)

    let commandEncoder = commandBuffer.makeComputeCommandEncoder()
    commandEncoder.setComputePipelineState(pipelineState!)
    commandEncoder.setTexture(sourceTexture, at: 0)
    commandEncoder.setTexture(destinationTexture, at: 1)

    commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup)

    commandEncoder.endEncoding()

    autoreleasepool {
        var inPlaceTexture = destinationTexture
        blur.encode(commandBuffer: commandBuffer, inPlaceTexture: &inPlaceTexture, fallbackCopyAllocator: nil)
    }
}

但有时就地纹理往往会失败,最终会在屏幕上产生 SCSS 效果

因此,如果有人可以在不使用就地纹理或如何使用 fallbackCopyAllocator 或以不同方式使用 compute shaders 的情况下向我建议解决方案,那将非常有帮助.

最佳答案

我在这方面做了足够的编码(将计算着色器应用于来自相机的视频流),您遇到的最常见问题是“像素缓冲区重用”问题。

您从样本缓冲区创建的 Metal 纹理备份到一个像素缓冲区,该缓冲区由视频 session 管理,并且可以重新用于后续视频帧,除非您保留对样本缓冲区的引用(保留仅提及 Metal 质感是不够的)。

请随时查看我的代码 https://github.com/snakajima/vs-metal ,它将各种计算着色器应用于实时视频流。

VSContext:set() 方法除了纹理参数外还接受可选的 sampleBuffer 参数,并保留对 sampleBuffer 的引用,直到计算着色器的计算完成(在 VSRuntime:encode() 方法中)。

关于ios - 如何使用 Metal 自定义计算着色器并获得非常流畅的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45214852/

相关文章:

iphone - ios - 我可以使用来自另一个 ViewController 的 IBAction 吗?

ios - Swift - 在重复循环中使用闭包

ios - 如何用swift制作单选按钮?

ios - 以相同的 Alpha 混合 Metal

swift - 不支持的架构 - Metal 和 Swift 之间的共享枚举

ios - SceneKit - 在不使用单独的 SCNRenderer 的情况下从 SCNView 获取渲染场景作为 MTLTexture

ios - 将 UIGestureRecognizer 初始化为 Swift 中属性定义的一部分?

ios - 带有 Facebook iOS SDK 的 OAuth2 授权码

ios - 使用 accessoryView 为 UITableViewCell 的 backgroundColor 设置动画

ios - 在 WKWebView 中显示 'Use camera' 选项