我尝试使用 clipRect
和 offset
属性使用Apple提供的默认过滤器裁剪 MTLTexture
,它可以与实时视频过滤一起使用 .
但是对于自定义过滤器(使用 custom shaders
),属性 clipRect
和 offset
对裁剪 MTLTexture
无效,我尝试使用 MPSImageLanczosScale
引用Crop and scale MTLTexture进行裁剪 .
func encodeWithTransform(to commandBuffer: MTLCommandBuffer, sourceTexture: MTLTexture, destinationTexture: MTLTexture, transform: MPSScaleTransform) {
var newTransform = transform
withUnsafePointer(to: &newTransform) { (transformPtr: UnsafePointer<MPSScaleTransform>) -> () in
lanczosScaleFilter.scaleTransform = transformPtr
lanczosScaleFilter.encode(commandBuffer: commandBuffer, sourceTexture: sourceTexture, destinationTexture: newCroppingTexture)
self.imageFilter.encode(to: commandBuffer!, sourceTexture: newCroppingTexture, destinationTexture: destinationTexture, cropRect: MTLRegionMake2D(0, 0, Int(uiscreenWidth) / 4, sourceTexture.height), offset : CGPoint(x: 0 / scale, y:0))
}
}
正如你在这里看到的那样,我们正在尝试裁剪纹理,然后对过滤器进行编码,这是一个双向操作,过程非常慢 .
但是如果应用过滤器而没有裁剪纹理,则性能非常平滑 . 编码方法如下所示 .
blur.clipRect = cropRect
blur.offset = MPSOffset(x: Int(offset.x), y: Int(offset.y), z: 0)
let threadsPerThreadgroup = MTLSizeMake(10, 10, 1)
let threadgroupsPerGrid = MTLSizeMake(destinationTexture.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)
}
无需使用模糊滤镜进行编码 . 但我添加了这个跳跃,它将使用 clipRect
和 offset
属性进行裁剪,但没有运气 .
因此,如果有人有更好的解决方案,可能会修改自定义着色器方法中的纹理rect,这将有所帮助 . 此外,如果有人会建议我苹果如何使用 clipRect
和 offset
属性来帮助我 .