このセクションでは、VRMモデルを用いてアバターを表示する方法を学びます。
VRMモデルは、3Dモデルの一種で、人間の形をしたアバターです。
VRMモデルは、表情やポーズなどの情報を持っているため、リアルな人間の動きを再現することができます。
VRMモデルは無料で作成することができます。
例えば、VRoid Studioというソフトウェアを使うと、簡単にVRMモデルを作成することができます。
VRoid Studio は、PC(Window, Mac)はもちろん、 iPadでも利用することができます。
ここでは、作成したVRMモデルを sample.vrm
という名前で保存したとします。
サンプルのモデルファイルをこちらからダウンロードしても構いません。
モデルファイルは、プログラムのファイルと同じ場所に配置してください。
VRMモデルを読み込むには、load.vrm(モデルファイルのパス)
を使います。
load.vrm(VRMモデルのパス)
今の場合、次のようにするとVRMモデルが表示されます。
const { camera, create, animate, controls, load, helper } = init()
controls.connect()
camera.position.set(0, 1.3, -1.5)
controls.target.set(0, 1, 0)
helper.grid({ size: 10 })
helper.axes()
create.ambientLight({ intensity: 0.2 })
create.directionalLight({
intensity: 2,
position: [-10, 10, -10]
});
create.plane({
size: 10,
rotation: [-Math.PI / 2, 0, 0],
option: {
color: 0xaaaaaa,
}
})
load.vrm("./sample.vrm")
animate()
他のオブジェクトを作るときと同じように、 サイズや位置を調整することができます。
背景画像や環境マップ、テクスチャなどと併用すると、 よりリアルな3Dシーンを作成することができます。
読み込んだVRMモデルは、変数に代入して操作することができます。
読み込みは非同期処理なので、変数に入れる場合は 非同期処理の終了時の処理を指定できる then
か、 非同期処理の終了を待つ await
を利用します。then
を使う場合、後から再代入するためconst
ではなく let
を使います。
const model = await load.vrm(モデルファイルのパス)
let model
load.vrm(モデルファイルのパス).then(m => model = m)
then
を使う場合、model
は読み込みが完了するまで undefined
です。
つまり、await
を使う場合は
const model = load.vrm(モデルファイルのパス)
animate(({ delta }) => {
// modelの操作
})
と書くことができますが、then
を使う場合は
let model
load.vrm(モデルファイルのパス).then(m => model = m)
animate(({ delta }) => {
if (model) {
// modelの操作
}
})
と書く必要があります。
await
を利用すると、モデルの読み込みが完了するまで待機します。
通常モデルはそれなりに重いため、読み込みに時間がかかり、 その間なにも表示できないことになります。
また await
はトップレベルなどでしか使えないため、 関数内で load.vrm
を行う場合には then
を使う必要があります。
これらのことから、VRMモデルを読み込む場合は、 基本的には then
を使うことをオススメします。
VRMモデル全体を動かしたり回転させるには、model
そのものではなく、model.scene
を操作します。
const { camera, create, animate, controls, load, helper } = init()
controls.connect()
camera.position.set(0, 1.3, -1.5)
controls.target.set(0, 1, 0)
helper.grid({ size: 10 })
helper.axes()
create.ambientLight({ intensity: 0.2 })
create.directionalLight({
intensity: 2,
position: [-10, 10, -10]
})
create.plane({
size: 10,
rotation: [-Math.PI / 2, 0, 0],
option: {
color: 0xaaaaaa,
}
})
let model
load.vrm("./sample.vrm").then(m => model = m)
animate(({ delta }) => {
if (model) {
model.scene.rotation.y += delta
}
})