近年、MetaがQuest 3を発売したり、AppleがVision Proを発表するなど、VR(仮想現実)やAR(拡張現実)への注目度が高まっています。そんな中、今回は、Webブラウザ上で3Dモデルを表示できるライブラリ「model-viewer」を紹介します。

model-viewerとは

model-viewerは、Googleが開発したWebコンポーネントです。まるでWebページに動画を埋め込むように、3Dモデルを簡単に表示できます。しかも、マウスや指でグリグリ動かしたり、拡大縮小したりと、インタラクティブな操作も可能です。対応している3Dモデルの形式はglTFとGLBで、これらのファイルを準備すればOKです。

model-viewerを使うには、以下のようなHTMLタグを記述します。

<!-- ライブラリ読み込み -->
<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.3.0/model-viewer.min.js"></script>

<!-- Web Componentsとしてmodel-viewerタグが使えます -->
<model-viewer
    alt="Neil Armstrong"s Spacesuit from the Smithsonian Digitization Programs Office and National Air and Space Museum"
    src="shared-assets/models/NeilArmstrong.glb"
    ar
    environment-image="shared-assets/environments/moon_1k.hdr"
    poster="shared-assets/models/NeilArmstrong.webp"
    shadow-intensity="1"
    camera-controls
    touch-action="pan-y"
>
</model-viewer>

上記のコードでは、以下のような設定がされています。

  • src属性で、表示する3Dモデルのファイルパスを指定
  • ar属性で、ARモードを有効化
  • environment-image属性で、3Dモデルの背景画像を指定
  • poster属性で、3Dモデルが読み込まれるまでの代替画像を指定
  • shadow-intensity属性で、影の濃さを調整
  • camera-controls属性で、カメラのコントロールを有効化
  • touch-action属性で、タッチ操作を制限

サポートするブラウザ

公式サイトによると、以下のブラウザで動作します。

  • Google Chrome(Windows、macOS、Android)
  • Microsoft Edge
  • Mozilla Firefox(Windows、macOS)
  • Safari(macOSのみ。iOSは非対応)

公式サイトによれば、基本的にChromium系のブラウザであれば動作します。Safariはサポート対象外となっていますが、macOS版であれば動作します(iOSのSafariでは動作しません)。Firefoxもデスクトップ版であれば動作可能です。

ただし、WebXRを利用する場合は、Chromium系でのみ動作するようです。

対応している3Dモデルのフォーマット

model-viewerが対応している3Dモデルのフォーマットは、以下の2種類です。

  • glTF(gl Transmission Format)
  • GLB(Binary glTF)

glTFは、3Dモデルのデータを JSON 形式で記述するフォーマットで、テクスチャなどの関連ファイルは別ファイルとして管理されます。

一方、GLBは、glTFをベースにしつつ、関連ファイルをまとめて1つのバイナリファイルにしたフォーマットです。

ARモードについて

model-viewerの大きな特徴の一つが、ARモードの提供です。ARモードを使うことで、実世界に3Dモデルを重ねて表示することができます。

ARモードを使うには、対応するデバイスとブラウザが必要です。現在、ARモードに対応しているのは、Android端末とChromiumベースのブラウザ(Google ChromeやMicrosoft Edgeなど)のみとなっています。

ARモードを有効にするには、タグにar属性を追加するだけです。あとは、表示された「AR」ボタンをタップすることで、ARモードが起動します。

他の3Dモデルビューワーとの違い

model-viewer以外にも、Webブラウザ上で3Dモデルを表示できるライブラリはいくつかあります。ここでは、オープンソースのライブラリを中心に紹介します。

glTF Viewer

glTF ViewerはThree.jsを使ったglTFビューワーです。名前の通り、glTFのみに対応しています。また、バージョン2以降のみに対応しています。

donmccurdy/three-gltf-viewer

A WebGL multiple file 3D viewer

A WebGL multiple file 3D viewerは、45種類もの3Dモデルフォーマットの表示に対応したビューワーです。Unity 3Dを利用して開発されているのが特徴です。また、React向けに開発されているのも特徴の一つです。

Rufus31415/react-webgl-3d-viewer-demo

Online 3D Viewer

Online 3D Viewerは、20種類近くの3Dモデルフォーマットに対応したビューワーです。3Dモデルのインポートとエクスポートの両方に対応しているのが特徴です。3D表示部分はThree.jsを利用しています。

kovacsv/Online3DViewer

Web 3D Viewer

