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;
}