Unity:Looking Glass を WebGL を使ってブラウザで表示する

最終更新日

注意

本記事は、Looking Glass SDK 0.14.0 での記事になります、最新版は 1.0.0 で本記事は対応していないのでご了承ください。

はじめに

Looking Glass と言うデバイスをご存知でしょうか。このデバイスはクラウドファンディングのKickstarterに昨年夏ごろ登場した裸眼で3Dが体験できる素晴らしいデバイスになります(動画)。本デバイスを Unity の WebGL プラットフォームで表示すれば Looking Glass 所持者の間で簡単にデモアプリが動かせるようになるのでその方法を調査してみました。
本ソースコードの デモ がありますので実際に試してみてください。

Unityを知らない方は、ぜひ こちらの記事 をご参照ください。

LookingGlass関連リンク

Looking Glass

まず、Looking Glass はUSB1本/HDMI1本でPC本体と接続されます。この時にそれぞれの役割としては以下のような感じだと思われます。

  • HDMIではLooking Glassに表示します、 2560×1600で表示され億域方向のドット情報が横並びで表示されますので、そのまま2Dで見るとぼやけた表示になります。
  • USB側では Looking Glass のコントローラーパネルのボタン操作、個体情報の取得などをしているようです。

WebGLプラットフォーム

次にUnityで出力されるWebGLプラットフォームについては以下のような認識でよいかと思います。

  • 各種Webブラウザで実行できる。
  • C#スクリプトは Javascript or WebAssembly に変換されて実行される。
  • グラフィックはWebGL2.0 で動作するようにUnityがよしなにしてくれる。
  • 全画面表示ができる。

問題点

問題点としては、Looking GlassのUSB部分がデバイスのアクセスになるので、Webブラウザから制御が行えない事になります。また、個体情報固有の情報を実行時に取得しているみたいでここの設定値がないとうまく描画が行えないので一度普通に実行してから個体情報を吸い出して固定値として実行することで回避しています。

Looking Glass のHDML側については、WebGLでも全画面表示が行えるため問題無くビルドして出力が行えればLooking Glassで表示されるものと思われます。

描画部分が特殊だと思われるかもしれませんがUnity側のスクリプトで奥行きなどの分割・画面の描画を行っています。(ASKA3D × LookingGlass のためのハック

とりあえず試してみた

試しに、何も考えずに Looking Glass SDK+WebGL プラットフォーム にて出力を行ってみるとやはりエラーが出力されました。このエラーはDLLを使っている事により、WebプラットフォームでのDLLの使い方はこちらを参照してね!!って感じのエラーが表示されます。

An error occurred running the Unity content on this page. See your browser JavaScript console for more info. The error was:
uncaught exception: abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/kripken/emscripten/wiki/Linking") at jsStackTrace (App.wasm.framework.unityweb:2:15158)
stackTrace (App.wasm.framework.unityweb:2:15329)
onAbort@http://localhost:56619/Build/UnityLoader.js:4:9322
abort (App.wasm.framework.unityweb:2:491060)
_dlopen (App.wasm.framework.unityweb:2:222751)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[43912]:0xcb6693 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[43491]:0xca4566)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41252]:0xc3af17 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41251]:0xc3ae8d)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41314]:0xc3e19a (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41309]:0xc3da69)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41306]:0xc3d128 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41398]:0xc44095)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[41397]:0xc43f5b (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[19556]:0x8181cd)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[44873]:0xce3bb3
UnityLoader["49b45e836a3529699091a4a490e5fa3f"]/dynCall_iiiii [Module.dynCall_iiiii] (App.wasm.framework.unityweb:2:1)
invoke_iiiii (App.wasm.framework.unityweb:2:357062)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[42707]:0xc82c7a (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[43127]:0xc93928)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[2595]:0x13472c (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[2594]:0x134698)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7670]:0x30d406 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[4713]:0x1b378e)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7654]:0x30cb7c (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[2836]:0x14a7a5)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[6732]:0x2b6005 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[6687]:0x2afcfa)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[6678]:0x2ae8f3 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[6679]:0x2aec94)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[6674]:0x2ae13c (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7827]:0x31e292)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7826]:0x31df73 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7824]:0x31de5b)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7820]:0x31d7b8 (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7816]:0x31d3fa)
@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7760]:0x314bcd (blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335 line 2 > WebAssembly.instantiate:wasm-function[7759]:0x314703)
UnityLoader["49b45e836a3529699091a4a490e5fa3f"]/_main [Module._main] (App.wasm.framework.unityweb:2:457547)
callMain (App.wasm.framework.unityweb:2:489770)
doRun (App.wasm.framework.unityweb:2:490455)
run (App.wasm.framework.unityweb:2:490641)
runCaller (App.wasm.framework.unityweb:2:489404)
removeRunDependency (App.wasm.framework.unityweb:2:21718)
UnityLoader["49b45e836a3529699091a4a490e5fa3f"]/</unityFileSystemInit</<@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335:2:406
doCallback (App.wasm.framework.unityweb:2:92746)
done (App.wasm.framework.unityweb:2:92884)
done (App.wasm.framework.unityweb:2:75827)
storeLocalEntry (App.wasm.framework.unityweb:2:74287)
UnityLoader["49b45e836a3529699091a4a490e5fa3f"]/reconcile/</<@blob:http://localhost:56619/c7816d3d-c41c-47f7-89d6-3f098e708335:2:76053
UnityLoader["49b45e836a3529699091a4a490e5fa3f"]/loadRemoteEntry [loadRemoteEntry/req.onsuccess] (App.wasm.framework.unityweb:2:74637)

