Help us understand the problem. What is going on with this article?

[連載] WebVR入門 vol.3

More than 3 years have passed since last update.

この記事は WebVR Advent Calendar 16日目の記事です。

ちょっと遅くなっているのはご愛嬌です;


[連載] WebVR入門 vol.1で、ごく簡単なキューブの表示をWebVRで行う、という記事を書きました。
ただあまりにシンプル過ぎてVRらしさが皆無でした。

なので今回はこれにちょっと手を入れてVRとして見栄えのするものを作ろうと思います。
今回のサンプルは前回の続きとなります。

辺りを見渡せるようにSkyboxを追加する

真っ暗闇の中にキューブが浮いているのを立体視してもなにも面白くありませんね。
というかなんなら不気味な感じですらあります。
(まぁ普段経験できないようなことが体験できるのもVRの醍醐味ですがw)

なので、ここにSkyboxを追加してみようと思います。

Skyboxって?

VRの話から若干それるのであまり詳細は説明しませんが、Sky と名前が付いていることからも分かる通り、空や遠景などを表示する手法です。
3Dの世界はとにかく負荷が高く、できるだけ人間の目を誤魔化すように誤魔化すようにと作られています。
このSkyboxも例外ではなく、遠景に当たる部分を、ワールド空間全体を覆うほど大きなキューブの中に閉じ込めて、そのキューブの中に空や遠景のテクスチャを貼ることで、まるで遠景も3Dでレンダリングされているかのように見せるテクニックです。

今回はこれを導入して、VRコンテンツの世界観をよりリアルなものにしたいと思います。

Skyboxを生成する

前回からの差分はまさにSkyboxを作る部分のみです。
以下のコードは、Three.jsのexamplesに含まれているコードです。

// Skybox
var cubeMap = new THREE.CubeTexture([]);
cubeMap.format = THREE.RGBFormat;
cubeMap.flipY = false;

var loader = new THREE.ImageLoader();
loader.load('texture/skyboxsun25degtest.png', function (image) {
    var getSide = function (x, y) {
        var size = 1024;
        var canvas = document.createElement('canvas');
        canvas.width  = size;
        canvas.height = size;

        var context = canvas.getContext('2d');
        context.drawImage(image, -x * size, -y * size);

        return canvas;
    }

    cubeMap.images[0] = getSide(2, 1);
    cubeMap.images[1] = getSide(0, 1);
    cubeMap.images[2] = getSide(1, 0);
    cubeMap.images[3] = getSide(1, 2);
    cubeMap.images[4] = getSide(1, 1);
    cubeMap.images[5] = getSide(3, 1);
    cubeMap.needsUpdate = true;
});

var cubeShader = THREE.ShaderLib['cube'];
cubeShader.uniforms['tCube'].value = cubeMap;

var skyboxMaterial = new THREE.ShaderMaterial({
    fragmentShader: cubeShader.fragmentShader,
    vertexShader: cubeShader.vertexShader,
    uniforms: cubeShader.uniforms,
    depthWrite: false,
    side: THREE.BackSide
});

var skybox = new THREE.Mesh(
    new THREE.BoxGeometry(10000, 10000, 10000),
    skyboxMaterial
);

scene.add(skybox);

上記のコードを追加すると以下のようになります。
cap.png

デモはこちら

デモのほうはOrbitControlsを付けて、マウスでドラッグすると辺りを見渡せるようにしてあります。
Oculus Riftがなくてもいちおう動作するのでよかったら見てみてください。

見てもらうと分かりますが、SkyboxをつけるだけでだいぶVR感が出てきましたね。

実は

さて、今回の記事、気づいている方は気づいていると思いますが、実はWebVR特有なことはなにもしていません。
ただのWebGLによるSkyboxの実装です。

ではなぜこれを書いたのかというと、VRというとちょっと特殊なイメージを持たれている方が多いと思ったからです。
ですが、今回実装したように、 普通に WebGLの実装を行い、シーンを構築し、あとはレンダリングのときにそれをVRモードで表示するだけで、どんなコンテンツもVR化することができる、ということを知ってもらいたかったからです。

もちろん、2Dのスクリーンに映しているから成り立っている演出などもあります。
ですが、それはそれなりに高度であったり、最終的なディティールのところになるので、VRを作る上では基礎的なところをしっかりやるだけでそれなりのコンテンツが作れるのです。

次回はこれにモバイル対応を入れて見たいと思います。
(まぁ実はこれも・・・)

ということで、今回は以上です。

edo_m18
現在はUnity ARエンジニア。 主にARのコンテンツ制作をしています。 趣味でWebGL/WebXRもいじってます。 Unityに関するブログは別で書いています↓ https://edom18.hateblo.jp/
http://edom18.hateblo.jp/
unity-game-dev-guild
趣味・仕事問わずUnityでゲームを作っている開発者のみで構成されるオンラインコミュニティです。Unityでゲームを開発・運用するにあたって必要なあらゆる知見を共有することを目的とします。
https://unity-game-dev-guild.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした