ARKit

ARKit教學:學習如何在實境加入一個虛擬3D物件

ARKit教學:學習如何在實境加入一個虛擬3D物件
ARKit教學:學習如何在實境加入一個虛擬3D物件
In: ARKit, Swift 程式語言

擁有一個很棒的視覺感受可以讓你的App有獨特的個化風格,在這個教學中,我們將會了解一個創造3D物件工具,與相關線上資源可以支援SceneKit格式的3D物件,最重要的是,學習如何使用SceneKit建立一個基本簡易的ARKit App。

事不宜遲,那我們先來試著在實境加入一些3D物件,我想應該會很有趣,我希望你將可以享受本篇教學,也感謝你分享本篇教學給予其他人了解。

當我們開始前,開發者還是需要一些基本知識,當然我們需要從之前的ARKit教學得到一些基礎知識,如果你是第一次碰觸ARKit,建議請先參考ARKit教學,來了解如何建立如何應用SceneKit來建立一個簡易的ARkit。

你將會學習到的功能

好的!我們將會一起學習到很多功能,以下項目將是本教學會教給你的,包含:

  • 簡單介紹3D物件的工具與資源
  • 如何實現一個單節點的3D物件
  • 如何加入一個基本亮度
  • 如何實現一個多節點的3D物件

如何建立或找到一個3D物件

要如何來建立或找到一個3D物件呢?請隨著腳步來看看我們如何建立或找到相關資源。

建立3D物件工具

sketchup

首先,你可以使用某些3D物件建立工具,來幫助你從無到有,建立屬於你的3D模型,或是,你也可以使用這些工具組已有的3D模型,並能支援SceneKit的檔案格式,我們等會會遇到更多的有關SceneKit支援格式的問題,如果你有計畫建立屬於你自己的3D物件,你可以參考下列這些工具:

3D物件相關線上資源

sketchfab

除了建立你自己的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裝置和下圖一樣的畫面:

arkit-1

請點選OK,你應該能夠看到你自己的相機畫面,下面就是當我用我的相機看到正在Apple store編寫程式的畫面:

arkit-2

實現一個單節點的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.scnSCNScene物件,這個檔案已先行建立在我給的範例開發程式中。

接著,我們同樣在guard let下執行初始化以paperPlane節點的SCNNode物件,我們也將recursively參數設為truerecursively的參數決定SceneKit是否要用前序搜尋法來找到子節點支幹。

所有場景的內容 – 包含節點、地理資訊與他們的素材、亮度、相機與其他相關物件都依序層級放在一個根節點內。

-Apple官方文件

一但這個節點初始化,我們來設定paperPlaneNode的方位,宣告xyz,初始方位設定皆為0,表示這個方位會放在和一開始父節點同樣的座標位置上,所以我會將z設為-0,5,代表此物件會在相機鏡頭的前方。

再來,我們將paperPlaneNode加到sceneViewrootNode,也就是根節點上。

現在在viewDidLoad()方法內來呼叫addPaperPlane(x:y:z:)這個方法:

override func viewDidLoad() {

    super.viewDidLoad()
    addPaperPlane()

}

建立並執行在你的裝置上,你將會看到一個白色的紙飛機!

arkit-paper-plane

此時,你會發現這個紙飛機有點看不清楚的感覺,這是因為缺少了亮度與陰影,在真實世界中,所有的事物都會有亮度與陰影組成,有了亮度與陰影,也造就了3D物件的視覺感受。

如果你從3D物件檔案夾打開paperPlane.scn,你可以看見紙飛機是全白色的,所以它自然就沒有很明顯的視覺深度。

xcode-paper-plane

所以來加點亮度在我們的紙飛機上吧!

加入基本亮度

其實加入亮度的方式不只一種,這個專案中,我們將使用打開自動亮度模式與自動亮度提升。

所以在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()
}

好極了!再次在你的裝置上建置與執行專案,你應該可以看見一個具有美麗的曲線、造型與明顯邊界的紙飛機了!

arkit-paperplane-light

此刻先靜下心來,來愛上這個具有美麗的曲線、造型與明顯邊界的紙飛機吧。

實現多節點的3D物件

有些3D物件檔案是含有多節點(Multiple Node)的特性,在這樣的情境下,來看看我們如何加入一個具多節點的3D物件在我們的ARSCNView。

在3D物件檔案夾內,有個car.dae的檔案,如果你點擊這個檔案,你會在Xcode Scene Editor打開這個檔案,你可以全部點選這個3D car物件的所有節點。

arkit-car-model

好的!現在請打開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()
}

再次建置並執行你的專案,你將會在你面前看到一台能漂浮在空中的車。

arkit-car

總結

恭喜你,能和我一起完成這個專案,希望你會喜歡這個專案。

為了能參考你做的功能是否有和我一樣,你也可以從GitHub下載完整專案

如果你想要學習更多有關ARKit的資訊,請分享給你朋友,並讓我知道。

譯者簡介:Oliver Chen-工程師,喜歡美麗的事物,所以也愛上Apple,目前在iOS程式設計上仍是新手,正研讀Swift與Sketch中。生活另一個身份是兩個孩子的爸,喜歡和孩子一起玩樂高,幻想著某天自己開發的App,可以讓孩子覺得老爸好棒!。聯絡方式:電郵[email protected]

原文ARKit Tutorial: Understanding and Implementing 3D Objects

作者
Jayven N
年輕、富創意的Jayven熱愛手機程式設計,善於發掘和凸顯不平凡處,透過文章抒發其獨特性。閒時喜歡做健身、看UFC。希望了解Jayven更多,可以到訪他的Medium平台或在LinkedIn跟他聯繫。
評論
更多來自 AppCoda 中文版
透過 Reality Composer 和 RealityKit 輕鬆地創建 3D AR Apps
ARKit

透過 Reality Composer 和 RealityKit 輕鬆地創建 3D AR Apps

RealityKit 是 2019 年推出的新框架,用於實作高性能 3D 模擬和渲染功能,而 Reality Composer 就讓初學者無需編寫任何程式碼,都可以輕鬆地創建互動的 AR 體驗。在這篇文章中,你將學會使用這兩個框架,構建互動的 3D AR App。
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。