動くようにする

さて、本題としてこの問題を解決します。問題としてはUSB側のアクセス部分のDLLが問題となっていそうなので、DLLを使っている部分をすべて削除してしまえば問題なさそうですので強引に行ってみましょう。

Looking Glass を使えるようにする

公式ブログなどを見てやりましょう。



DLL、関連スクリプト削除(スキップOK)

ここの手順はやらなくても動くのでスキップしても問題ありませんが、DLL関係が残っていると気持ち悪いので削除します。

  • HoloPlay/Core/Scripts/HIDapi フォルダを削除
  • HoloPlay/Core/Scripts/HIDapi ファイルを削除

Unityのインスペクター上で消えていないことがあるので、残っていたら削除しましょう。

Unity再起動

DLL・API削除に伴い、Unity側がキャッシュファイルなどで復元してしまうことがあるので再起動しましょう。

DLL参照部分を無効にする

以下、2つのスクリプトの先頭行に「#define EEPROM_DISABLED」と追加しましょう。

  • HoloPlay/Core/Scripts/Config.cs に Define を追加
  • HoloPlay/Core/Scripts/EEPROMCalibration.cs に Define を追加
#define EEPROM_DISABLED
//Copyright 2017 Looking Glass Factory Inc.
//All rights reserved.
//Unauthorized copying or distribution of this file, and the source code contained herein, is strictly prohibited.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using HoloPlay.Extras;
using UnityEngine;
using UnityEngine.Events;

namespace HoloPlay
{
    [ExecuteInEditMode]
    public static class Config
    {
#define EEPROM_DISABLED
#if !EEPROM_DISABLED
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using System.Reflection;

namespace HoloPlay
{
    public class EEPROMCalibration
    {

個体固有の情報を読み込んだと勘違いさせる

Config.cs の当該個所に、「eepromFound = true;」を追加します。

#if !EEPROM_DISABLED
            // 省略
#else
            eepromFound = true;
#endif
            if (!eepromFound)
            {

個体固有の情報を取得して強制的に書き換える

USBが動作しなくなっているので別プロジェクトを作って) 一度普通にLookingGlassを起動して、以下の情報を取得しましょう

  • 実行してから「HoloPlay Capture」を選択。
  • インスペクターの表示を「Debugに切り替える」。
  • Quiltスクリプトに表示されているConfigの設定値をメモ。

以下の個体情報をメモしておいてください。Serialに「0000」などが表示されていると上手く読み込めていないので注意してください。

次に、Config.cs の以下のソースコードの固有値情報を上でメモした情報に書き換えてください。

        /// <summary>
        /// Type for visual lenticular calibration
        /// </summary>
        [Serializable]
        public class VisualConfig
        {
            public string configVersion = "1.0";
            public string serial = "LKG-2K-01409";
            public ConfigValue pitch = new ConfigValue(47.57965f, 1f, 200, "Pitch");
            public ConfigValue slope = new ConfigValue(-5.443152f, -30, 30, "Slope");
            public ConfigValue center = new ConfigValue(-0.07010868f, -1, 1, "Center");
            public ConfigValue viewCone = new ConfigValue(40, 0, 180, "View Cone");
            public ConfigValue invView = new ConfigValue(1, 0, 1, "View Inversion", true);
            public ConfigValue verticalAngle = new ConfigValue(0, -20, 20, "Vert Angle");
            public ConfigValue DPI = new ConfigValue(338, 1, 1000, "DPI", true);
            public ConfigValue screenW = new ConfigValue(2560, 640, 6400, "Screen Width", true);
            public ConfigValue screenH = new ConfigValue(1600, 480, 4800, "Screen Height", true);
            public ConfigValue flipImageX = new ConfigValue(0, 0, 1, "Flip Image X", true);
            public ConfigValue flipImageY = new ConfigValue(0, 0, 1, "Flip Image Y", true);
            public ConfigValue flipSubp = new ConfigValue(0, 0, 1, "Flip Subpixels", true);
            [NonSerialized] public string loadedFrom = "not loaded -- default used";
            [NonSerialized] public bool loadedSuccess = false;
        }

お疲れ様です

以上で完了になります。

最後に

デモを作成したので皆さまの環境で動くか確認してみてください。おそらく動かないはずです、個体の情報はそれぞれの環境で違いますので(涙)

よい Looking Glassライフを!!







よければ、SNSにシェアをお願いします!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする