読者です 読者をやめる 読者になる 読者になる

roman-tech

テクノロジーはロマンだ。

超お手軽VR開発フレームワーク A-FRAME入門:第7回 ネオンカラーを作成してみよう

今回は男子なら誰でも憧れるネオンカラーをA-FRAMEで再現してみたいと思います!ネオンカラーの代表格といえばTRON

f:id:roman-tech:20160718133309j:plain:w400

やっぱいつの時代もネオンカラーは男心をくすぐるパワーがありますね!

目的

  • TRONのようなネオンカラーオブジェクトを作成する

本記事で学べること

  • 透過処理について学ぶ
  • 視点方向にオブジェクトを固定

開発編

早速開発にはいりましょう。
ネオンを作成するにあたりまずは実現方法を考えましょう。思いついたのは以下2つの手法です。

  • 1.透過処理でそれっぽく見せる(簡単そう)
  • 2.webGLを内部で使用しているためシェーダーで実装する(難しそう)
    今回は短時間でかつ簡単に実装したいため、ひとまず1の手法でやってみます。
    まずは白色のシリンダーを描画します。
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>neon</title>
    <script src="../lib/aframe.js"></script>
</head>

<body>
    <a-scene>
        <a-camera position="0 0 0"></a-camera>
        <a-assets>
            <a-mixin id="layer1" material="opacity: 1; color: #ffffff"></a-mixin>
        </a-assets>
        <a-cylinder mixin="layer1" mixin="common" position="0 0 -5" height="5" radius="0.1"></a-cylinder>
        <a-sky color="#000"></a-sky>
    </a-scene>
</body>
</html>

うん。。まぁこんなもんですよね。

f:id:roman-tech:20160718134336j:plain:w300

次に違う色のシリンダーを半径と透過率だけ変えて2つ描画してみましょう。

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>neon</title>
    <script src="../lib/aframe.js"></script>
</head>
<body>
    <a-scene>
        <a-camera position="0 0 0"></a-camera>
        <a-assets>
            <a-mixin id="layer1" material="opacity: 1; color: #ffffff"></a-mixin>
            <a-mixin id="layer2" material="opacity: 0.3; color: #0000ff"></a-mixin>
            <a-mixin id="layer3" material="opacity: 0.1; color: #0000ff"></a-mixin>
        </a-assets>
        <a-cylinder mixin="layer1" mixin="common" position="0 0 -5" height="5" radius="0.1"></a-cylinder>
        <a-cylinder mixin="layer2" mixin="common" position="0 0 -5" height="5" radius="0.2"></a-cylinder>
        <a-cylinder mixin="layer3" mixin="common" position="0 0 -5" height="5" radius="0.3"></a-cylinder>
        <a-sky color="#000"></a-sky>
    </a-scene>
</body>
</html>

ここで重要なのは以下の記述です。opacityは透過率を意味し、0-1の値をとります。0に近くなるにつれて透明度が高くなります。ここでは白色のシリンダーを透明度1,、青色のシリンダー(半径0.2)を透明度0.3、青色のシリンダー(半径0.3)を透明度0.1で描画しています。

material="opacity: 0.3; 

では結果をみてみましょう!

f:id:roman-tech:20160718134907j:plain:w500

やっつけではありますがそれっぽくなりましたね!!
しかし、この形状、何かに似ている。。。
ライトセーバー!!
ということで急遽ライトセーバーっぽくしていきます。
とりあえず、ライトセーバーの取っ手をつけてみます。

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>force</title>
    <script src="../lib/aframe.js"></script>
</head>
<body>
    <a-scene>
        <a-camera position="0 0 0">
            <a-entity rotation="0 0 0" position="0 0 -5">
                <a-cylinder mixin="layer1" mixin="common" height="5" radius="0.1"></a-cylinder>
                <a-cylinder mixin="layer2" mixin="common" height="5" radius="0.2"></a-cylinder>
                <a-cylinder mixin="layer3" mixin="common" height="5" radius="0.3"></a-cylinder>
                <a-cylinder height="0.5" color="#888888" radius="0.2" position="0 -2.75 0"></a-cylinder>
                <a-cylinder height="0.5" color="#444444" radius="0.2" position="0 -3.25 0"></a-cylinder>
            </a-entity>
        </a-camera>
        <a-assets>
            <a-mixin id="common" position="0 0 -5"></a-mixin>
            <a-mixin id="layer1" material="opacity: 1; color: #ffffff"></a-mixin>
            <a-mixin id="layer2" material="opacity: 0.3; color: #ff0000"></a-mixin>
            <a-mixin id="layer3" material="opacity: 0.1; color: #ff0000"></a-mixin>
        </a-assets>
        <a-sky color="#000"></a-sky>[f:id:roman-tech:20160718141021j:plain]
    </a-scene>
