Im essayant d'appliquer les filtres de caméra en direct à travers le métal en utilisant les filtres par défaut MPSKernal
donnés par Apple et la coutume compute Shaders
.Comment utiliser un shader de calcul personnalisé en utilisant du métal et obtenir une performance très lisse?
Dans shader Compute j'ai fait l'encodage inplace avec le MPSImageGaussianBlur et le code va ici
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)
}
}
Mais parfois, la texture inplace ont tendance à échouer et finalement il crée un effet de secousse sur l'écran.
Donc, si quelqu'un peut me suggérer la solution sans utiliser la texture inplace ou comment utiliser le fallbackCopyAllocator
ou en utilisant le compute shaders
d'une manière différente qui serait vraiment utile.
Pourquoi vous codant pour la 'blur' que vous appelez _after_' endEncoding() 'sur le codeur de commande? –
@MatthijsHollemans j'ai utilisé encodeur de commande pour coder l'état du pipeline au GPU un langage compréhensible. Ceci est fait en créant le ** MTLLibrary ** et en créant une fonction, puis en créant un état de pipeline à encoder vers le ** encodeur de commande **. Et le but de l'encodeur de commande est de définir l'état du processus (dans ce cas, coder le shader de calcul vers le GPU). Une fois l'encodage terminé, dites au GPU qu'il est prêt à l'encoder sur le GPU. Merci. En attente de suggestions –
Mon mauvais, j'ai mal interprété votre code. –