Web 3D Viewerは、3Dモデルの表示だけでなく、ツリーリストの表示や簡易的な編集機能も備えたソフトウェアです。ワイヤーフレーム表示やオブジェクトの向きをクリックで変更できるのが特徴です。編集結果は別のファイルフォーマットでエクスポートすることができます。

lss3070/Web3DViewer

React Three Fiber

React Three Fiberは、React向けの3D表示コンポーネントです。3D表示にはThree.jsを利用しています。

A-Frame

A-Frameは、主にWebVRに特化したライブラリです。glTFとGLBの両方に対応しています。AR.jsと組み合わせることで、AR表示にも利用できます。

model-viewerの使い方

ここからはの利用例を紹介します。

デモ

「model-viewer」を使ったデモを試してみるには、Model Editorを利用するのが便利です。ここでは、自作の3Dモデルなどを読み込ませて、表示を確認することができます。

WebXRでの表示

WebXRでの表示を行う際の書き方です。

この例では、VRデバイスに対応し、手を表示したりできます。また、JavaScriptでのタップイベントなどとの組み合わせも可能です。

<model-viewer
    src="../../assets/ShopifyModels/Chair.glb"
    poster="../../assets/ShopifyModels/Chair.webp"
    shadow-intensity="1"
    ar
    camera-controls
    touch-action="pan-y"
    alt="A 3D model carousel"
>
  <button slot="ar-button" id="ar-button">
    View in your space
  </button>
  <div id="ar-prompt">
    <img src="../../assets/hand.png">
  </div>
  <button id="ar-failure">
    AR is not tracking!
  </button>
  <div class="slider">
    <div class="slides">
      <button class="slide selected" onclick="switchSrc(this, "Chair")" style="background-image: url("../../assets/ShopifyModels/Chair.webp");">
      </button><button class="slide" onclick="switchSrc(this, "Mixer")" style="background-image: url("../../assets/ShopifyModels/Mixer.webp");">
      </button><button class="slide" onclick="switchSrc(this, "GeoPlanter")" style="background-image: url("../../assets/ShopifyModels/GeoPlanter.webp");">
      </button><button class="slide" onclick="switchSrc(this, "ToyTrain")" style="background-image: url("../../assets/ShopifyModels/ToyTrain.webp");">
      </button><button class="slide" onclick="switchSrc(this, "Canoe")" style="background-image: url("../../assets/ShopifyModels/Canoe.webp");">    
    </button></div>
  </div>
</model-viewer>

WebXR

ARでの表示

ARで表示を行う際には、ページがHTTPSで提供されている必要があります。また、iframeを利用するのですが、そのページがxr-spatial-trackingを有効にしている必要があります。

iOSの場合は、ios-src属性で指定したUSDZファイルを利用します。

<model-viewer
    src="../../shared-assets/models/Astronaut.glb"
    ar
    ar-scale="fixed"
    camera-controls
    touch-action="pan-y"
    alt="A 3D model of an astronaut"
    skybox-image="../../shared-assets/environments/aircraft_workshop_01_1k.hdr" 
    ios-src="../../shared-assets/models/Astronaut.usdz"
    xr-environment
>
</model-viewer>

AR

カスタムボタンの追加

モデル上にJavaScriptと組み合わせるボタンを配置することができます。これは、AR対応デバイスでの利用を想定しています。

<model-viewer
    ar
    camera-controls
    touch-action="pan-y"
    src="../../shared-assets/models/Astronaut.glb"
    alt="A 3D model of an astronaut">
    <button slot="ar-button" style="background-color: white; border-radius: 4px; border: none; position: absolute; top: 16px; right: 16px; ">
       Activate AR
    </button>
</model-viewer>

カスタムボタン

透明な背景の設定

通常は白などの背景が表示されますが、style属性でbackground-color: unset;を指定することで、背景を透明にできます。これにより、3Dモデルの背後にあるHTMLコンテンツが表示されるようになります。

<div
    class="demo"
    style="background: linear-gradient(#ffffff, #ada996);
    overflow-x: hidden;"
>
  <span
        style="position: absolute; text-align: center; font-size: 100px; line-height: 100px; left: 50%; transform: translateX(-50%);">
            Background<br>is visible<br>through<br>transparent<br>objects.
    </span>
  <model-viewer
        camera-controls
        touch-action="pan-y"
        src="../../shared-assets/models/glTF-Sample-Assets/Models/ToyCar/glTF-Binary/ToyCar.glb"
        ar
        alt="A 3D transparency test"
        style="background-color: unset;"
    >
    </model-viewer>
