株式会社クイックのWebサービス開発blog

HAPPYなサービスプランナー・エンジニア・デザイナーのブログです。

Three.jsでWebGL入門

こんにちは、システムエンジニアのponです。
ここ数日「Pokémon LEGENDS アルセウス」にハマっているのですが、3D酔いしてしまって1日1時間しか遊べないのが悲しいです。

車酔いする人は車運転すると酔わないよ!と言いますし、
自分で3Dコンテンツ作れば3D酔いが軽減するのでは?ということで今日は遅ればせながらThree.jsで立体物を動かしてみようと思います!

Three.jsとは?

three.jsは、ウェブブラウザ上でリアルタイムレンダリングによる3次元コンピュータグラフィックスを描画する、クロスブラウザ対応の軽量なJavaScriptライブラリおよびAPIである。 Three.js - Wikipedia

web上で手軽に3Dコンテンツを作成できるライブラリです。
昨年話題になった「Yamauchi No.10 Family Office」のコーポレートサイトでもThree.jsが使用されています。 y-n10.com

公式にドキュメントやサンプルコードがたくさんあるので面白そうなものを写経するだけでもかなり勉強になります。 threejs.org

今回立体にするもの

看護roo!ロゴの

f:id:aimstogeek:20220210101704p:plain:w300
2つ目の「o」を立体にします。
f:id:aimstogeek:20220210101421p:plain:w300
(かわいい・・・!)

下準備

SVGを用意します。
Adobe XDでSVGを作るとなぜか取り込めないのと、
取り込むとなぜか天地が逆転するので上下反転したシェイプをPhotoshopで作成してSVGを取得します。

f:id:aimstogeek:20220210103548p:plain
ぺジェ線引くのたのしい

discourse.threejs.org

表示してみる

See the Pen three.js test by QUICK Web Service Development (@quick-engineers) on CodePen.

 

Three.jsはシーン(空間)を作成してとメッシュ(物体)とそれを映すカメラを空間に配置してレンダリングするとcanvas上に表示されます。
文章にしてみるとなかなか難しいですがこちらのサイトが図解で説明されていて大変分かりやすかったです。 ics.media

メッシュはマテリアルとジオメトリから構成されるので、今回はSVGLoaderを使用してSVGのパスからジオメトリのシェイプとマテリアルに設定する色を取得しています。

const loader = new THREE.SVGLoader();
const svgMarkup = document.querySelector('#logo').outerHTML;
const svgData = loader.parse(svgMarkup);

const svgGroup = new THREE.Group();
svgData.paths.forEach((path, i) => {
  // パスからシェイプ作成
  const shapes = path.toShapes(true);

  shapes.forEach((shape, j) => {
    const material = new THREE.MeshBasicMaterial({
      // pathに設定している色を取得して設定
      color: path.color,
      side: THREE.DoubleSide,
          depthWrite: false
    });
    const geometry = new THREE.ExtrudeGeometry(shape, {
      // 奥行き30で押し出しします
      depth: 30,
      bevelEnabled: false
    });

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

    svgGroup.add(mesh);
  });
});

以下のサイトがとても分かりやすかったので参考にしました。 muffinman.io  

出力はされたもののこれだと立体かどうかよく分からないですね・・・

回してみる

See the Pen three.js SVGloader test by QUICK Web Service Development (@quick-engineers) on CodePen.

 

動きがあると厚みが見えるので立体感が出ますね!
回すのは意外と簡単で、レンダリングの部分を以下コードを変更するだけで回り出します。

tick();

function tick() {
  // フレームごとにy軸回転する
  svgGroup.rotation.y += 0.01;
  renderer.render(scene, camera);
  requestAnimationFrame(tick);
}

マウスに合わせて動かしてみる

See the Pen Untitled by QUICK Web Service Development (@quick-engineers) on CodePen.

 

マウスに合わせて動かす挙動は公式のこちらを参考にしました。 threejs.org

ついでにマテリアルをMeshToonMaterialに変更しつつ、メッシュを追加して前方にステンドグラスみたいに光が落ちてる感じにしました。
(でもライトが正面から当たっている矛盾)

まとめ

今回は簡単ですが、three.jsを使って立体表現に挑戦してみました。
普段の実務ですとこういった動きのある実装をすることはあまり無いのですが
LPや診断ページなど読み物コンテンツに導入してみるのも華やかで良いなと思いました。
表現の幅を広げて親しみのあるサイトを作成していければと思います ٩( ᐛ )( ᐖ )۶


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp