42
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ようこそジャパリARへ!

Posted at

ジャパリAR.png

DBX-ugfVwAIKQDe.jpg

私は@jyuko、ちょっと前にA-Frameでジャパリパークてきなものを作ったヒトのフレンズだよ。

ようこそジャパリVRへ!

今回は、WebARを使ってMMDを表示させてみたよ!

WebAR? 何それー!

WebARハ、Google Tangoノ機能ヲWebブラウザデ使エルモノダヨ!
マダ実験的ナ機能ダケド、色々ト楽シイ使イ方ガデキルヨ。
詳シイコトハ、GET ARサンガ記事ニシテクレタカラ、ソッチヲ見ルトイイヨ!

Tango対応スマホで実装するWebARとは?簡単なARアプリ開発をしてみた

(その節はありがとうございました)

説明してやるのです

GET ARの記事にも書いているですが、メインのシーンは通常のThree.jsと同じように実装すればいいのです。サードパーティ製のライブラリだって使えるのですよ。

フレンズを召喚したいのなら、MMDLoader.jsを使って、以下のコードを足すのです。
OutlineEffectを使うと何故かカメラ映像が表示されなくなるので、一旦無効にしておいたのです。我々は賢いので。

index.html
<script src="../../libs/third_party/mmdparser.min.js"></script>
<script src="../../libs/third_party/ammo.js"></script>

<script src="../../libs/third_party/TGALoader.js"></script>
<script src="../../libs/third_party/MMDLoader.js"></script>
<script src="../../libs/third_party/OutlineEffect.js"></script>
<script src="../../libs/third_party/CCDIKSolver.js"></script>
<script src="../../libs/third_party/MMDPhysics.js"></script>

<script>
    var model, mesh, helper, effect, ikHelper, physicsHelper;
    var clock = new THREE.Clock();

    function init(){
        ...
        // 処理を最初の方に持ってくる
        renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );

        effect = new THREE.OutlineEffect( renderer );

        //var modelFile = 'アルパカ・スリ/Model/アルパカ・スリ.pmx';
        var modelFile = 'トキ/Model/トキ.pmx';
        var vpdFiles = ['普通の撮影ポーズ/ミクvpd/01.vpd'];
        var vmdFiles = ['Rick式サーバルメトロノーム/サーバルメトロノーム.vmd'];

        helper = new THREE.MMDHelper();
        var loader = new THREE.MMDLoader();

        // Poseの実装例
        loader.loadModel( modelFile, function ( object ) {
            model = new THREE.Object3D();
            mesh = object;
            mesh.position.z = -1.5; // 1.5m前方に表示
            mesh.scale.set(0.1, 0.1, 0.1);
            model.add( mesh );
            scene.add( model );

            var vpdIndex = 0;
            function loadVpd () {
                var vpdFile = vpdFiles[ vpdIndex ];
                loader.loadVpd( vpdFile, function ( vpd ) {
                    helper.poseAsVpd( mesh, vpd );
                }, onProgress, onError );
            }
            loadVpd();
        });

        /*
        // Motionの実装例
        // TODO:ブラウザが頻繁に落ちるので注意
        loader.load( modelFile, vmdFiles, function ( object ) {
            model = new THREE.Object3D();
            mesh = object;
            mesh.position.set(0, 0, -1.5);
            mesh.scale.set(0.1, 0.1, 0.1);
            model.add( mesh );
            helper.add( mesh );
            helper.setAnimation( mesh );
            scene.add( model );

            ikHelper = new THREE.CCDIKHelper( mesh );
            ikHelper.visible = false;
            scene.add( ikHelper );

            helper.setPhysics( mesh );
            physicsHelper = new THREE.MMDPhysicsHelper( mesh );
            physicsHelper.visible = false;
            scene.add( physicsHelper );
            helper.unifyAnimationDuration( { afterglow: 2.0 } );
        });
        */
        ...


        renderer.domElement.addEventListener("click", function(event) {
            pos.x = event.pageX / window.innerWidth;
            pos.y = event.pageY / window.innerHeight;
            // 位置と向きを基準に合わせる
            mesh.position.set(0, 0, 0);
               mesh.rotation.set(-Math.PI/2, 0, -Math.PI/2);
            picking();
        });
        ...
    }
    ...

    function updateAndRender() {
        ...
        helper.animate( clock.getDelta() );
        renderer.render( scene, cameraPersp );
        // TODO:OutlineEffectをかけると、カメラ映像が表示されない
        // effect.render( scene, cameraPersp );
        
        requestAnimationFrame( updateAndRender );
    }
</script>

あとは、occlusionサンプルと大体同じなのです。どうですか? わかったのですか?

ここまでできれば、WebAR対応のブラウザで表示するだけですが、MMDの多くは再配布NGなのでローカルにWebサーバを立てて、LANからアクセスしやがれなのです。
ちなみに我々は、Macでapachectlを使って、WiFi経由でLAN接続しているのです。

apacheを使ってローカルサーバーを構築する方法

Macがないなら、自力でなんとかするのです。我々は忙しいので。

気をつけるんですのよ

three.jsはchromium-webarに同梱されていますけれど、MMDLoader.jsとバージョンが合っていないと、MMDが表示されないことがありますわ。GitHubからMMDLoader.jsをダウンロードする際にbuildフォルダに入っているthree.jsを使った方がいいですわよ。
そのとき、一行だけコード修正する箇所がありますの。詳しくは、chromium-webarのREADMEに書いてありましてよ。

case 0x8b5e: case 36198: return setValueT1; // SAMPLER_2D  // case 36198: Added by WebAR

それと、MMDをLoadすると、ChromiumARブラウザが不安定になって、アプリ落ちが発生しやすくなりますの。できるだけファイルサイズの小さいモデルやモーションデータを使った方が安定しますわ。

Screenshot_20170604-091824.png

あとがき

WebARで何を作ろうかと考えたとき、Tango Unity SDKの方が機能は充実しているし、パフォーマンスもよいので、three.jsのサードパーティ製ライブラリを組み合わせる使い方がいいなと思いました。
いわゆるWebのエコシステムってやつです。

UnityにインポートしたMMDをAndroidアプリに利用するのは結構面倒(できる人にはできるらしいけど)で、その点WebARならMMDLoader.jsを使ってそのまま読み込めるので簡単です。MMDに限らず、各種3DフォーマットのLoaderは充実しているので、様々なモデルを手軽に表示することができます。

Tango対応スマートフォンがないと動かないのと、ChromiumARブラウザが不安定で重たいモデルだと頻繁にアプリ落ちしてしまうのが難点ですが、いずれ端末も増えて、WebARもChromeにサポートされる頃には安定するでしょう。

クレジット

今回お借りしたもののリストです。

googlevr/chromium-webar
https://github.com/googlevr/chromium-webar

three.js
https://threejs.org/

MMDLoader.js(@takahirox
https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/MMDLoader.js

536式トキ(@琥沙郎/536
http://3d.nicovideo.jp/works/td29233

536式アルパカ・スリ(@琥沙郎/536
http://3d.nicovideo.jp/works/td29307

普通の撮影ポーズ(@KEITEL
http://seiga.nicovideo.jp/seiga/im5162984

Rick式サーバルメトロノーム(@Rick
http://www.nicovideo.jp/watch/sm30759263

けものフレンズ ロゴジェネレータ(@hiruberuto
http://qiita.com/hiruberuto/items/463219b158d74668e7d9

42
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?