</body>
</html>

新しく二つのシリンダーを加えて取っ手を表現しました。また、ネオンの色も赤に変えました。

<a-cylinder height="0.5" color="#888888" radius="0.2" position="0 -2.75 0"></a-cylinder>
<a-cylinder height="0.5" color="#444444" radius="0.2" position="0 -3.25 0"></a-cylinder>
f:id:roman-tech:20160718135732j:plain:w400

なんかチープですがまぁいいでしょう。次に背景を加えてそれっぽくします。
が、ここで問題が!
ライトセーバーは3D空間上に配置されたオブジェクトと見なされているため、視線に追従できずライトセーバーが置き去りになっています。

f:id:roman-tech:20160718141021j:plain:w400

これを解決するのが以下のコードです。

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>force</title>
    <script src="../lib/aframe.js"></script>
</head>
<body>
    <a-scene>
        <a-camera position="0 0 0">
            <a-entity rotation="-30 0 0" position="0 0 -5">
                <a-cylinder mixin="layer1" mixin="common" height="5" radius="0.1"></a-cylinder>
                <a-cylinder mixin="layer2" mixin="common" height="5" radius="0.2"></a-cylinder>
                <a-cylinder mixin="layer3" mixin="common" height="5" radius="0.3"></a-cylinder>
                <a-cylinder height="0.5" color="#888888" radius="0.2" position="0 -2.75 0"></a-cylinder>
                <a-cylinder height="0.5" color="#444444" radius="0.2" position="0 -3.25 0"></a-cylinder>
            </a-entity>
        </a-camera>
        <a-assets>
            <a-mixin id="common" position="0 0 -5"></a-mixin>
            <a-mixin id="layer1" material="opacity: 1; color: #ffffff"></a-mixin>
            <a-mixin id="layer2" material="opacity: 0.3; color: #ff0000"></a-mixin>
            <a-mixin id="layer3" material="opacity: 0.1; color: #ff0000"></a-mixin>
        </a-assets>
        <a-sky src="back.jpg" rotation="0 200 0"></a-sky>
    </a-scene>
</body>
</html>

ポイントはカメラオブジェクトの中に視線と共に移動させたいオブジェクトを記載することです。以下の部分ですね。a-cameraタグの中にシリンダーを描画しています。

<a-camera position="0 0 0">
            <a-entity rotation="-30 0 0" position="0 0 -5">
                <a-cylinder mixin="layer1" mixin="common" height="5" radius="0.1"></a-cylinder>
                <a-cylinder mixin="layer2" mixin="common" height="5" radius="0.2"></a-cylinder>
                <a-cylinder mixin="layer3" mixin="common" height="5" radius="0.3"></a-cylinder>
                <a-cylinder height="0.5" color="#888888" radius="0.2" position="0 -2.75 0"></a-cylinder>
                <a-cylinder height="0.5" color="#444444" radius="0.2" position="0 -3.25 0"></a-cylinder>
            </a-entity>
</a-camera>

結果をみてみましょう!

f:id:roman-tech:20160718141600j:plain:w500

フォースを感じる!!
以下にアップロードしましたのでぜひみなさんも試めしてみてください。
force


ただし、僕のiphone6だと描画性能が弱いのか、ライトセーバーが結構チラついて表示されます。微妙ですね。。。

まとめ

なんとなくネオンカラーのオブジェクトを作成して、それを応用してジェダイの騎士の気分を味わいました。ネオンカラーはサイバー感があるのでもっと活用したいですね!もしこの手法以外でネオンカラーを実現できる方法をご存知の方は教えてください!それでは!

以下VR開発にオススメです!

© 2016 Tsukasa Horinouchi