2
Help us understand the problem. What are the problem?

posted at

updated at

Organization

three.js で glTF データのジオメトリとシェーダを組み合わせる

three.js で blender などで作ったモデルに、
GLSL で記述したシェーダを組み合わせる忘備録です。

blender 側の設定

blender でモデリングしたデータを glTF 形式で書き出します。
マテリアルのデータが全くないとうまくシェーダが適応されなかった記憶があるので、
エクスポートオプションのジオメトリの「マテリアル」も一緒にエクスポートするようにしてください。

シェイプキーを使う場合は「アニメーション」のシェイプキーにチェックを入れてください。

three.js

GLTFLoader を使ってデータを読み込み、Mesh のジオメトリデータを取得します。
shader を読み込み、マテリアルデータを作成します。

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import vertexShader from './shaders/shader.vert';
import fragmentShader from './shaders/shader.frag';

async function getGeometryData() :Promise<THREE.BufferGeometry> {
  return new Promise((resolve) => {
    // gltf の読み込み
    const loader = new GLTFLoader();
    loader.load('./gltf/main.glb', (object) => {
      object.scene.traverse( (child) => {
        // main という名前のオブジェクト
        if(child instanceof THREE.Mesh && child.name === "main") {
          console.log(child.geometry);
          resolve(child.geometry);
        }
      });
    });
  });
}

async function setMesh() {
  const geometry = await getGeometryData();
  const material = new THREE.ShaderMaterial({
    vertexShader: vertexShader,
    fragmentShader: fragmentShader
  });

  const mesh = new THREE.Mesh(
    geometry,
    material
  );
} 

シェイプキーアニメーションを行う場合

blender で作ったモデルデータに、シェイプキーアニメーションを設定し、
アニメーションするオブジェクトに対して shader を利用するときは
VertexShader を下記のようにします。

#include <morphtarget_pars_vertex>

void main() {
  #include <begin_vertex>
  #include <morphtarget_vertex>

  // モデルをローカル座標から視点系座標に変換
  vec4 mvPosition   = modelViewMatrix * vec4( transformed, 1.0 );

  gl_Position   = projectionMatrix * mvPosition;
}

シェイプアニメーションを適用。

if (mesh.morphTargetInfluences) {
  mesh.morphTargetInfluences[0] = 1;
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?