Day 2 時開啟了雙版本的 AR 畫面,不過還是先打通其中一邊比較合理(?)。
先從 RealityView 來吧!
今天先請 AI 畫一張 3D 木質魔杖的 png 圖片,看看在 AR 中產生一個平面中放上圖片的樣子。
還蠻有質感的。
import SwiftUI
import RealityKit
import ARKit
@available(iOS 18.0, *)
struct RealityCameraView: View {
var body: some View {
RealityView { content in
content.camera = .spatialTracking
guard let uiImage = UIImage(named: "Wand.png"),
let texture = try? TextureResource.generate(from: uiImage.cgImage!, options: .init(semantic: .color)) else {
return
}
let mesh = MeshResource.generatePlane(width: 0.04, height: 0.25)
var material = SimpleMaterial()
material.color = .init(texture: .init(texture))
let entity = ModelEntity(mesh: mesh, materials: [material])
entity.components.set(BillboardComponent())
let anchor = AnchorEntity(.camera)
entity.position = [0, 0, -0.4]
anchor.addChild(entity)
content.add(anchor)
}
.ignoresSafeArea()
}
}
分段拆解:
guard let uiImage = UIImage(named: "Wand.png"),
let texture = try? TextureResource.generate(from: uiImage.cgImage!, options: .init(semantic: .color)) else {
return
}
這裡是將已放入 Assets.xcassets 的圖片 Wand.png 載入,在 RealityKit 的領域中,都要轉換為 TextureResource。
let mesh = MeshResource.generatePlane(width: 0.04, height: 0.25)
生成一片平面網格,注意這裡的單位是公尺。寬 4 公分、高 25 公分,當作魔杖的載體。
var material = SimpleMaterial()
material.color = .init(texture: .init(texture))
建立 SimpleMaterial,它會反應基本光照,並支援貼圖。
把上面的 texture 指定成顏色貼圖(Color)。
let entity = ModelEntity(mesh: mesh, materials: [material])
建立一個 3D 實體(RealityKit 物件)。
entity.components.set(BillboardComponent())
讓平面自動朝向相機。
let anchor = AnchorEntity(.camera)
entity.position = [0, 0, -0.4]
anchor.addChild(entity)
建立一個相機錨點,會固定跟著相機座標移動。
把魔杖放在相機前 40 公分(Z 軸負方向是鏡頭前方),並將魔杖掛到錨點之下。
試過大於 -40 公分,魔杖會變更大隻,如果 Z 軸為 0 則看不見魔杖。如果小於 -40 公分則魔杖越來越短。
content.add(anchor)
最後,把錨點(連同魔杖實體)加入 RealityView 的內容中。
目前鏡頭對著牆面的效果:
另外,會發現如果太貼近牆面,魔杖會被吃掉:
這是我將手機前傾,讓魔杖被吃掉一半的樣子。
position z 軸設定越小,則需要離牆面的距離越遠,才能讓魔杖出現。
下一回要找找看如何將魔杖自黑色平面中釋放。