本系列文章是对 http://metalkit.org 上面MetalKit内容的全面翻译和学习.
MetalKit系统文章目录
可能大家已经在WWDC2016
上看过了,新的 Playground app for the iPad真是个震撼的产品!作为一个playground爱好者,我更是深感如此.现在我们可以轻易地在iPad上写Swift
代码,只要点击一个按钮就能运行.今天我们将要试试Metal Performance Shaders (MPS),因为它在移动设备上很好用而我们以前又没有讨论过它.需要提醒的是,MPS
框架只能在iOS
和tvOS
上工作.我们会用一个便捷的方法,在macOS
设备的playground上编写代码然后通过iCloud Drive
来分享到你的移动设备上.还有,iPad
的playground只能在iOS10
以上运行.
让我们在Xcode
中创建一个新的iOS
playground.你可以在Resources
文件夹下添加任意图片.我已经添加了一张名为nature.jpg.下一步,在playground主页面中写几行代码,如下面截图(代码在文末Github)
让我们看一下这些代码.在以前的文章中我们已经一遍遍写过类似的代码.你应该立刻注意到新添加的代码引起了一个错误,这是因为macOS
不"认识"MPS
框架.一旦我们在iPad中打开后,错误就会消失:
import MetalPerformanceShaders
下一步,我们用MTKTextureLoader
从先前添加图片处创建一个新的纹理.现在最有意思的部分来了!一旦我们创建MTLCommandBuffer
对象,我们将不会像以前做的那样从这个命令缓冲器创建MTLCommandEncoder
对象.相反,我们创建一个新的MPSImageGaussianBlur
对象,如下面的代码:
let shader = MPSImageGaussianBlur(device: view.device!, sigma: 5)
shader.encode(commandBuffer: commandBuffer, sourceTexture: texIn, destinationTexture: texOut)
MPS
对象最棒的地方在于,它让你可以将一个计算着色器(内核函数)应用于输入纹理,而无需配置任何状态,描述符,管线或写个内核函数!MPS
对象会为我们处理好所有事情.当然,用这个便捷方法的话,我们也只能采用预设的着色器,并只能更改这个特殊着色器的sigma之类的参数.
目前为止还不错!我们已经通过iCloud Drive
把playground发送到了iPad
上.打开Finder
窗口,点击iCloud Drive
并把playground文件复制到这个文件夹:
我们终于开始用上iPad了!打开新的Playground
应用来到My Playgrounds
.在屏幕左上角点击+按钮.可以看出来,你也可能在iPad
上创建一个新的playground并可以轻易用其它方式共享输出到你的macOS
设备上.但是现在,我们点击iCloud Drive
如下图:
当iCloud Drive
窗口弹出后,请注意我们已经进入了iPad
为playground提供的私有文件夹,我们现在想要导入我们用到的MPS.playground,点击它:
当iPad加载守playground后,我们就开工了!现在你能在你的iPad
上看到playground的主页面了:
你所要做的就是点击Run My Code
,就能看到我们图片已经带上了一个漂亮的模糊滤镜:
你可能会说:"我怎么才能看到整个图片呢?"答案就在下面的GIF图片中.只要简单地在屏幕中间长按,直到出现屏幕分隔线.不要松手指,想看代码或输出图片就左右拖动分隔线(你可能想要重新载入这个页面因为这个动态GIF只会播放一次):
现在你能看到整个模糊过的图片了!欣赏过图片后,点击屏幕左侧的按钮来返回分屏状态.在我们把它收起来之前,再来点牛逼效果.将下面这行:
let shader = MPSImageGaussianBlur(device: view.device!, sigma: 5)
替换为
let shader = MPSImageSobel(device: device)
查看输出的新图片:
我们只是改动了一行代码就产生如此不同的效果!还有几十种不同的着色器来供你尝试.查看 Metal Performance Shaders API来获取更多信息.如果你对图像处理有兴趣,你也许会想要查看Simon Gladman的 Core Image for Swift这本书.如果你想要学更多MPS
后端的Metal
,可以查看Moore的 Metal by Example这本书.
源代码source code 已发布在Github上.
下次见!