ARKitで立方体の6面それぞれに異なるテクスチャを貼る方法[追記あり]


はじめに

iOS11(beta)で登場したARKitで遊んでいます。ちょっとしたアイディアで面白いアプリができそうで楽しいです。

立方体の6面それぞれに別々のテクスチャを貼ろうとしたところ、検索しても明確な説明が見つからなかったので、簡単なコードを書いて実験してみました。

※この記事を描いてだいぶ経ってから、扱っている立体は〈立方体〉ではなく、〈直方体〉であることに気がつきました。タイトルまで変えると検索性が悪くなるので、本稿ではそのまま〈立方体〉で通しています。(2020/06/02 追記)

環境

  • Xcode Version 9.0 beta 3 (9M174d)
  • iOS11 beta 11.0(15A5341f)
  • iPhone 6S(MKQW2J/A)

座標系について

地面に垂直に立って、カメラを正面に向けてiPhoneを保持しているとします。

アプリ起動時のiPhoneの位置が原点となり、自分から見て、左→右方向がX軸の正の方向、下→上方向がY軸の正の方向となります。Z軸は正面→背面方向が正の方向となりますので、気をつける必要があります。

このときiPhoneが傾いていたとしても、地面に対して垂直・水平が基準となって座標系が設定されます。この座標系はアプリ起動後に設置され、その後iPhoneの位置が移動しても、原点の位置と軸の方向は維持されます(これがARの面白いところ)。

長さの単位ですが、コード上の1.0が現実世界の1mに対応します。

テクスチャの貼り方を試す

立方体の6面全てに同一のテクスチャを貼る場合は、以下のようにすれば済みます。

cube.firstMaterial?.diffuse.contents = UIImage(named: "texture.png")

6面それぞれに別のテクスチャを貼ろうとした場合は、ノードのmaterialsプロパティに、テクスチャの配列を与えれば良いのですが、順番や向きがどうなるのかよくわからなかったので、シンプルなプログラムを書いて実験してみます。

図のような6面分のテクスチャを用意しました。

コード

幅10cm、高さ20cm、奥行き30cmの立方体を作成し、テクスチャを貼り付けます。辺の長さを変えているのは、面の対応関係がわかりやすいようにです。

GameScene.swift
    func makeCube() {
        // 幅10cm、高さ20cm、奥行き30cmの立方体を作成
        let cube = SCNBox(width: 0.1, height: 0.2, length: 0.3, chamferRadius: 0)
        let cubeNode = SCNNode(geometry: cube)

        // 6面、別々のテクスチャを貼る
        let m1 = SCNMaterial()
        let m2 = SCNMaterial()
        let m3 = SCNMaterial()
        let m4 = SCNMaterial()
        let m5 = SCNMaterial()
        let m6 = SCNMaterial()

        m1.diffuse.contents = UIImage(named: "texture_1.png")
        m2.diffuse.contents = UIImage(named: "texture_2.png")
        m3.diffuse.contents = UIImage(named: "texture_3.png")
        m4.diffuse.contents = UIImage(named: "texture_4.png")
        m5.diffuse.contents = UIImage(named: "texture_5.png")
        m6.diffuse.contents = UIImage(named: "texture_6.png")

        cube.materials = [m1, m2, m3, m4, m5, m6]

        // 初期位置の指定: 50cm画面奥、10cm上方に配置
        cubeNode.position = SCNVector3Make(0, 0.1, -0.5)

        self.rootNode.addChildNode(cubeNode)
    }

結果

このようにテクスチャが貼られます。

手前から見たとき、つまり原点側からZ軸マイナス方向に見たときの画像です。

手前側で3つの線分が直交している点が原点で、赤がX軸、緑がY軸、青がZ軸です。
やや上から見下ろしているので、立方体は1,2,5の面が見えます。

奥から振り返って見たとき、つまりZ軸マイナス方向から原点方向を見たときの画像です。

画面奥に原点があり、X軸、Y軸、Z軸が直交しています。
やや下から見上げているので、立方体は、3,4,6の面が見えます。

展開図にしてみるとこんな配置となります。

おわりに

Qiitaに記事を書くのは初めてです。

初歩的な事ですが、自分がわからなかったことがわかったとき、それを共有することで、どこかの誰かに役立てば嬉しいことです。

ARKitはいじっていてわくわくします。簡単なアプリを作って、app storeで公開することを目標にしています。