
Web3Dで主に扱うデータ形式まとめ
はじめに
こんにちは、WebXR JPというコミュニティを運営しているにっしです。
最近この個人ブログにさまざまな形式の3Dモデルビューアー埋め込み機能を実装していました。
いい機会なので、改めてWebでよく扱う3Dデータ形式をまとめ、three.js / R3F(React Three Fiber)環境で便利に使えるライブラリを紹介します。
3Dにあまり馴染みのないWebエンジニアにも、宣言的に3Dシーンをコーディングできるんだ、っていうのを伝えられれば嬉しいです。
.glb - 3DにおけるJPEG
glTF(GL Transmission Format) は、WebGLの仕様策定元であるKhronos Group社が策定したWeb3D向けの標準形式で、JSONベースで3Dモデルやシーンを表現するフォーマットです。
.glbは、このglTFのバイナリ版で、テクスチャやアニメーションを含めて1ファイルにまとめられます。
"The JPEG of 3D"と呼ばれるほど軽量な形式で、Webで一般的な3Dモデル(正確にはメッシュモデル)を扱う際のデファクトスタンダードです。three.jsの公式ドキュメントでも推奨されています。
.gltfはテクスチャ(3Dモデルの見た目を決める画像)や頂点のデータが分割して保存される形式であるのに対し、.glbはそれらのデータを1ファイルにまとめたバイナリ形式です。
複数のモデルで同一のテクスチャを共有する場合は分割されている.gltfの方が効率的な場合もありますが、ほとんどの場合は.glbの方が軽量です(three.jsメンテナのDon McCurdy氏も言及)。
Blender等で制作した3Dモデル(メッシュ)をWebで描画する場合は、とりあえず.glb形式にエクスポートすれば問題ないでしょう。
model-viewer
単純に.glbモデルをWebで表示させたいだけであれば、Googleが公開しているmodel-viewerを使えば簡単に実装できます。
model-viewerは、Googleが開発したライブラリで、HTMLタグだけで3Dモデルの表示やAR表示に対応できるのが特徴です。 遅延読み込みやキャッシュなど、3Dモデルを扱う際に面倒になりがちな仕組みも自動で組み込まれているので、手軽に導入できます。
npm install model-viewer<model-viewer
src="/models/sample.glb"
alt="3Dモデル"
auto-rotate
camera-controls
></model-viewer>model-viewerのパラメータ設定をGUIベースで簡単に調整できるツールが公式で公開されています。どのようなパラメータがあるか確認するのに便利です。
宇宙服の3Dモデル(NASA 3D Resourcesより引用)
加えて、BloomやOutlineなど、簡単にエフェクトが追加できるライブラリが別で提供されています。
model-viewer自体は、three.jsベースで実装されています。 ただ、TypeScriptで実装する時に、現状公式の型定義が提供されていないので、自前で用意する必要があります。 以下のdiscussionsで、型定義のサンプルが共有されてるのでこれを参考に実装しましょう。
model-viewerでは、ar属性を付与するだけでiOS/AndroidでAR表示が可能です。
デフォルトでは、AndroidではScene Viewer、iOSではQuick Lookというネイティブ機能でAR表示されます。
ar-modes属性でwebxrを指定しておけば、WebXR ARに対応した環境(Meta Quest 3など)でもARモードが利用できます。
<model-viewer
src="/models/sample.glb"
alt="3Dモデル"
auto-rotate
camera-controls
ar
ar-modes="webxr scene-viewer quick-look"
></model-viewer>なお、iOSのAR表示(Quick Look)では.glbではなく.usdz形式が必要です。ドキュメントではios-srcを省略してもUSDZが自動生成されると記載されていますが、度々動かないケースがissue等で報告されているため、ios-src属性に.usdzファイルのパスを明示的に指定することをおすすめします(.usdzについては後述)。
Scene Viewer
Scene Viewerは、Googleが開発しているAR表示機能で、ARCoreがサポートしているAndroid端末で利用できます。
R3F
model-viewerは手軽ですが、カスタムシェーダーの適用やARモードの挙動制御など、ドキュメントで提供されている以上のカスタマイズは難しいです。
機能が足りない場合は@react-three/dreiのuseGLTFを使ってモデルを読み込み、シーンを実装していくことになります。
import { Canvas } from "@react-three/fiber";
import { useGLTF } from "@react-three/drei";
import { Suspense } from "react";
function Model() {
const { scene } = useGLTF("/models/sample.glb");
return <primitive object={scene} />;
}
export default function App() {
return (
<Canvas>
<ambientLight />
<Suspense fallback={null}>
<Model />
</Suspense>
</Canvas>
);
}ちなみに、dreiで提供されているuseGLTFは、R3Fが提供するuseLoaderの薄いラッパーになっており、Draco / Meshoptデコーダーの設定を加えたものです。
// @react-three/drei - src/core/Gltf.tsx
// https://github.com/pmndrs/drei/blob/c9d3d0dc9473f026c83965a7eb8c7f7a1a1bf0ae/src/core/Gltf.tsx#L32
const useGLTF = (path, useDraco, useMeshopt, extendLoader) =>
useLoader(GLTFLoader, path, extensions(useDraco, useMeshopt, extendLoader));useLoaderはキャッシュやSuspenseとの連携が組み込まれているので、R3Fで3Dアセットを読み込む際は積極的に活用しましょう。
.usdz - Apple AR向け形式
.usdz(Universal Scene Description Zip)はUSDと呼ばれる形式を非圧縮Zipにパッケージした形式です。
元々、USDはPixar社が3Dシーン向けに策定したフォーマットで、Apple社とPixar社が共同で3D・AR向けに最適化したものがUSDZ形式です。
テクスチャやマテリアル、ボーンなどの3Dデータだけでなく、音声や動画もファイルとして埋め込むことができます。
USD自体はオープンな規格で、誰でも仕様を確認できます。 ただし、音声ガイドやアニメーションなど、USDZでAppleが独自に拡張している部分は公開されていないものもあり、完全にオープンとは言えない状況です。
Blender等の3Dツールでも標準で.usdzへのエクスポートに対応しているので、既存の3Dモデルを.usdz化するのは簡単です。
また、LiDAR搭載のiPhoneでは、Apple純正のReality Composerアプリで3Dスキャンして.usdzを作成することもできます。
Quick Look
Appleが提供しているQuick Lookという機能で、iPhone、iPad、Apple Vision Pro上で.usdzファイルをAR表示できます。(Macは非サポート)
iPadOS上で公式サンプルを表示した様子
以下のように、rel="ar"属性を付与したa要素で囲うだけで実装できます。
<a rel="ar" href="/models/sample.usdz">
<img src="/models/sample-thumbnail.jpg" />
</a>対応デバイスだと右下にARボタンが表示され、非対応デバイスだとクリック時に.usdzファイルがダウンロードされる挙動になっています。