</div>

透明な背景

カメラコントロール

camera-controls 要素を付けると、VRデバイスやマウスによる視点変更が可能になります。

<model-viewer
    camera-controls
    touch-action="pan-y"
    src="../../shared-assets/models/Astronaut.glb"
    alt="A 3D model of an astronaut"
>
</model-viewer>

カメラコントロール

カメラの初期アングルの設定

カメラの初期アングルは camera-orbit で指定します。単位は deg (度)か rad (ラジアン)です。また、 deg は省略可能です。

<model-viewer
    camera-controls
    touch-action="pan-y"
    camera-orbit="45deg 55deg 4m"
    src="../../shared-assets/models/Astronaut.glb"
    alt="A 3D model of an astronaut"
>
</model-viewer>

CSS風にcalcも利用できます。

<model-viewer
    camera-controls
    touch-action="pan-y"
    camera-orbit="calc(-1.5rad + env(window-scroll-y) * 4rad) calc(0deg + env(window-scroll-y) * 180deg) calc(5m - env(window-scroll-y) * 10m)"
    src="../../shared-assets/models/Astronaut.glb"
    alt="A 3D model of an astronaut"
>
</model-viewer>

カメラの初期アングル

ズーム機能の無効化

disable-zoom を指定するとズーム機能が無効になります。

<model-viewer
    camera-controls
    touch-action="pan-y"
    disable-zoom
    src="../../shared-assets/models/Astronaut.glb"
    alt="A 3D model of an astronaut"
>
</model-viewer>

ズーム不可

JavaScriptによるカメラ操作

cameraOrbit プロパティを使って、JavaScriptからカメラを操作することができます。

<model-viewer
    id="orbit-demo"
    interpolation-decay="200"
    src="../../shared-assets/models/Astronaut.glb"
    alt="A 3D model of an astronaut"
>
</model-viewer>
<script>
(() => {
  const modelViewer = document.querySelector("#orbit-demo");
  const orbitCycle = [
    "45deg 55deg 4m",
    "-60deg 110deg 2m",
    modelViewer.cameraOrbit
  ];
  setInterval(() => {
    const currentOrbitIndex = orbitCycle.indexOf(modelViewer.cameraOrbit);
    modelViewer.cameraOrbit =
        orbitCycle[(currentOrbitIndex + 1) % orbitCycle.length];
  }, 3000);
})();
</script>

JavaScriptで自動的に操作

アニメーションの再生

3Dモデルがアニメーションをサポートしている場合、 autoplay を指定すると自動的に再生されます。

<model-viewer
    camera-controls
    touch-action="pan-y"
    autoplay
    ar
    ar-modes="webxr scene-viewer"
    scale="0.2 0.2 0.2"
    shadow-intensity="1"
    src="../../shared-assets/models/RobotExpressive.glb"
    alt="An animated 3D model of a robot"
>
</model-viewer>

アニメーション

色の変更

同じモデルを使いつつ、色を変更する例です。

<model-viewer
    id="shoe"
    camera-controls
    touch-action="pan-y"
    src="../../shared-assets/models/glTF-Sample-Assets/Models/MaterialsVariantsShoe/glTF-Binary/MaterialsVariantsShoe.glb"
    ar
    alt="A 3D model of a Shoe"
>
  <div class="controls">
    <div>Variant: <select id="variant"></select></div>
  </div>
</model-viewer>
<script>
    const modelViewerVariants = document.querySelector("model-viewer#shoe");
    const select = document.querySelector("#variant");

    modelViewerVariants.addEventListener("load", () => {
        const names = modelViewerVariants.availableVariants;
        for (const name of names) {
            const option = document.createElement("option");
            option.value = name;
            option.textContent = name;
            select.appendChild(option);
        }
        // Adds a default option.
        const option = document.createElement("option");
            option.value = "default";
            option.textContent = "Default";
            select.appendChild(option);
    });

    select.addEventListener("input", (event) => {
        modelViewerVariants.variantName = event.target.value === "default" ? null : event.target.value;
    });
</script>

色変更

まとめ

<model-viewer> はWeb Componentsとして作られているので、HTMLタグとして利用できます。また、JavaScriptと組み合わせることで、様々な表現が可能です。フレームワークに依存していないので、ReactやVue.jsと組み合わせることも可能です。

VR表示やもちろん、ARでも利用できるので、さまざまなプロジェクトで利用できるでしょう。ぜひ試してみてください。

<model-viewer>