FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

Web上でVRゴーグルを使って没入体験ができるWebXRが面白い!

皆様こんにちは。シャープのマスクが当たったものの、未だ未開封で使いどきが分かっていない菅野です。

シャープのマスクも人気ですが、今はVRゴーグルも熱いです!
Oculus Quest 2が先代よりパワーアップしつつ価格はダウンして登場し「VR元年」到来かと言われています。(毎年言われています)
とにかく、高性能なVR機器が3万円台という気軽に買える価格(?)になったので私は発売日にGETしました!
VRです。

f:id:zakknak:20201103070817j:plain:w500

エンジニアなら自分でなにか作りたくなるよね?

ゲームも6DoFのトラッキングと左右の視差による立体視で本当にそこにいるような感覚です。
今まで平面の板に映っていたのを3Dだと思っていたのが馬鹿らしくなります。

f:id:zakknak:20201103070402j:plain:w400

そうなると、このVR世界を自由に創造したくなりますよね?
できるだけサクッと。
そこで役に立ちそうなのがWeb上でVRやARのコンテンツを作成できるWebXRという規格です。

HTML上のCanvasタグに3Dの描画をすることができるThree.jsではWebXRをサポートしているので、このライブラリ経由で割と簡単に実装することができます。

Three.jsを試す

実は以前からリモートでのミーティングに使用するために3Dのアバターを表示するブラウザアプリを作り、それをOBS経由でミーティングアプリで使うということをしていました。

使っているライブラリはThree.js と three.jsでVRM(アバターモデル)を読み込むthree-vrm、顔の位置を3Dで推測するfacemeshです。 本題ではないので詳細は割愛します。

で、これをVR化したいと思います。 threejs.org

やることは公式ドキュメントに書いてあるとおり、VRモードへ移行するボタンの設置などです。

出来上がったら、これをOculusのブラウザで開いて「ENTER VR」ボタンを押すと向こうの世界へ行けます(笑)

居ました!動き回って様々な角度から見ることができます。
PCだと普通の動画ですが、実際にOculusで見える景色はすごいですよ。

もっと色々作る

3Dキャラを表示するだけだとつまらないので、せっかくだからゲームみたいなものを作りたいと思います!

素材をつくる

まずはゲームに使う3Dモデルを作りましょう。
SculptGLと言うWeb上でモデリング出来るとても良いツールがあります。

stephaneginier.com

f:id:zakknak:20201103082404j:plain:w400

開くと球が表示されるので適当に弄ると形を変えられます。

ゲームに使う何かを適当に作っていきます。

出来ました。

f:id:zakknak:20201103082641j:plain:w400

…このゲームの方向性が決まりましたね。

Sketchfab

SculptGLはデータをSketchfabへエクスポートすることも出来ます。
Sketchfabは3Dモデルの共有サイトです。

sketchfab.com

SketchfabにエクスポートするとglTFへ変換されたものもダウンロードできるようになるので便利です。
glTFは3Dのjpegとも呼ばれ、WebGLと親和性の高いフォーマットです。

Sketchfabでは無料で公開されている作品が多いので、その中から良さげな無人島もダウンロードしておきました。

作る

Three.jsにはglTFを読み込むローダーがあるので簡単に読み込むことが出来ます。

const scene = new Scene();

// (略)

function loadGLTF(gltfLoader: GLTFLoader, url: string): Promise<GLTF> {
  return new Promise((resolve, reject) => {
    gltfLoader.load(url, data => {
      return resolve(data);
    }, p => console.log(`load: ${Math.round(p.loaded / p.total * 100)}%`), e => reject(e));
  });
}

const gltfLoader = new GLTFLoader();
const stage = await loadGLTF(gltfLoader, "Tropical_Sketchfab.gltf");

scene.add(stage.scene);

f:id:zakknak:20201103093746j:plain:w400

無人島と🥺を読み込んだら、左右のコントローラーから伸びる線を描画させます。

function buildLine() {
  const geometry = new BufferGeometry().setFromPoints([new Vector3(0, 0, 0), new Vector3(0, 0, - 1)]);
  const line = new Line(geometry);
  line.scale.z = 5;
  return line;
}

const renderer = new WebGLRenderer({canvas, "antialias": true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(canvasWidth, canvasHeight);
renderer.xr.enabled = true;

const controller1 = renderer.xr.getController(0);
const controller2 = renderer.xr.getController(1);

const controlLine = buildLine();
controller1.add(controlLine.clone());
controller2.add(controlLine.clone());

f:id:zakknak:20201103093903j:plain:w400

そして、描画毎にキャラが動いたり、コントローラーから伸びる線と接触したら消える処理を作成して描画毎に呼び出します。

const clock = new Clock();
const game = new Game(pien, scene, camera, controller1, controller2);

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
  game.onRender(clock.getDelta());
});

それと、WebXR device emulatorと言うブラウザ拡張を入れると、VR機器をエミュレートしてデバッグできるので便利です。
f:id:zakknak:20201103095226j:plain:w400

動作を確認して、多分、完成。
f:id:zakknak:20201103094059j:plain:w600

結果

PCで見るとそんなでもないですが、VRゴーグルでこのカオスな空間にいると迫りくる恐怖は半端ないです。

手元で確認できるように作ったものを公開しました。 zakknak-labo.web.app

以上

今回はVRゴーグルVRでしたが、スマホでARなども作成することが出来ます。
ブラウザから手軽に試せるのでちょっとしたコンテンツ作成が捗りそうですね。

3D空間だと表現力がより高まると思うので色々出来そうです。

それでは良いバーチャルライフを!