SceneKit | 加載 3D模型(obj/scn/dae)到你的AR項(xiàng)目中

本文主要講解如何加載一些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是模型上的貼紙!

image.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)
    }
    

效果如下:

image.png

2.2 從加載obj文件中加載3D模型

現(xiàn)在我們用obj格式的素材,步驟還是一樣啄刹,先導(dǎo)入原材料到項(xiàng)目中涮坐。

image.png

理論上講,我們只要將上面加載模型的代碼稍微改動(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)果然是黑乎乎的:

image.png

額。盹廷。征绸。

明明是一份3D文件久橙,只是不同格式導(dǎo)出俄占,怎么有如此差異管怠??

莫慌缸榄,一般來(lái)說(shuō)渤弛,這種看不清的情況大都是由于light造成的,我們?cè)囍砑右粋€(gè)light試一下甚带,選擇一個(gè)Omni light添加到editor中她肯。

image.png
image.png

此時(shí)發(fā)現(xiàn),小人變亮了鹰贵,但是身上貌似沒(méi)有貼紙晴氨。怎么辦?碉输?籽前?

這種材質(zhì)沒(méi)有加載出來(lái)的情況,去查看一下Diffuse敷钾,選擇一個(gè)Diffuse試一下枝哄,然鵝,選了還是不行阻荒,預(yù)覽并沒(méi)有按照我們預(yù)期出來(lái)挠锥。

image.png

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)化工具,如下方法使用:

image.png

點(diǎn)擊選擇之后鲫售,會(huì)彈出一個(gè)彈窗共螺,現(xiàn)在convert:

image.png

轉(zhuǎn)化之后,我們發(fā)現(xiàn) .obj 格式的文件已經(jīng)轉(zhuǎn)化成.scn格式的文件了情竹。

image.png

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)行一下,效果如下:

image.png

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),歡迎和我溝通指正生棍。

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颤霎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涂滴,更是在濱河造成了極大的恐慌友酱,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柔纵,死亡現(xiàn)場(chǎng)離奇詭異缔杉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)搁料,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)或详,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)系羞,“玉大人,你說(shuō)我怎么就攤上這事霸琴〗氛瘢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵沈贝,是天一觀的道長(zhǎng)杠人。 經(jīng)常有香客問(wèn)我勋乾,道長(zhǎng)宋下,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任辑莫,我火速辦了婚禮学歧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘各吨。我一直安慰自己枝笨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布揭蜒。 她就那樣靜靜地躺著横浑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屉更。 梳的紋絲不亂的頭發(fā)上徙融,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音瑰谜,去河邊找鬼欺冀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛萨脑,可吹牛的內(nèi)容都是我干的隐轩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼渤早,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼职车!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起鹊杖,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悴灵,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后仅淑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體称勋,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年涯竟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赡鲜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片空厌。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖银酬,靈堂內(nèi)的尸體忽然破棺而出嘲更,到底是詐尸還是另有隱情,我是刑警寧澤揩瞪,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布赋朦,位于F島的核電站,受9級(jí)特大地震影響李破,放射性物質(zhì)發(fā)生泄漏宠哄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一嗤攻、第九天 我趴在偏房一處隱蔽的房頂上張望毛嫉。 院中可真熱鬧,春花似錦妇菱、人聲如沸承粤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辛臊。三九已至,卻和暖如春房交,著一層夾襖步出監(jiān)牢的瞬間彻舰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工涌萤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淹遵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓负溪,卻偏偏與公主長(zhǎng)得像透揣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子川抡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容