夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

glTFのファイルフォーマットを覗く

本日は3Dモデリング枠です。

〇glTFフォーマットのモデルの作成

まずはglTFフォーマットのモデルを作成していきます。

BlenderではデフォルトでglTFのバイナリ形式であるglb形式のフォーマットのエクスポートをサポートしています。

今回はデフォルトのCubeを用いていきます。

これによってエクスポートパスにglbファイルが出力されます。

ダブルクリックなどを行うことで行うことで通常はPaint3Dなど標準の3Dアプリで表示されます。

そのためプログラムから開くでエディタを選択する必要があります。メモ帳などでもJson部は見ることはできますが、文字化けすることがあります。

今回はBzというバイナリエディタを使用しました。

Jsonファイルがあるのが確認できました。

では公式のドキュメントを読んでいきます。

〇GLBフォーマットの構造

GLBのフォーマットは次のようなバイナリ構造になっています。

・12バイトのヘッダー

Jsonデータ

次の図は公式ドキュメントに記載されているGLBフォーマットのサンプルです。

〇ヘッダー

ヘッダーは4バイトのデータが3つあり、次のようになります。

・uint32 magic :glTFとして認識するためのデータで必ず0x46546C67となります。

・unit32 version :glTFのバージョン情報が記録されます。

・unit32 length :ヘッダーとすべてのJsonチャンクを含むデータの大きさを記録します。

〇チャンク

チャンクとはJson部のことを指します。

各チャンクは次のようなデータを持ちます。

・unit32 chunkLength : chunkDataの長さ

・unit32 chunkType :タイプを示す。

・ubyte chunkData :バイナリデータ本体

registry.khronos.org

チャンクタイプは2種類ありJsonかBINです。それぞれ0x4E4F534Aか0X004E4842で区別されます。

BINはバイナリデータとして01であらわされるデータで人間に理解しやすい形式のJsonに対してBINはコンピュータに理解しやすく効率的な処理をできる形式になります。

JSON部を見る

上記のドキュメントを参考にCubeのデータを読み解きます。

{
   "asset":{
      "generator":"Khronos glTF Blender I/O v3.4.49",
      "version":"2.0"
   },
   "scene":0,
   "scenes":[
      {
         "name":"Scene",
         "nodes":[0]
      }
   ],
   //オブジェクト情報
   "nodes":[
      {
         "mesh":0,
         "name":"Cube"
      }
   ],
  //マテリアル情報
   "materials":[
      {
         "doubleSided":true,
         "name":"Material",
         "pbrMetallicRoughness":{
            "baseColorFactor":[
               0.800000011920929,
               0.800000011920929,
               0.800000011920929,
               1
            ],
            "metallicFactor":0,
            "roughnessFactor":0.5
         }
      }
   ],
  //メッシュ情報
   "meshes":[
      {
         "name":"Cube",
         "primitives":[
            {
               "attributes":{
                  "POSITION":0,
                  "TEXCOORD_0":1,
                  "NORMAL":2
               },
               "indices":3,
               "material":0
            }
         ]
      }
   ],
   //頂点情報
   "accessors":[
      {
         "bufferView":0,
         "componentType":5126,
         "count":24,
         "max":[
            1,
            1,
            1
         ],
         "min":[
            -1,
            -1,
            -1
         ],
         "type":"VEC3"
      },
      {
         "bufferView":1,
         "componentType":5126,
         "count":24,
         "type":"VEC2"
      },
      {
         "bufferView":2,
         "componentType":5126,
         "count":24,
         "type":"VEC3"
      },
      {
         "bufferView":3,
         "componentType":5123,
         "count":36,
         "type":"SCALAR"
      }
   ],
   "bufferViews":[
      {
         "buffer":0,
         "byteLength":288,
         "byteOffset":0,
         "target":34962
      },
      {
         "buffer":0,
         "byteLength":192,
         "byteOffset":288,
         "target":34962
      },
      {
         "buffer":0,
         "byteLength":288,
         "byteOffset":480,
         "target":34962
      },
      {
         "buffer":0,
         "byteLength":72,
         "byteOffset":768,
         "target":34963
      }
   ]
}
〇頂点情報

頂点情報はaccessorsにあります。

   "accessors":[
      {
         "bufferView":0,
         "componentType":5126,
         "count":24,
         "max":[1,1,1],
         "min":[-1,-1,-1],
         "type":"VEC3"
      },
      // 他の accessors エントリ
   ]

それぞれ次のような情報になります。

・bufferView: 頂点情報が格納されているバッファビューを指すインデックス。

・componentType: 頂点の各要素(この場合、座標)のデータ型(この例では5126は浮動小数点数)。

・count: 頂点の数 ここでは24頂点

・max/min: 頂点座標の最大値と最小値。これは、頂点データの範囲を示します。 Boundsなどで使用されます。

・type: 頂点データの型(この例ではVEC3は3次元ベクトル)。

以上がglTFのフォーマットになります。