この記事は 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);
デモのほうはOrbitControlsを付けて、マウスでドラッグすると辺りを見渡せるようにしてあります。
Oculus Riftがなくてもいちおう動作するのでよかったら見てみてください。
見てもらうと分かりますが、SkyboxをつけるだけでだいぶVR感が出てきましたね。
実は
さて、今回の記事、気づいている方は気づいていると思いますが、実はWebVR特有なことはなにもしていません。
ただのWebGLによるSkyboxの実装です。
ではなぜこれを書いたのかというと、VRというとちょっと特殊なイメージを持たれている方が多いと思ったからです。
ですが、今回実装したように、 普通に WebGLの実装を行い、シーンを構築し、あとはレンダリングのときにそれをVRモードで表示するだけで、どんなコンテンツもVR化することができる、ということを知ってもらいたかったからです。
もちろん、2Dのスクリーンに映しているから成り立っている演出などもあります。
ですが、それはそれなりに高度であったり、最終的なディティールのところになるので、VRを作る上では基礎的なところをしっかりやるだけでそれなりのコンテンツが作れるのです。
次回はこれにモバイル対応を入れて見たいと思います。
(まぁ実はこれも・・・)
ということで、今回は以上です。