はじめに
Webサイトに3D表現を組み込みたいと思ったとき、多くの人がThree.jsにたどり着きます。ただ、Three.jsは強力な反面、シーン・カメラ・レンダラー・ジオメトリ・マテリアルといった概念を命令的なJavaScriptコードで組み立てる必要があり、Vueでコンポーネント指向の開発に慣れていると少し勝手が違うと感じるかもしれません。
そこで登場するのがTresJSです。Three.jsの機能をVueのコンポーネントとしてそのまま宣言的に書けるようにしてくれるライブラリで、Reactでいうところのreact-three-fiberのVue版というとイメージしやすいでしょう。今回はTresJSの特徴から実際のコード例、実践的な使いどころまで紹介します。
TresJSとは
TresJS(トレスジェイエス)は、Vueのカスタムレンダラーを使ってThree.jsのシーンを宣言的に構築できるオープンソースライブラリです。「Tres」はスペイン語で「3」を意味し、3D・Three.js・Vue3という3つの要素を組み合わせたプロジェクトであることが名前の由来になっています。
Three.jsのTHREE.MeshやTHREE.BoxGeometryといったクラスは、TresJSでは<TresMesh>や<TresBoxGeometry>のようにVueテンプレート上のコンポーネントとしてそのまま利用できます。命令的なセットアップコードを書かずに済むため、Vueに慣れたエンジニアであれば違和感なく3D表現に取り組めます。
主な特徴
- 宣言的な記法 - Three.jsのオブジェクトをVueコンポーネントとしてテンプレートに書けるため、シーンの構造が見た目からも直感的に把握できます
- Three.jsの資産をそのまま活用 - Three.jsの最新APIやドキュメント、サンプルの知識をほぼそのまま流用できます
- TypeScript対応 - 型定義が用意されており、プロパティの補完やエラー検出の恩恵を受けられます
- 豊富なエコシステム - 追加コンポーネント集の
cientosやポストプロセッシング用のpost-processing、Nuxt統合パッケージなど周辺ライブラリが揃っています
インストール
新規プロジェクトを作る場合は、専用のスキャフォールディングツールが用意されています。
npx create-tres@latest
既存のVueプロジェクトに追加する場合は、コアパッケージをインストールするだけで利用を開始できます。
# npm
npm install three @tresjs/core
# yarn
yarn add three @tresjs/core
# pnpm
pnpm add three @tresjs/core
three本体もpeerDependencyとして必要になる点に注意してください。
基本的な使い方
まずは画面に緑色の立方体を表示するだけのシンプルな例を見てみましょう。すべてのシーンは<TresCanvas>から始まります。このコンポーネントがWebGLレンダラーの初期化やレンダリングループの開始を担ってくれます。
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas clear-color="#82DBC5" window-size>
<TresPerspectiveCamera :position="[3, 3, 3]" :look-at="[0, 0, 0]" />
<TresMesh>
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshBasicMaterial color="#00ff00" />
</TresMesh>
</TresCanvas>
</template>
TresPerspectiveCameraでカメラの位置と注視点を、TresMeshの子要素としてジオメトリとマテリアルを指定するだけで、Three.jsで書けば数十行になるセットアップが数行のテンプレートで完結します。
アニメーションを付けたい場合は、useLoopコンポーザブルを使ってレンダリングループにフックできます。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { TresCanvas, useLoop } from '@tresjs/core'
import type { Mesh } from 'three'
const boxRef = shallowRef<Mesh>()
useLoop().onBeforeRender(({ delta }) => {
if (boxRef.value) {
boxRef.value.rotation.y += delta
}
})
</script>
<template>
<TresCanvas clear-color="#82DBC5" window-size>
<TresPerspectiveCamera :position="[3, 3, 3]" :look-at="[0, 0, 0]" />
<TresMesh ref="boxRef">
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshStandardMaterial color="#4f88e3" />
</TresMesh>
<TresAmbientLight :intensity="0.5" />
<TresDirectionalLight :position="[3, 3, 3]" />
</TresCanvas>
</template>
delta(前フレームからの経過時間)を使って回転量を計算しているため、フレームレートに依存しない滑らかなアニメーションになります。
実践的なユースケース
商品ビュワー
ECサイトなどで商品を360度回転させて確認できるビューワーは、TresJSが特に力を発揮する場面です。OrbitControlsをcientosから読み込むことで、マウス操作によるカメラ制御を簡単に実装できます。
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { OrbitControls, useGLTF } from '@tresjs/cientos'
const { scene } = await useGLTF('/models/product.glb')
</script>
<template>
<TresCanvas window-size>
<TresPerspectiveCamera :position="[2, 2, 2]" />
<OrbitControls />
<primitive :object="scene" />
<TresAmbientLight :intensity="1" />
</TresCanvas>
</template>
useGLTFコンポーザブルを使えば、Blenderなどで作成した3Dモデル(glTF形式)を読み込んでそのまま表示できます。
データビジュアライゼーション
配列のデータを高さや色に反映した3Dの棒グラフのように、通常のCSSやCanvas 2Dでは表現しづらいビジュアライゼーションもVueのリアクティビティと組み合わせて宣言的に構築できます。データが更新されればテンプレートのv-forがそのまま3Dオブジェクトの再描画に反映されるため、Vueらしい書き味を維持したままインタラクティブな3D表現に応用できます。
まとめ
TresJSは、Three.jsが持つ表現力をVueのコンポーネント指向という馴染みのある形で扱えるようにしてくれるライブラリです。宣言的な記法によってシーンの見通しが良くなるだけでなく、cientosのような周辺エコシステムを組み合わせることでモデル読み込みやカメラ制御といった実務的な機能も手軽に実装できます。
まずは公式のプレイグラウンド(play.tresjs.org)で簡単なシーンを触ってみて、感覚をつかんでから自分のプロジェクトに組み込んでみてはいかがでしょうか。Vueで3D表現に挑戦してみたい方にとって、良い入口になるはずです。