本系列文章是對 metalkit.org 上面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)
![mps_1.png](https://i.iter01.com/images/c56c728d107ea7b701e179d465ad64b57f666377ab9d47b570296eb2c83eb39d.png)
讓我們看一下這些程式碼.在以前的文章中我們已經一遍遍寫過類似的程式碼.你應該立刻注意到新新增的程式碼引起了一個錯誤,這是因為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檔案複製到這個資料夾:
![mps_8.png](https://i.iter01.com/images/2eca63dc57ab37424ceed20d6afdb035d44f42d9ef04ffc3abe84031960f1264.png)
我們終於開始用上iPad了!開啟新的Playground
應用來到My Playgrounds
.在螢幕左上角點選 + 按鈕.可以看出來,你也可能在iPad
上建立一個新的playground並可以輕易用其它方式共享輸出到你的macOS
裝置上.但是現在,我們點選iCloud Drive
如下圖:
![mps_2.png](https://i.iter01.com/images/72fec3c21c9c2a0958b61036588d65ef01c085c0a14cc84a4655167ffffb6aa6.png)
當iCloud Drive
視窗彈出後,請注意我們已經進入了iPad
為playground提供的私有資料夾,我們現在想要匯入我們用到的MPS.playground,點選它:
![mps_3.png](https://i.iter01.com/images/dd1fa4fc05ce19958d79b5115c8435f90faba2899a13e1cda646f7211ebac1b0.png)
當iPad載入守playground後,我們就開工了!現在你能在你的iPad
上看到playground的主頁面了:
![mps_4.png](https://i.iter01.com/images/c1e5852955b8df66b8f2a8facb0892d3046cd2b6980dc9fdd34a12aae07c694d.png)
你所要做的就是點選Run My Code
,就能看到我們圖片已經帶上了一個漂亮的模糊濾鏡:
![mps_5.png](https://i.iter01.com/images/140a5adf632a1937b72eef1a6c0705532af8c2f7e522da99642a434d024bb7b3.png)
你可能會說:"我怎麼才能看到整個圖片呢?"答案就在下面的GIF圖片中.只要簡單地在螢幕中間長按,直到出現螢幕分隔線.不要鬆手指,想看程式碼或輸出圖片就左右拖動分隔線(你可能想要重新載入這個頁面因為這個動態GIF只會播放一次):
![mps_6.gif](https://i.iter01.com/images/b3d5940d04fda8a5c2978eb2a72d0589b2ec0ab9eb76ce03c510584594976d67.gif)
現在你能看到整個模糊過的圖片了!欣賞過圖片後,點選螢幕左側的按鈕來返回分屏狀態.在我們把它收起來之前,再來點牛逼效果.將下面這行:
let shader = MPSImageGaussianBlur(device: view.device!, sigma: 5)
複製程式碼
替換為
let shader = MPSImageSobel(device: device)
複製程式碼
檢視輸出的新圖片:
![mps_7.PNG](https://i.iter01.com/images/ef1380092c074f9e5bc9728676297b3640c40fc8ef809a3e24a14e7fc85e34b3.png)
我們只是改動了一行程式碼就產生如此不同的效果!還有幾十種不同的著色器來供你嘗試.檢視 Metal Performance Shaders API來獲取更多資訊.如果你對影象處理有興趣,你也許會想要檢視Simon Gladman的 Core Image for Swift這本書.如果你想要學更多MPS
後端的Metal
,可以檢視Moore的 Metal by Example這本書.
原始碼source code 已釋出在Github上.
下次見!