擁有一個很棒的視覺感受可以讓你的App有獨特的個化風格,在這個教學中,我們將會了解一個創造3D物件工具,與相關線上資源可以支援SceneKit格式的3D物件,最重要的是,學習如何使用SceneKit建立一個基本簡易的ARKit App。
事不宜遲,那我們先來試著在實境加入一些3D物件,我想應該會很有趣,我希望你將可以享受本篇教學,也感謝你分享本篇教學給予其他人了解。
當我們開始前,開發者還是需要一些基本知識,當然我們需要從之前的ARKit教學得到一些基礎知識,如果你是第一次碰觸ARKit,建議請先參考ARKit教學,來了解如何建立如何應用SceneKit來建立一個簡易的ARkit。
你將會學習到的功能
好的!我們將會一起學習到很多功能,以下項目將是本教學會教給你的,包含:
- 簡單介紹3D物件的工具與資源
- 如何實現一個單節點的3D物件
- 如何加入一個基本亮度
- 如何實現一個多節點的3D物件
如何建立或找到一個3D物件
要如何來建立或找到一個3D物件呢?請隨著腳步來看看我們如何建立或找到相關資源。
建立3D物件工具
首先,你可以使用某些3D物件建立工具,來幫助你從無到有,建立屬於你的3D模型,或是,你也可以使用這些工具組已有的3D模型,並能支援SceneKit的檔案格式,我們等會會遇到更多的有關SceneKit支援格式的問題,如果你有計畫建立屬於你自己的3D物件,你可以參考下列這些工具:
3D物件相關線上資源
除了建立你自己的3D物件外,你也許會使用一些需能立即選用或得付費的3D模型放在你的ARKit App中,這兒有些線上資源應該對你有些幫助:
可支援SceneKit格式
我們會使用SceneKit來建立ARKit App。為了能在ARKit App上讀取3D物件,理所當然地,你的3D物件檔案格式必須支援SceneKit,這樣Xocde才能讀懂你的物件。
SceneKit需在能支援的格式下才能讀取場景內容,或是能支援NSData物件的檔案
Apple官方說明
在本篇教學中,我們將會使用SceneKit Scene (.scn) 和Digital Asset Exchange (.dae)檔案支援格式在SceneKit上。
從範例專案開始
首先,請先下載範例專案,我已建立這個App的基本架構並加入兩個3D檔案,所以我們更可以專注在ARkit的開發,一旦下載後,請打開Xcode,並先執行測試一下。
你應該可以在你的iOS裝置和下圖一樣的畫面:
請點選OK,你應該能夠看到你自己的相機畫面,下面就是當我用我的相機看到正在Apple store編寫程式的畫面:
實現一個單節點的3D物件
太棒了!是時候來添加一個單節點的3D物件到我們的ARSCNView,插入下列方法到ViewController
的類別中:
func addPaperPlane(x: Float = 0, y: Float = 0, z: Float = -0.5) { guard let paperPlaneScene = SCNScene(named: "paperPlane.scn"), let paperPlaneNode = paperPlaneScene.rootNode.childNode(withName: "paperPlane", recursively: true) else { return } paperPlaneNode.position = SCNVector3(x, y, z) sceneView.scene.rootNode.addChildNode(paperPlaneNode) }
在上述的程式碼中,我們利用guard let
語法來安全執行來初始化以一個paperPlane.scn的SCNScene物件,這個檔案已先行建立在我給的範例開發程式中。
接著,我們同樣在guard let
下執行初始化以paperPlane節點的SCNNode物件,我們也將recursively
參數設為true
,recursively
的參數決定SceneKit是否要用前序搜尋法來找到子節點支幹。
所有場景的內容 – 包含節點、地理資訊與他們的素材、亮度、相機與其他相關物件都依序層級放在一個根節點內。
-Apple官方文件
一但這個節點初始化,我們來設定paperPlaneNode
的方位,宣告x
、y
與z
,初始方位設定皆為0,表示這個方位會放在和一開始父節點同樣的座標位置上,所以我會將z
設為-0,5
,代表此物件會在相機鏡頭的前方。
再來,我們將paperPlaneNode
加到sceneView
的rootNode
,也就是根節點上。
現在在viewDidLoad()
方法內來呼叫addPaperPlane(x:y:z:)
這個方法:
override func viewDidLoad() { super.viewDidLoad() addPaperPlane() }
建立並執行在你的裝置上,你將會看到一個白色的紙飛機!
此時,你會發現這個紙飛機有點看不清楚的感覺,這是因為缺少了亮度與陰影,在真實世界中,所有的事物都會有亮度與陰影組成,有了亮度與陰影,也造就了3D物件的視覺感受。
如果你從3D物件檔案夾打開paperPlane.scn,你可以看見紙飛機是全白色的,所以它自然就沒有很明顯的視覺深度。
所以來加點亮度在我們的紙飛機上吧!
加入基本亮度
其實加入亮度的方式不只一種,這個專案中,我們將使用打開自動亮度模式與自動亮度提升。
所以在ViewController
的類別內,加入下列方法:
func configureLighting() { sceneView.autoenablesDefaultLighting = true sceneView.automaticallyUpdatesLighting = true }
酷!我們剛做了:
- 一個
configureLighting()
的方法 - 在這個方法內,我們將
sceneView
的屬性autoenablesDefaultLighting
設定為true
,如果autoenablesDefaultLighting
設定為true
,SceneKit將自動地增加亮度到這個場景中,技術上而言,SceneKit會感知所使用的場景沒有亮度或是僅有些自有周圍亮度時,將會開啟全向光源。 - 下一步,我們將
sceneView
的屬性automaticallyUpdatesLighting
設定為true
,如果將automaticallyUpdatesLighting
設定為true
,這個屬性會自動從相機場景感知計算所需要的光度,若你想要自己控制亮度,你就得將此屬性設為false
。
現在我們把configureLighting()
的方法嵌入viewDidLoad
的方法內:
override func viewDidLoad() { super.viewDidLoad() configureLighting() addPaperPlane() }
好極了!再次在你的裝置上建置與執行專案,你應該可以看見一個具有美麗的曲線、造型與明顯邊界的紙飛機了!
此刻先靜下心來,來愛上這個具有美麗的曲線、造型與明顯邊界的紙飛機吧。
實現多節點的3D物件
有些3D物件檔案是含有多節點(Multiple Node)的特性,在這樣的情境下,來看看我們如何加入一個具多節點的3D物件在我們的ARSCNView。
在3D物件檔案夾內,有個car.dae的檔案,如果你點擊這個檔案,你會在Xcode Scene Editor打開這個檔案,你可以全部點選這個3D car物件的所有節點。
好的!現在請打開ViewController.swift
,插入下列的程式碼在addPaperPlane(x:y:z:)
的方法下:
func addCar(x: Float = 0, y: Float = 0, z: Float = -0.5) { guard let carScene = SCNScene(named: "car.dae") else { return } let carNode = SCNNode() let carSceneChildNodes = carScene.rootNode.childNodes for childNode in carSceneChildNodes { carNode.addChildNode(childNode) } carNode.position = SCNVector3(x, y, z) carNode.scale = SCNVector3(0.5, 0.5, 0.5) sceneView.scene.rootNode.addChildNode(carNode) }
在上述程式碼中,我們做了:
- 首先,我們建立一個以
car.dae
檔案的SCNScene物件,並使用guard let
安全語法描述,然後我們初始化一個SCNNode物件,叫做carNode
。 - 接著,我們先設定一個
carSceneChildNodes
的變數來儲存所有在carScene根節點下的子節點,過來,我們搜尋並加入carScene下所有的子節點,並加到carNode的子節點。 - 然後,我們設定CarNode的方位,CarNode的x、y和z資訊,將由
addCar
的宣告變數設定,然後我們設定縮放比例,皆為0.5。 - 最後我們將CarNode加入在SceneView的根節點。
現在先註解原有的addPaperPlane()
方法,並加入addCar()
方法於viewDidLoad()
方法內:
override func viewDidLoad() { super.viewDidLoad() configureLighting() //addPaperPlane() addCar() }
再次建置並執行你的專案,你將會在你面前看到一台能漂浮在空中的車。
總結
恭喜你,能和我一起完成這個專案,希望你會喜歡這個專案。
為了能參考你做的功能是否有和我一樣,你也可以從GitHub下載完整專案。
如果你想要學習更多有關ARKit的資訊,請分享給你朋友,並讓我知道。
原文:ARKit Tutorial: Understanding and Implementing 3D Objects