ハイライト
Appleはネイティブの
<model>要素をvisionOSからiOS、iPadOS、macOSへ広げます。開発者はJavaScriptライブラリを追加せず、1行のHTMLだけでWebページにインタラクティブな3Dモデルを埋め込めます。AR Quick Lookと立体レンダリングにも対応します。
主要内容
Webで3Dモデルを表示するには、これまで実質的に2つの道しかありませんでした。Googleのmodel-viewerを導入するか、Three.jsで自前のレンダリングパイプラインを組むかです。どちらも大量のJavaScriptを読み込む必要があり、visionOSでは立体レンダリング(stereoscopic rendering)のパフォーマンス負荷にも別途対応しなければなりません。
AppleはまずvisionOSでネイティブの<model>要素を導入しました。今、この要素がiOS、iPadOS、macOSのSafariにも来ます。同じ1行のマークアップが、すべてのAppleプラットフォームで動作します。
(00:37)
<model>はネイティブHTML要素で、ブラウザが直接レンダリングします。visionOSでは立体レンダリングが標準で備わり、iPhoneやiPadでも滑らかに操作できます。W3Cで標準化が進んでいるWeb標準でもあり、コードは将来に向けて互換性を持ちます。この要素に対応していないブラウザ向けには、Appleが公式のpolyfillをフォールバックとして提供しています。
(00:48)
このセッションではアウトドア用品のECサイトを例に、3Dアセットの取得から公開前の最適化までの完全な流れを示します。アセットを取得する方法は3つあります。iPhoneで実物をスキャンする、Blenderなどのツールでゼロから作る、AIで生成する、の3つです。セッションでは、キャンプ用マレットの数枚の写真からTripo3Dで数分以内にUSDZモデルを生成する流れが紹介されました。
(02:22)
USDZはAppleが推奨する形式です。Universal Scene Descriptionをzipパッケージ化した形式で、ジオメトリ、マテリアル、テクスチャ、アニメーションを1つのファイルに収めます。Safariは他の形式にも対応しますが、互換性の観点ではUSDZが第一候補です。
(03:17)
詳細内容
モデルの読み込みとフォールバック
<model>の使い方は<img>や<video>と同じくらい直感的です。src属性でUSDZファイルを指すだけです。
<!-- src 属性を使う -->
<model src="mallet.usdz"></model>
<!-- <source> 子要素で MIME タイプを指定する -->
<model>
<source src="mallet.usdz" type="model/vnd.usdz+zip">
</model>
(04:19)
フォールバックも簡単です。<model>の内側に<img>を置くと、この要素に対応していないブラウザでは画像が表示されます。
<model id="mallet" src="mallet.usdz">
<img src="mallet.png"
alt="Rubber mallet with wooden handle">
</model>
(04:39)
ポイント:
<model>の内側に<img>をネストして、自然なフォールバックを実現します- 古いSafariや
<model>非対応ブラウザでは画像が自動的にレンダリングされます - ユーザーは少なくとも商品の静的ビューを見られます
3Dモデルファイルは数十MBになることが多く、読み込みに時間がかかります。readyプロパティは、モデルの読み込み完了時にresolveされるPromiseを返します。
<model id="mallet" src="mallet.usdz"></model>
<script>
const model = document.getElementById("mallet");
model.ready.then(result => {
// Hide the loading indicator
}).catch(error => {
// Loading failed, show fallback
});
</script>
(05:09)
ポイント:
model.readyはPromiseで、モデルの解析が完了するとresolveされますthenコールバック内でloadingアニメーションを非表示にしますcatchコールバックで読み込み失敗を処理し、フォールバック内容を表示します
<model>にまったく対応していないブラウザにはpolyfillを使えます。
<script type="module">
if (!window.HTMLModelElement) {
import("model-element-polyfill.js").then(() => {
// Polyfill ready to use
});
}
</script>
(05:39)
ポイント:
window.HTMLModelElementでネイティブ対応を検出します- 非対応ならpolyfillスクリプトを動的に読み込みます
- polyfillはvisionOSの立体レンダリングのようなハードウェア依存機能までは再現できません
スタイルとインタラクション
<model>は独自の仮想空間にレンダリングされ、ページの背景を継承しません。要素に直接background-colorを設定する必要があります。
<model id="mallet" src="mallet.usdz"></model>
<style>
model {
background-color: #f4f1ec;
}
</style>
(06:13)
ポイント:
- 背景色は常に不透明で、透明度を含む色は不透明色に変換されます
<model>要素へ直接CSSを書くことで見た目を制御できます
最も単純なインタラクションは、ユーザーがモデルを自由に回転できるようにすることです。stagemode="orbit"属性を追加します。
<model id="mallet"
src="mallet.usdz"
stagemode="orbit">
</model>
(06:47)
ポイント:
stagemode="orbit"により、ユーザーはモデルを左右に自由回転できます- 上下方向に傾けて指を離すと、モデルはばねのように元の角度へ戻ります
- 回転中に一部が切れないよう、モデルは自動的に少し縮小されます
視点をカスタマイズしたい場合は、JavaScriptでentityTransformを操作します。先にstagemodeを無効にする点に注意します。
<model id="boot" src="boot.usdz"></model>
<button id="button-side">Side</button>
<button id="button-reset">Reset</button>
<script>
const model = document.getElementById("boot");
const initialTransform = model.entityTransform;
document.getElementById("button-side")
.addEventListener("click", () => {
const transform = new DOMMatrix();
transform.rotateSelf(0, 135, 0);
model.entityTransform = transform;
});
document.getElementById("button-reset")
.addEventListener("click", () => {
model.entityTransform = initialTransform;
});
</script>
(07:31)
ポイント:
entityTransformを使う前にstagemode属性を削除するか、"none"に設定しますDOMMatrixは3D空間におけるモデルの向きを表しますrotateSelf(0, 135, 0)はY軸を中心に135度回転します- リセット用に
initialTransformを事前に保存します - カスタム回転ではモデルが切れる可能性があるため、位置を手動調整する必要があります
視点を直接切り替えると唐突に見えます。requestAnimationFrameで滑らかな遷移を実装します。
const model = document.getElementById("boot");
const duration = 500;
let currentAngle = 0;
let animationId = null;
function animateTo(targetAngle) {
if (animationId) cancelAnimationFrame(animationId);
const startAngle = currentAngle;
const startTime = performance.now();
function step(now) {
const progress = Math.min((now - startTime) / duration, 1);
const ease = 1 - Math.pow(1 - progress, 3);
currentAngle = startAngle + (targetAngle - startAngle) * ease;
model.entityTransform = new DOMMatrix().rotateSelf(0, currentAngle, 0);
if (progress < 1) animationId = requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
document.getElementById("button-side").addEventListener("click", () => animateTo(135));
document.getElementById("button-reset").addEventListener("click", () => animateTo(0));
(08:35)
ポイント:
- まず
cancelAnimationFrameで実行中のアニメーションをキャンセルし、衝突を防ぎます ease = 1 - Math.pow(1 - progress, 3)でease-outのイージングを実現します- 各フレームで新しい
DOMMatrixを使ってentityTransformを更新します - 500ミリ秒の長さは、応答性と視覚的な滑らかさのバランスを取ります
アニメーション再生
USDZファイルにはBlenderやMayaで作ったアニメーションを埋め込めます。<model>は既定で最初のアニメーショントラックを再生し、JavaScriptで再生速度を制御できます。
<model id="bottle" src="bottle.usdz"></model>
<button id="button-play" onclick="play(5)">
Play
</button>
<button id="button-reverse" onclick="play(-5)">
Reverse
</button>
<script>
const model = document.getElementById("bottle");
function play(rate) {
model.playbackRate = rate;
model.play();
}
</script>
(10:07)
ポイント:
model.play()でアニメーション再生を開始しますplaybackRateで再生速度を制御し、正の値は正方向、負の値は逆再生です- 例では5と-5を使って、5倍速の正再生と逆再生を実現しています
AR Quick Look
<model>を<a rel="ar">タグで包むと、iOSとiPadOSのユーザーはタップして直接AR Quick Lookに入れます。
<a rel="ar" href="bottle.usdz">
<model id="boot" src="bottle.usdz"></model>
</a>
(11:06)
ポイント:
<a rel="ar">は<model>と同じUSDZファイルを指します- iOS/iPadOSではネイティブAR体験を起動します
- visionOSではモデルが立体レンダリングで表示され、ユーザーはページから商品を「引き出して」確認できます
コマンドライン最適化ツール
usdcrushはUSDZファイルサイズを大幅に圧縮できます。セッションの例では、7.9 MBのブーツモデルを1.9 MBまで圧縮し、肉眼で分かる画質劣化はありませんでした。
(12:39)
usdrecordはUSDZファイルからサムネイルやフォールバック画像を一括レンダリングできます。商品カタログ全体を走査してfallback画像を自動生成するスクリプトを書けば、手動のスクリーンショットは不要です。
(13:10)
この2つのツールはmacOSにプリインストールされており、USDツールスイートの一部です。
重要ポイント
1. EC商品ページを1行で3D化する
既存の商品画像を<model>タグに置き換え、同じUSDZファイルを読み込みます。ユーザーはページ上で商品を回転して細部を確認し、タップしてARモードに入り、自宅に置いた見た目を確認できます。入口は1行のHTMLです。
- 実装の考え方:
usdrecordでfallback画像を一括生成し、<model>内に<img>をネストしてフォールバックを作り、外側を<a rel="ar">で包んでAR入口を用意します
2. ポートフォリオサイトでインタラクティブな3D展示を行う
デザイナーや建築家は、自分のWebサイトで3D作品を直接展示できます。訪問者はファイルをダウンロードせず、ブラウザ内でモデルを回転・確認できます。stagemode="orbit"の1行でインタラクションを実現できます。
- 実装の考え方: USDZ形式で書き出し、
<model stagemode="orbit">で直接埋め込み、CSSで背景色を設定してページの雰囲気になじませます
3. 教育アプリで3Dモデルを解説する
生物の授業では細胞構造を、歴史の授業では復元された文物モデルを表示できます。entityTransformとrequestAnimationFrameでプリセット視点の切り替えを実装し、「断面図」ボタンを押すと特定角度へ滑らかに回転させます。
- 実装の考え方: いくつかの視点角度を定義し、
animateTo()関数でイージング付きの視点切り替えを実装し、playbackRateでモデル内蔵アニメーションを制御します
4. AI生成3Dアセットのワークフロー
Tripo3DやMeshy.aiを使い、数枚の商品写真からUSDZモデルを生成し、usdcrushで圧縮してデプロイします。プロの3Dモデリングスキルは不要です。
- 実装の考え方: 写真 -> AIでUSDZを生成 ->
usdcrushで圧縮 ->usdrecordでfallback画像を生成 -> 公開
5. 3Dコンテンツのクロスプラットフォーム配信
同じHTMLコードでiPhone、iPad、Mac、Vision Proに3Dコンテンツを表示できます。visionOSでは立体的な奥行き効果も加わります。polyfillを組み合わせれば、ネイティブ<model>非対応ブラウザもカバーできます。
- 実装の考え方:
window.HTMLModelElementを検出し、存在しない場合はpolyfillを読み込んで互換性を最大化します
関連セッション
- Explore immersive website environments — visionOS上の没入型Webサイト環境APIを詳しく学べます
- What’s new for the spatial web — WWDC25の空間Web機能を深く掘り下げます
- What’s new in USD and MaterialX — USDエコシステムとコマンドラインツールの詳しい解説です
- Get started with Reality Composer Pro 3 — 3Dアセット制作ツールです
- Create 3D models for your spatial apps — 3Dモデル制作のベストプラクティスです
コメント
GitHub Issues · utterances