LoginSignup
4
3

More than 1 year has passed since last update.

three.jsのGLTFLoaderでgltfファイルを読み込み、生webglで描画したい

Last updated at Posted at 2021-12-28

概要

gltfの読み込みだけthree.jsでして、他は生webgl使いたい人向けです。

今回は、頂点の座標の配列とインデックス(どの頂点で三角形を描画するかを示したもの)の取得まで説明します。
そこからの描画はwebglの以下の入門サイト等で説明があるので、本記事では割愛します。
https://wgld.org/d/webgl/w018.html

コード

とりあえずコードはこんな感じです。
GLTFLoaderのload関数の第一引数は"./box.gltf"のようなgltfファイルへのパスです。
第二引数はコールバックでgltfファイルの読み込みが終わった時に呼ばれる関数が指定できます。
引数のdataには第一引数で指定したgltfファイルがjsのobject型に変換されたものが入っており、頂点の座標の配列等も入っています。

        const loader = new THREE.GLTFLoader();
        loader.load(path, (data) => { 
                const returnData = {
                    //頂点の座標の配列
                    positionData: data.scene.children[0].geometry.attributes.position.array,
                    //頂点の個数(drawElementsならelementCount使うので不要かも?)
                    vertexCount: data.scene.children[0].geometry.attributes.position.count,
                    //indexの配列
                    elementData: data.scene.children[0].geometry.index.array,
                    //indexの個数
                    elmentCount: data.scene.children[0].geometry.index.count,
                }; 
            }

promise使って同期処理に

GLTFLoaderのload関数の第二引数で指定したコールバックは、gltfファイルが読み込まれてから非同期的に呼ばれるぽいので少し使いずらいです。
のでjsのpromiseという機能を使い、gltfファイルが読み終わりコールバックが呼ばれるまで他の処理を止めておくコードも書いておきます。

async function getGeometory(path) {
    return new Promise((resolve => {
        const loader = new THREE.GLTFLoader();
        loader.load(path, (data) => {
                const returnData = {
                    //頂点の配列
                    positionData: data.scene.children[0].geometry.attributes.position.array,
                    //頂点の個数(drawElementsならelementCount使うので不要かも?)
                    vertexCount: data.scene.children[0].geometry.attributes.position.count,
                    //indexの配列
                    elementData: data.scene.children[0].geometry.index.array,
                    //indexの個数
                    elmentCount: data.scene.children[0].geometry.index.count,
                    // uvData: data.scene.children[0].geometry.attributes.uv.array,
                };
                resolve(returnData);
            }
        );
    }));
}

このgetGeometory関数を定義したら、以下の様に呼び出せば、resolveの引数のreturnData が左辺値geometorydataに入ります。
awitを付けることでgetGeometory関数の処理が終わるまで、次の行にはいかない普通の同期処理になります。

 const geometorydata = await getGeometory("./../../model/sphere.gltf");

あとは、このgeometorydataから頂点座標のバッファとインデックスバッファを作りdrawElements関数を呼べばよいですね。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3