本文主要講解如何加載一些3D模型到AR項(xiàng)目中去。
0. 寫(xiě)在前面
本文分三節(jié)內(nèi)容:
- 第一節(jié)會(huì)介紹與之相關(guān)的一些基本概念紧显;
- 第二節(jié)講述如何具體實(shí)施;
- 第三節(jié)小結(jié)缕棵。
本文開(kāi)發(fā)環(huán)境如下:
- Xcode Version 9.4 beta
- iPhone X iOS 11.4 beta
本文會(huì)完成一個(gè)Demo孵班,放在GitHub上面。
1. 相關(guān)的概念
1.1 scene 和 node
新建基于SceneKit的AR project時(shí)候招驴,系統(tǒng)默認(rèn)生成一個(gè)ship.scn
文件篙程,這個(gè)文件就是一個(gè) scene(場(chǎng)景)文件,在這個(gè)文件中别厘,ship是其中的一個(gè)node虱饿,3D模型必須“附著”在node上才能被呈現(xiàn)。
在之前的文章《iOS AR開(kāi)發(fā)基礎(chǔ)02 | ARKit開(kāi)發(fā)基本套路和核心API》中有講到相關(guān)概念,如果還有對(duì)這個(gè)概念模糊的話氮发,請(qǐng)移步去翻閱渴肉。
1.2 SCNReferenceNode類
如果你對(duì)SCNReferenceNode類不熟悉的話,可以先看iOS 11 SceneKit開(kāi)發(fā)教程03 | 使用SCNNode && SCNReferenceNode定義場(chǎng)景結(jié)構(gòu) 第三節(jié)的內(nèi)容爽冕。
刪除viewDidLoad
中加載 ship.scn 文件的代碼仇祭,然后開(kāi)始擼我們自己的工程。
2.1 從加載dae文件中加載3D模型
項(xiàng)目中用到的資源放在 resource.zip 壓縮包中颈畸。
將資源文件添加到project中來(lái)乌奇,資源文件中包含,三個(gè)文件承冰,其中dea文件是模型华弓,另外兩個(gè)png是模型上的貼紙!
新建一個(gè)類 BadyGrootNode
類困乒,繼承自SCNNode寂屏,這個(gè)node用來(lái)“附著”3D模型。
實(shí)現(xiàn)思路是實(shí)例化一個(gè)SCNReferenceNode
,用來(lái)加載dae文件中的內(nèi)容娜搂,然后這個(gè) reference node 作為子node添加到BadyGrootNode
上迁霎,返回BadyGrootNode
實(shí)例。
給這個(gè)類添加init方法:
override init(){
super.init()
guard let url = Bundle.main.url(forResource: "baby_groot", withExtension: "dae") else {
fatalError("baby_groot.dae not exit.")
}
guard let customNode = SCNReferenceNode(url: url) else {
fatalError("load baby_groot error.")
}
customNode.load()
self.addChildNode(customNode)
}
在里面就用到了1.2節(jié)中提到的兩個(gè)方法0儆睢考廉!
然后在實(shí)現(xiàn)ARSCNViewDelegate
方法,當(dāng)系統(tǒng)檢測(cè)到水平面之后携御,將這個(gè)BadyGrootNode
實(shí)例添加到平面anchor上昌粤。
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard anchor is ARPlaneAnchor else { return }
print("-----------------------> session did add anchor!")
node.addChildNode(customNode)
}
效果如下:
2.2 從加載obj文件中加載3D模型
現(xiàn)在我們用obj格式的素材,步驟還是一樣啄刹,先導(dǎo)入原材料到項(xiàng)目中涮坐。
理論上講,我們只要將上面加載模型的代碼稍微改動(dòng)一下誓军,就可以直接將我們obj格式的模型加載出來(lái)袱讹。
// guard let url = Bundle.main.url(forResource: "baby_groot", withExtension: "dae") else {
// fatalError("baby_groot.dae not exit.")
// }
guard let url = Bundle.main.url(forResource: "baby_groot", withExtension: "obj") else {
fatalError("baby_groot.obj not exit.")
}
好,改完run一把發(fā)現(xiàn)昵时,小人是加載出來(lái)了捷雕,但是黑乎乎的,看不清楚壹甥。
此時(shí)我們?cè)趕cene editor中預(yù)覽我們的模型文件救巷,發(fā)現(xiàn)果然是黑乎乎的:
額。盹廷。征绸。
明明是一份3D文件久橙,只是不同格式導(dǎo)出俄占,怎么有如此差異管怠??
莫慌缸榄,一般來(lái)說(shuō)渤弛,這種看不清的情況大都是由于light造成的,我們?cè)囍砑右粋€(gè)light試一下甚带,選擇一個(gè)Omni light添加到editor中她肯。
此時(shí)發(fā)現(xiàn),小人變亮了鹰贵,但是身上貌似沒(méi)有貼紙晴氨。怎么辦?碉输?籽前?
這種材質(zhì)沒(méi)有加載出來(lái)的情況,去查看一下Diffuse敷钾,選擇一個(gè)Diffuse試一下枝哄,然鵝,選了還是不行阻荒,預(yù)覽并沒(méi)有按照我們預(yù)期出來(lái)挠锥。
run我們的項(xiàng)目,和預(yù)期一樣侨赡,出現(xiàn)的小人沒(méi)有貼紙蓖租。
此時(shí),我做了以下假設(shè)羊壹,SceneKit在對(duì).obj格式的文件加載兼容性不好蓖宦。(此假設(shè)純屬個(gè)人推論,沒(méi)有官方依據(jù)舶掖,酌情接受)
兼容性不好怎么辦球昨?那就轉(zhuǎn)化成兼容性好的唄,比如說(shuō)dae眨攘,比如說(shuō)scn主慰。
Xcode為我們提供了轉(zhuǎn)化工具,如下方法使用:
點(diǎn)擊選擇之后鲫售,會(huì)彈出一個(gè)彈窗共螺,現(xiàn)在convert:
轉(zhuǎn)化之后,我們發(fā)現(xiàn) .obj 格式的文件已經(jīng)轉(zhuǎn)化成.scn格式的文件了情竹。
2.3 從加載scn文件中加載3D模型
此時(shí)藐不,我們只要將BadyGrootNode
中的init方法稍作改動(dòng)就可以完成scn文件的加載:
// guard let url = Bundle.main.url(forResource: "baby_groot", withExtension: "dae") else {
// fatalError("baby_groot.dae not exit.")
// }
guard let url = Bundle.main.url(forResource: "baby_groot", withExtension: "scn") else {
fatalError("baby_groot.scn not exit.")
}
運(yùn)行一下,效果如下:
2.4 擴(kuò)展
總結(jié)前面的內(nèi)容,有以下幾點(diǎn)需要說(shuō)明:
- 我們發(fā)現(xiàn)2.3加載出來(lái)的模型2.1加載出來(lái)的模型大很多雏蛮,可以通過(guò)調(diào)節(jié)node的scale來(lái)使其變小涎嚼,此處也不做詳細(xì)講述;
- 2.3加載出來(lái)的模型燈光看著比較亮挑秉,不柔和法梯,這是因?yàn)槲抑患恿艘粋€(gè)燈,具體的燈光設(shè)計(jì)不屬于本文的范疇犀概,此處也不做詳細(xì)講述立哑;
- 3D文件還有很多格式,此處不一一列舉實(shí)驗(yàn)了姻灶,有需求的小伙伴可以按照上面的思路自己嘗試铛绰。
另外,由于scn格式文件是scene editor直接可用的产喉,還有其他思路可以從scn文件中加載node捂掰,比如:
- 先通過(guò)
SCNScene(named: "baby_groot.scn")!
取到scene - 然后在通過(guò)遍歷sceneView.scene.rootNode.childNodes的方式,獲取你需要的node
這種方式靈活性更高镊叁,你可以在開(kāi)發(fā)中按需選擇不同的方式3就恰!晦譬!
所以此時(shí)疤苹,我們?cè)倩乜次覀兊?.1小節(jié),我們可以在一開(kāi)始就把dae轉(zhuǎn)化成為scn文件敛腌。
推薦一個(gè)下載3D模型的網(wǎng)站Free 3D Models卧土,可以在上面下載很多好玩的3D模型。
3. 小結(jié)
本文講述了如何加載自定義的3D模型到你的AR項(xiàng)目中像樊,希望可以對(duì)你的思路有所啟發(fā)尤莺。
如果您對(duì)文中內(nèi)容有疑問(wèn),歡迎和我溝通指正生棍。