今回の記事は3Dオブジェクトの表面に色や画像を貼り付けたりする方法に関してご紹介します。
3Dオブジェクトの表面情報について
まず、3Dオブジェクトの表面に色をつける際に3Dオブジェクトに関しても理解しておく必要があると思います。
簡単に説明すると、ARkitでは3Dオブジェクトを「SCNNode」というもので構成します。この「SCNNode」は「表面情報(SCNMaterial)」と「表示形式(SCNTextとかSCNBoxなど)」いうクラスを持っており、この「SCNMaterial」を操作することで表面情報を付与することができます。
簡単に「SCNText」の表示形式の定義と表面の色情報を付与した上で、「SCNNode」を作成するコードを書いてみます。ちなみにSCNTextは空間内に文字をかける形式です。
3Dオブジェクトの表面に色付け
文字の表面に色をつける
let depth:CGFloat = 0.01 // 奥行き00.1m
let text = SCNText(string: "テスト", extrusionDepth: depth)
text.font = UIFont.systemFont(ofSize: 0.5)
let m1 = SCNMaterial()
m1.diffuse.contents = UIColor.red // 前面に赤色
text.firstMaterial = m1
let Node = SCNNode(geometry: text)
ちなみに上記では前面の色しか指定できていませんが「SCNText」では下記の書き方で前面・背面などいくつもの表面情報を付与することも可能です。
let depth:CGFloat = 0.01 // 奥行き0.01m
let text = SCNText(string: "テスト", extrusionDepth: depth)
text.font = UIFont.systemFont(ofSize: 0.5)
let m1 = SCNMaterial()
m1.diffuse.contents = UIColor.red // 前面に赤色
let m2 = SCNMaterial()
m2.diffuse.contents = UIColor.green // 背面に緑色
let m3 = SCNMaterial()
m3.diffuse.contents = UIColor.blue // 側面に青色
let m4 = SCNMaterial()
m4.diffuse.contents = UIColor.yellow // 前面粗さ
let m5 = SCNMaterial()
m5.diffuse.contents = UIColor.yellow // 背面粗さ
text.materials = [m1, m2, m3, m4, m5]
let Node = SCNNode(geometry: text)
表面情報も色以外にも光沢であったり鏡反射であったり色々要素があるので気になる方は調べてみてください。
下記をARkitのViewControllerに貼り付けると簡単にbuildして色を確認できると思います。確認してみてください。
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.showsStatistics = true
let scene = SCNScene()
sceneView.scene = scene
let depth:CGFloat = 0.01 // 奥行き0.2m
let text = SCNText(string: "テスト", extrusionDepth: depth)
text.font = UIFont.systemFont(ofSize: 0.5)
let m1 = SCNMaterial()
m1.diffuse.contents = UIColor.red // 前面に赤色
let m2 = SCNMaterial()
m2.diffuse.contents = UIColor.green // 背面に緑色
let m3 = SCNMaterial()
m3.diffuse.contents = UIColor.blue // 側面に青色
let m4 = SCNMaterial()
m4.diffuse.contents = UIColor.yellow
let m5 = SCNMaterial()
m5.diffuse.contents = UIColor.yellow
text.materials = [m1, m2, m3, m4, m5]
let Node = SCNNode(geometry: text)
// テキストを配置する場所を決める
let (min, max) = (Node.boundingBox)
let textBoundsWidth = (max.x - min.x)
let textBoundsheight = (max.y - min.y)
let z = CGFloat(-1.0) // 目の前1メートルの距離
Node.pivot = SCNMatrix4MakeTranslation(textBoundsWidth/2 + min.x, textBoundsheight/2 + min.y, 0)
Node.position = SCNVector3(0, 0, z)
// AR空間にテキスト要素を配置
sceneView.scene.rootNode.addChildNode(Node)
// 必要に応じて自動的に光源が追加されるように設定
sceneView.autoenablesDefaultLighting = true
// デバッグ用設定
// バウンディングボックス、ワイヤーフレームを表示する
sceneView.debugOptions = [.showBoundingBoxes, .showWireframe]
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration()
configuration.environmentTexturing = .automatic
sceneView.session.run(configuration)
}
では次に表面に画像を貼り付ける他の「SCNNode」も多数あるので画像をつける方法は別の「SCNSphere(球体)」の表示形式を使って表示してみます。
3Dオブジェクトの表面に画像貼り付け
画像貼り付けも基本的には同じで「SCNMaterial」を使っての操作で問題ないです。
画像を取得するところまでは下記記事にリンクを貼っておきますので自身のカメラロールから画像を取得しましょう。
「【Swift】カメラロールにアクセスし画像を取得する方法」
上記で取得できた画像を「image」とした上で下記のコードに進んでいきます。
let sphere = SCNSphere(radius: 0.01)
sphere.firstMaterial?.diffuse.contents = image
Node =let Node = SCNNode(geometry: text)
先ほどの「SCNText」と流れは同じでまずはNodeの形式を「SCNSphere」決定し、そのNodeの表面情報に画像を付与する。最終的にできた「SCNSphere」を「SCNNode」として使用するという流れです。後は上記のコードのように「scineview」に表示すればAR空間内に画像付きの3Dオブジェクトを配置することができます。
今回の記事は以上です。他にも多数のARkit関連の記事を記載しているので気になる方は参考リンクなどから確認してみてください。
コメント
[…] 「3Dオブジェクトの平面に画像を貼り付ける」「3Dオブジェクトを作ってARkitに」 […]
[…] 「ARkitでBlenderで作成した3Dオブジェクトを配置する方法。」「SCNNodeの表面に色や画像を貼り付ける方法。」 […]