本系列文章是對 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)
讓我們看一下這些程式碼.在以前的文章中我們已經一遍遍寫過類似的程式碼.你應該立刻注意到新新增的程式碼引起了一個錯誤,這是因為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上.
下次見!