宇宙服の3Dモデル(NASA 3D Resourcesより引用)
AppleのQuick Look Galleryでは、メトロポリタン美術館の展示品を音声ガイド付きのUSDZでAR表示する事例が紹介されています。
.vrm - アバター向け形式
VRMは、pixiv社が策定した.glbベースのアバター向け3D形式です。
規定されたボーン構造、顔の表情、髪などの揺れもの対応(SpringBone)といったアバター向けの機能に加え、ライセンス情報をフォーマット自体に埋め込めるのが特徴です。
現在、最新のVRMはVRM 1.0という新しい仕様になっていますが、コミュニティとしてはまだ十分広まっていないようでVRM 0系のみサポートしているアプリケーションも多いです。 破壊的変更が多くされているようなので、実装前にどちらのバージョンにするか決めましょう。
@pixiv/three-vrm
pixiv公式のThree.js向けVRMローダーです。VRM 0.xと1.0の両方に対応しています。
npm install @pixiv/three-vrmimport { Canvas, useFrame, useLoader } from "@react-three/fiber";
import { Suspense } from "react";
import { VRM, VRMLoaderPlugin } from "@pixiv/three-vrm";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
function VRMModel({ url }: { url: string }) {
const gltf = useLoader(GLTFLoader, url, (loader) => {
loader.register((parser) => new VRMLoaderPlugin(parser));
});
const vrm = gltf.userData.vrm as VRM;
// 毎フレーム更新(揺れもの等)
useFrame((_, delta) => {
vrm.update(delta);
});
return <primitive object={vrm.scene} />;
}
export default function App() {
return (
<Canvas>
<ambientLight />
<Suspense fallback={null}>
<VRMModel url="/models/avatar.vrm" />
</Suspense>
</Canvas>
);
}VRMアバター(揺れもの対応)
.sog - 3DGS形式
Gaussian Splatting(3DGS)は、2023年に発表された新しい3D表現手法です。
従来のメッシュベースの3Dとは異なり、大量の点群を配置してシーンを表現します。 写真や動画から3Dシーンを生成でき、フォトリアルな表現が得意です。
スマホアプリのScaniverseなどで手軽に撮影でき、LiDARセンサー搭載のiPhoneではより高精度なスキャンが可能です。
多くの3Dスキャンツールでは.ply形式で出力されますが、ファイルサイズが大きいため、Webで配信する場合は.spz(Niantic製)や.sog(PlayCanvas製)などの圧縮形式に変換して使用します。
変換にはPlayCanvas製のsplat-transformが便利です。
なお、Khronos Group社によりglTFへの統合が進められており、将来的には最適な形式が変わる可能性があります。
Spark
Sparkは、Three.js向けのGaussian Splattingレンダラーで、.sogや.spzなど、ほぼ全てのスプラット形式に対応しています。
npm install @sparkjsdev/sparkimport { Canvas, extend, useThree } from "@react-three/fiber";
import {
SparkRenderer as SparkRendererImpl,
SplatMesh as SplatMeshImpl,
} from "@sparkjsdev/spark";
import { useMemo } from "react";
const SparkRenderer = extend(SparkRendererImpl);
const SplatMesh = extend(SplatMeshImpl);
function Scene({ url }: { url: string }) {
const renderer = useThree((state) => state.gl);
const sparkRendererArgs = useMemo(() => ({ renderer }), [renderer]);
const splatMeshArgs = useMemo(() => ({ url }), [url]);
return (
<SparkRenderer args={[sparkRendererArgs]}>
<SplatMesh args={[splatMeshArgs]} />
</SparkRenderer>
);
}
export default function App() {
return (
<Canvas>
<Scene url="/models/scene.sog" />
</Canvas>
);
}公式でR3F向けのサンプルも用意されています。
Gaussian Splattingで撮影したワークショップ風景
その他のデータ形式
ここまで紹介した形式以外にも、Web3Dで扱うデータ形式をちょこっと紹介していきます。
パノラマ画像
パノラマ画像は通常の.jpg/.png形式で保存されますが、投影方式によっていくつかの種類があります。
- 正距円筒図法(Equirectangular): 360° × 180°の全天球を2:1の比率で表現。Insta360などの360°カメラの撮影形式
- 円筒形(Cylindrical): 水平360°のみで上下は制限あり。iPhoneのパノラマ撮影はこの形式
以下はそれぞれの形式のパノラマ画像をそのまま表示したものです。
Equirectangularは球体を平面に展開しているため上下が大きく歪んでいるのに対し、Cylindricalは水平方向のみを表現しているため歪みがありません。
各投影方式の違いについては、以下の記事で球体から平面への展開過程が図解されています。
Photo Sphere Viewer
three.jsベースのパノラマビューア専用ライブラリで、React向けにはreact-photo-sphere-viewerが公開されています。
npm install @photo-sphere-viewer/core react-photo-sphere-viewer"use client";
import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer";
export default function App() {
return (
<ReactPhotoSphereViewer
src="/images/panorama.jpg"
height="100vh"
width="100%"
/>
);
}以下はパノラマビューアでの表示例です。ドラッグで周りを見回せます。
Equirectangular形式 - 上下左右すべての方向を見回せます(画像引用元: Free Skybox)
Cylindrical形式 - 水平方向のみ見回せます(iPhoneで撮影)
VR180・VR360度動画
VR動画はパノラマ画像と同じ投影方式を動画に適用したもので、.mp4/.webm形式のメタデータにVR情報が含まれています。
- VR360: 全方位360°を撮影。周囲をすべて見回せる
- VR180: 前方180°のみを撮影。多くはステレオ(立体視)対応で、VR視聴時の映像品質が高い
three.js / R3FエコシステムではVR動画再生用のライブラリはほとんど公開されていないようですが、パノラマ画像の表示と同様の原理で実装できます。
以下はSBS(Side-by-Side)形式のVR180動画の元データと、半球に投影して表示した例です。
SBS形式のVR180動画(左目・右目の映像が横に並んでいる)
VR180動画(ドラッグで見回し、クリックで再生/一時停止)
上のビューアーの実装は以下のように実装してみていました。
- Three.jsの
SphereGeometryで180度の半球を作り、VideoTextureで動画を貼り付ける - SBS形式では左目・右目の映像が横に並んでいるので、UV座標を調整して片目分(左半分)だけを半球にマッピングする
空間ビデオ
著者は空間ビデオ周りにあまり詳しくないため、簡単な紹介だけにとどめます。
空間ビデオ(Spatial Video)は、iPhone 15 Pro以降やApple Vision Proで撮影できる映像形式で、MV-HEVC(Multiview HEVC)コーデックを使用します。
visionOS 26のSafariでは、標準の <video> タグだけで空間ビデオ・180°・360°動画の再生に対応可能なようです。
3D都市モデル - WebGIS
ここまで触れてきたデータとはだいぶ特色が違いますが、3D都市空間モデルの表現というのも存在します。
大規模な3D地理空間データをWebで表示する際には3D Tilesという仕様がよく使われます。 Cesium社が開発し、現在はOGC(Open Geospatial Consortium)の標準仕様となっています。
3D Tilesは.glbのような3Dモデル形式ではなく、大量の3Dデータを配信するための仕組みです。Google Mapsでは地図をズームすると近い部分だけ詳細な画像タイルが読み込まれますが、3D Tilesはこの考え方を3Dデータに適用したもので、カメラに近い建物は高精細に、遠い建物は簡略化して読み込みます(LOD: Level of Detail)。実際にGoogle Mapsの3Dビューも3D Tilesで実現されています。
日本では国土交通省が進めるPLATEAU(プラトー)プロジェクトで、全国の3D都市モデルがオープンデータとして公開されており、3D Tiles形式でも配信されています。
3D Tilesの主要な配信元としては、Cesium社が提供するホスティングサービスであるCesium ionや、Googleが航空写真から生成したGoogle Photorealistic 3D Tilesがあります。
CesiumJSとR3Fの相性
3D Tilesを扱う最も有名なライブラリはCesiumJSですが、独自のレンダリングエンジンを採用しているため、three.js / R3Fとは相性が良くありません。
単純に地図や都市モデルを描画するだけであれば、three.js自体のレンダリングエンジンは不要な機能が多く含まれるため、CesiumJSやdeck.glのようなGIS特化のライブラリを検討した方が適切です。
ただし、WebGIS系ライブラリの多くは現状WebXRをサポートしていないため、WebXRで都市モデルを扱いたい場合はthree.js / R3F上で描画する方が良いでしょう。
3d-tiles-renderer
R3Fプロジェクトの中で3D Tilesを扱いたい場合は、NASAが開発した3d-tiles-rendererが利用できます。three.js用に作られた3D Tilesローダーなので、three.jsのレンダリングパイプライン内で動作します。
また、r3f向けに宣言的に使えるコンポーネントもライブラリ側が用意してくれているので、非常に使いやすいです。
npm install 3d-tiles-rendererimport { Canvas } from "@react-three/fiber";
import { TilesRenderer } from "3d-tiles-renderer/r3f";
export default function App() {
return (
<Canvas>
<ambientLight />
<TilesRenderer url="/tiles/tileset.json" />
</Canvas>
);
}以下は、Cesium Ionでホストされている東京の3D都市モデル(PLATEAU)のデモです。
PLATEAU 東京都3D都市モデル(東京タワー周辺)
続いて、Google Photorealistic 3D Tilesのデモです。PLATEAUとは異なり、Googleが航空写真・衛星画像から独自に生成したメッシュデータで、同じ東京タワー周辺でもテクスチャ付きで実際の景観に近い見た目になっています。
Google Photorealistic 3D Tiles 3Dモデル(東京タワー周辺)
まとめ
Web3Dで扱う主要なデータ形式を紹介しました。
Appleが独自実装しているUSDZ周りのAR機能には音声ガイドなど魅力的な機能も多いので、ぜひオープンになってAndroidXRなどでも使われるようになってほしいところですが、XR体験の導線に関わる部分は特許も絡むため、なかなか一筋縄ではいかなさそうです。
今年リリースされる世界初AndroidXR搭載XRグラスであるProject Auraの登場で、Web3D、そしてその先のWebXRが一気に発展しそうな予感がしています。そのメインのユースケースとなるWeb3D周りの技術を、この機会に整理してみました。
仕様もドラフトだらけでまだまだ発展途上のWebXR領域。この領域がより発展することを願っています。
WebXRの今とこれからについて、sawa-zenさんという方がとてもうまく言語化してまとめているので、ぜひ興味ある方はご覧ください。
宣伝1
WebXRに関する技術について共有したり雑談できるコミュニティ、WebXR JPを昨年立ち上げて運営しています。 ぜひWebXR技術について知りたい・話したい方はぜひご参加ください。
宣伝2
sawa-zenさんが、R3Fで実装しているWebXR対応メタバースというのを開発・公開されています。
R3Fベースで開発しており、UGCでユーザーもR3Fでワールドを制作・公開でき、とても開発体験が良いです! ぜひ体験してみて下さい〜!
世界でおそらく最も精度が良いthree.js IKが実装されていたり、コミュニティのHalbyさんがVRMアバターの最適化ライブラリを実装していたり、おそらく世界一three.js/R3Fの知見が集まっています。
宣伝3
こちらも、peraさんという方がGaussian Splattingの共有サイトをthree.jsベースで開発されています。 こちらもぜひ試してみると、簡単に共有できます〜
VRが好きなWebエンジニア。WebXRやVR・機械加工などの技術が好きでものづくりしている。WebXR JPというコミュニティやWeb技術集会というVR空間内の技術イベントを運営中。
コメント
この記事についてのご意見・ご質問をお気軽にどうぞ