WebGPUライブラリ「UltraMotion3D」で3DのサンプルWebコンテンツを動かしてみよう

はじめに
今回は、本連載で作るWebGPUをラップした3Dライブラリ「UltraMotion3D」を使ったサンプルを紹介します。次のURLを見ればどういうものが作れるか何となく分かると思います。もちろん、必ず「Google Chrome」で見てください。右上と左下のメニューでWebページを遷移できます。
まずは、次のURLの「メニュー」→「DOWNLOAD」からサンプルをダウンロードしてください。ダウンロードした「webgpu.zip」は次のURLの内容とほぼ同じものです。
また、今回の最後で「XAMPP」の使い方も説明します。テクスチャファイルを使ったWebGPUの描画にはWebサーバが必須となります。XAMPPはローカルサーバを立てるために使います。
・UltraMotion3DのWebサイト
https://webgpu.roxiga.com
(※必ずGoogle Chromeで見てください)
UltraMotion3Dについて
次回から、1ステップずつ背景色を表示したり、シェーダーを使って三角形を表示したり、ベクトルや行列を計算したり、モデルを表示したり、テクスチャを表示したり、ボーンアニメーションしたりしてUltraMotion3Dライブラリを作っていきます。1機能ずつ肉付けしていくので無理なく実装できると思います。
今回は、それらが完成したUltraMotion3Dライブラリを使ったサンプルをお見せします。まずはボーン変形しないリジッドボディ(剛体)モデルを平行移動や回転をさせてみます。
後述のテクスチャ(ポリゴン面に模様を貼る画像)を使ったサンプル以外は、Webサーバ上ではなくてもローカルのWebブラウザ上でWebGPUコンテンツを見ることができます。つまり、まだXAMPPを使わなくてもローカルで見ることができます。
UltraMotion3Dの構成
解凍した「webgpu」フォルダの「lib」フォルダにはUltraMotion3Dライブラリを構成するJavaScript(.js)ファイルが入っています。また「models」フォルダにはモデルデータが入っています。cssフォルダのスタイルシートは「index.html」などの.htmlファイルを装飾します。
.htmlファイルがメインのファイルです。ここから.jsファイルを呼び出して実行したり、.cssファイルを呼び出したりします。
webgpuフォルダ ┠cssフォルダ(スタイルシート) ┃┠main.cssファイル(メインのスタイルシート) ┃┗mobile.cssファイル(モバイルのスタイルシート) ┠libフォルダ(UltraMotion3Dライブラリ) ┃┠BoneModel3D.jsファイル(ボーンクラス) ┃┠Material.jsファイル(材質クラス) ┃┠Matrix3D.jsファイル(行列クラス) ┃┠Model3D.jsファイル(モデルクラス) ┃┠UltraMotion3D.jsファイル(ライブラリのメイン) ┃┠Vector3D.jsファイル(ベクトルクラス) ┃┗WGSL.jsファイル(シェーダー) ┠modelsフォルダ(モデルデータ) ┃┠Box.jsファイル(ボックスデータ) ┃┠Character.jsファイル(キャラクターデータ) ┃┠MirrorBall.jsファイル(ミラーボールデータ) ┃┠RedGirl.jpgファイル(テクスチャファイル) ┃┗RedGirl.jsファイル(少女データ) ┠about.htmlファイル(アバウトページ) ┠bone.htmlファイル(ボーンページ) ┠index.htmlファイル(トップページ) ┗texture.htmlファイル(テクスチャページ)
複数のリジッドボディモデルを表示
index.htmlをGoogle Chromeで開くと、テトラポッドに似た3Dモデルがたくさん回転しています(図1)。UltraMotion3Dライブラリでは10000個の3Dモデルまで描画できます。
3Dモデルの初期化時に「init」関数が呼ばれ、3Dの描画時に「draw」関数が呼ばれ、WebGPUを初期設定するときに「initWebGPU」関数が呼ばれます。まず「index.html」ファイルのDOMが全て読み込まれたら<body>タグの「onload」属性でinitWebGPU関数を呼び出します。引数には<canvas>タグのid属性を指定します。
「models」→「Box.js」ファイルを見れば分かると思いますが、「Box」クラスは「Model3D」クラスから派生したクラスでリジッドボディモデルを扱います。リジッドボディとは、力を加えても3Dモデルが変形しないようなモデルのことです。もちろん、サイコロのように変形しなくても動くことはできます。
・サンプルコード「index.html」<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>UltraMotion3D</title> <meta name="viewport" content="width=device-width"> <link href="css/main.css" rel="stylesheet" type="text/css" /> <link href="css/mobile.css" rel="stylesheet" type="text/css" media="only screen and (max-width:480px)" /> <script src="lib/Material.js"></script> <script src="lib/Vector3D.js"></script> <script src="lib/Matrix3D.js"></script> <script src="lib/Model3D.js"></script> <script src="lib/WGSL.js"></script> <script src="lib/UltraMotion3D.js"></script> <script src="models/Box.js"></script> <script type="text/javascript"> var _models = []; function init() { for ( i = 0; i < 1000; i++ ) { _models.push(new Box()); _models[i].pos.x = (Math.random()-Math.random())*2000; _models[i].pos.y = (Math.random()-Math.random())*1000; _models[i].pos.z = Math.random()*-50000; } } function draw() { _camera.lookAt(new Vector3D(0,0,1000),new Vector3D(0,0,0),new Vector3D(0,1,0)) for (model of _models ) { model.addRotateX(-90); model.addRotateY(-90); model.draw(); } } </script> </head> <body onload='initWebGPU("CanvasAnimation");'> <canvas id="CanvasAnimation" width="2000" height="1000"></canvas> <div id="container"> <header> <h1>UltraMotion3D</h1> <nav> <a href="index.html">HOME</a> <a href="bone.html">BONE</a> <a href="texture.html">TEXTURE</a> <a href="about.html">ABOUT</a> </nav> </header> <div id="space"></div> <h2>メニュー</h2> <ul> <li><a href="index.html">HOME</a></li> <li><a href="bone.html">BONE</a></li> <li><a href="texture.html">TEXTURE</a></li> <li><a href="about.html">ABOUT</a></li> </ul> <footer> <h3>このサイトは2023年から<a href="http://vexil.jp" target="_blank">Vexil.jp</a>がテストしています。</h3> </footer> </div> </body> </html>
【サンプルコードの解説】
UltraMotion3Dライブラリを読み込むには<script>タグの「src」属性で「lib」→「Material.js」「lib」→「Vector3D.js」「lib」→「Matrix3D.js」「lib」→「Model3D.js」「lib」→「WGSL.js」「lib」→「UltraMotion3D.js」が必要です。さらに、3Dモデルデータ「models」→「Box.js」を読み込みます。
「_models」変数を空の配列で宣言します。
init関数で1000個のBoxモデル(「models」→「Box.js」ファイル内で宣言したクラス)のインスタンスを生成し、_models配列の後ろに追加します。ランダムなXYZ位置座標にBoxを配置します。
draw関数でカメラを中心に向け(lookAtメソッド)、全てのモデルのXY回転を1秒間に-90度だけ回転(「addRotateX」「addRotateY」メソッド)させて描画(「draw」メソッド)します。
bodyタグでUltraMotion3Dの中で最初のinitWebGPU関数を呼び出します。
<canvas>タグにWebGPUの3D画像を描画します。このスタイルシート(「main.css」「mobile.css」)では背景一面に<canvas>画像を描画します。