#ChannelPlayer · Unity · VRソフト

動画の自動露出

色の設定がおかしく感じる動画は、手動でちょっと設定すれば良いのだが、写真を表示するアプリでは自動補正をかけると暗い画面が明るくなったり、明るい画面がちょうど良い感じになったりできるのだから、動画でも出来ても良いのではと、ネットをあちこち検索してみた。

そうすると、Unity Asset Storeにてちょうど良さそうなのがあったので導入してみた。

Auto Exposure Mobile Color Grading | Fullscreen & Camera Effects | Unity Asset Store https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/auto-exposure-mobile-color-grading-107079

これはカメラ側にShaderを実装して、その場で変換をかけるようなもの。Asset Storeでの写真へのリンクを示すが、いい感じになるなとは思う。Channel Playerに持ち込む際、Unity 2018から2019に上げる必要があり、そちらの手間がかかり、やっとbuildできるようになったが、取り付けただけで動作は確認できていない。

並行して、色補正は出力側のShaderに実装しているので、カメラ側のShaderで求めたパラメータを、出力側のShaderにどう渡そうかと調査検討中。フラグメントシェーダーやバーテックスシェーダーから値を取り出すのは、GetFloat()などで良いのかと思うが、意外と使っているShaderは見つからない。コンピュートシェーダーなら演算結果を取り出すのは当たり前なんだけれども、とりあえずIndie Visual Lab のUnity Graphics ProgrammingのVol.1と、ソースなどを眺めている。

2022-11-09 追記
さらに調べてみると、Auto ExposureやColor Gradingは、UnityのPost Processing Stack v2にあるので、普通はこちらを使うらしい。もっともVRアプリでは重いので使わないのが一般的のようだが、必要なShader modelを調べるとAuto ExposureはShader model 5, Color Gradingは、Shader Model 3なので、Quest2でも、OpenGL ES 3.1+AEPなら、Shader Model 5なので一応使えることになる。

現在は、Channel PlayerのSteamVR版にて、HDR(High Dynamic Rangeレンダリング)を有効にして、かつ少しでも軽くするために、Stereo Rendering Modeを Multi Passから、Single Passに変更して、VR動画再生時にAuto ExposureとColor Gradingのオンオフ出来ることを確認した。

現在は、Post Processing Stackを導入すると、左右のカメラの前に、矩形で再生中の動画のミラー映像が表示されるようになったため、左右のカメラを廃止する方向で検討中。

左右カメラの存在は、VR動画再生中に動画の前にオブジェクトを配置すると左右の目からはブレて表示されるので、それを避けるために、左右のカメラを導入して、キャプションやダイアログウィンドウ表示を左右のどちらか片方に表示するようにしていたのだが、左右カメラを廃止して、その代わり、他の動画アプリ同様 3D表示オフモードを用意することになる。

3D表示オフモードを用意するには、AVProVideoのユーザーサポート掲示板によれば、AVProVideo AssetのVer1の頃には存在したForceEye Modeを、Ver2版にポーティングすることになる。実際、AVProVideo Asset Ver2でも、AVProVideo.cgincにコードは存在するのだが、使っているShaderによっては実装されていないので、自前で改造することになる。

広告
#ChannelPlayer · VRソフト

ダイレクトジャンプ機能

Channel Playerでは、動画再生中にYボタンを押すと、プロパティダイアログが表示されます。

一番上に表示されているものは、現在再生中ファイルが保存されたフォルダ名です。ダイアログの中にはボタンが4個と、右上にキャプチャーボタンが表示されます。
4個のボタンのうち、現在再生中のファイル名を表示しているボタンにフォーカスして、このダイアログが開きますが、ダイアログを開いて、そのまま左右にスティックを動かせ、トリガーを引くと再生位置を変更し、ダイレクトジャンプを実行します。他のファイルでの再生とする場合には、上下にスティックを動かせば選択可能です。

ボタン上の再生位置をスティックの左右動作で変更する際、右端まで持って行ってトリガーを引くと、次のタイトルの先頭からの再生になります。もっともそれよりも、スティックを一つ下げてトリガーを引けば、通常は次のファイルの先頭からの再生となります。タイバーの位置が変更されている場合には、その位置からの再生となるのでご注意ください。

#ChannelPlayer · VRソフト

2D 縦長動画が大きく表示される理由

Channel Playerでは、2Dの横長動画はフルHDとなる横と縦が1920×1080ドットであることを想定してスクリーンを設置しており、RiftやQuestでスクリーンを見たときに、左右に首を振らずとも見える最大限のスクリーンとして表示している。

2Dの縦長動画を表示する場合、縦と横が1080×1920ドットであれば、1920×1080の横長のスクリーンを縦にしたときの大きさで表示されれば必要充分な仕様だとは思う。しかしChannel Playerでは、出来るだけ大きなスクリーンとしたかったために、横は1080ドットの元映像を1920ドットまで広げて表示を行う。

その結果、アスペクト比そのままだと縦は、1920 x (1920/1080) = 3413ドットまで広げることになり、縦横約1.7倍に広げて表示することになる。

2Dの縦長動画の再生は、他のアプリでは、縦が詰まってしまい横長動画よりも見劣りしてしまうが、Channel Playerでは、どーんと大きく表示される。このことをお知らせしておかないと、びっくりするかもと思い、ここに記した。

もしも、横長動画も大きく表示させたい場合には、カメラ位置をスクリーン近くに寄せてください。逆に縦長動画が大きくて困る場合には、カメラ位置をスクリーンから遠ざけてください。左側のスティックで操作可能です(カメラ移動をポーズ中のみとしている場合にはポーズしてからとなります)。

#ChannelPlayer · Unity · VRソフト

静止画のGamma → Linear 変換

Channel Playerでは、動画だけでなく静止画の描画も実装している。静止画だが180/LRフォーマットで、3D表示させる実装は今まで実現していなかったので現在実装中である。ちなみに参考にしているサイトはUnity_Panorama180Viewである。

静止画を一度表示した後で、2D/Monoから、180/LRにフォーマットを変換した場合、動画とは異なりTextureに再ロードが必要となるが、SteamVR版に比べQuest版は異様に遅いので、どこに問題があるか調べていた。

結論は、Texture2Dに展開後のGamma→Linear変換に時間がかかっていた。8000×4000ドットの静止画だと、大体4秒ぐらいかかる。

Quest版は、SteamVR版のUnity環境のビルドターゲットをWindowsからAndroidに変えたものであるので、基本的には全く同じように動作するはずである。しかし、SciFiシアターシーンでは問題無いが、Playerシーンでは、どうしても暗い映像となってしまい、Ver1.28以前では、ビルド時の色空間をLinearではなくGammaとしていた。

Ver1.29では色空間をLinearにした結果、SciFiシアターシーンも明るくなったが、Playerシーンでは、静止画表示の際、Gamma→Linearに変換することが必要となった。

それでも1920×1080程度の大きさの静止画であれば問題無かったが、評価用に用いた静止画の180/LRの静止画はその約16倍の面積であり、このときのGamma→Linear変換の時間が長くなってた。

Gamma→Linear変換は、RenderTexture(Texture2D)を画像保存すると暗い時での取り組みを参考にして、以下のようなコードを書いていた。

    private void gamma_correct(Texture2D tex)
    {
#if UNITY_ANDROID
        if (tex != null)
        {
            // ガンマ補正
            var color = tex.GetPixels();
            //Debug.Log(DateTime.Now.ToString("HH:mm:ss.fff") + ": 13 LinearToGammaSpace start");
            for (int i = 0; i < color.Length; i++)
            {
                color[i].r = Mathf.LinearToGammaSpace(color[i].r);
                color[i].g = Mathf.LinearToGammaSpace(color[i].g);
                color[i].b = Mathf.LinearToGammaSpace(color[i].b);
            }
            //Debug.Log(DateTime.Now.ToString("HH:mm:ss.fff") + ": 14 LinearToGammaSpace done");
            tex.SetPixels(color);
            //Debug.Log(DateTime.Now.ToString("HH:mm:ss.fff") + ": 15 tex.SetPixels(color) done");            
        }
#endif
    }

でも、ここに時間がかかることが判ったので、【Unity】【C#】ガンマ(Gamma, sRGB) – リニア(Linear) 値の相互変換  の情報を参考にして、以下コードに書き換えた。その結果、約4秒が0.8秒ぐらに短縮できた。その他の処理もあるので、8000×4000ドットの静止画だと残念ながらページめくるだけでも2秒ほどかかる。Quest 2はそもそも片目2Kぐらいの解像度なんだから、もっと小さい面積の静止画で十分だろうとは思う。

    private void gamma_correct(Texture2D tex)
    {
#if UNITY_ANDROID
        if (tex != null)
        {
            // ガンマ補正
            var color = tex.GetPixels();
            //Debug.Log(DateTime.Now.ToString("HH:mm:ss.fff") + ": 13 LinearToGammaSpace start");
            for (int i = 0; i < color.Length; i++)
            {
                //color[i].r = Mathf.LinearToGammaSpace(color[i].r);
                //color[i].g = Mathf.LinearToGammaSpace(color[i].g);
                //color[i].b = Mathf.LinearToGammaSpace(color[i].b);
                color[i].r = linearValue(color[i].r);
                color[i].g = linearValue(color[i].g);
                color[i].b = linearValue(color[i].b);
            }
            //Debug.Log(DateTime.Now.ToString("HH:mm:ss.fff") + ": 14 LinearToGammaSpace done");
            tex.SetPixels(color);
            //Debug.Log(DateTime.Now.ToString("HH:mm:ss.fff") + ": 15 tex.SetPixels(color) done");            
        }
#endif
    }

    private float linearValue(float gamma)
    {
        return gamma * (gamma * (gamma * 0.305306011f + 0.682171111f) + 0.012522878f);
    }
#ChannelPlayer · Unity · VRソフト

Twitch Live Stream Playerアセットの調査

Unity Asset StoreにてTwitch Live Stream Playerアセットが復活していたので試してみた。
ドキュメントもあまりないので、ソースコードを確認すると、TwitchのURLを入れると、ストリームのURLを、どこかのサーバーに接続して取得する構造になっていて、相変わらず使うのが難しいアセットのままだった。

残念。

Channel Playerが再生可能なメディアは現状、ローカルストレージとWebDAVだけで、とてもChannel Playerとは言える状態にまだ無いが、TwitchやYoutubeなどのコンテンツが再生できるチャンネルを、どうやって追加するか模索の日々は続く。Youtube-DL系を採用するのが一番早いかなとは、やはり思う。

#ChannelPlayer · VRソフト

キャプション表示

Channel Playerの動画再生中におけるキャプション表示について

以下がキャプションと呼んでいる現在再生中のファイルの情報を示すダイアログです。

キャプションを表示するには、左右のOculus Touchコントローラーのグリップを握るだけで表示されます。他の操作方法では没入感が損なわれるので、そのようなUIとしました。
表示させたままとするには、右スティックを押すと表示したままとなり、再度押すと消すことが出来ます。右スティックを誤って押し込んだ場合、表示固定となるので、その場合は再度押し込んで表示を消してください。

タイトル キャプション

・キャプションでは、右下に24時間制のデジタル時計表示があり、これはリアル世界での現在時刻です。
・その左の「Vol:0.7」は現在の音量設定となります。値域は0.0から1.0までです。これが薄く表示されているときにはMute中となります。
・左下の2D Defalutの表示の意味は、2D映像を動画デフォルトのアスペクト比で表示しているという意味となります。アスペクト比を変更すると、その設定が表示されます。

・真ん中のタイムバーは、現在再生中ファイルの再生位置を示します。これは表示だけなので、再生位置をタイムバー上で変更したい場合には、再生中にYボタンを押して、別途プロパティダイアログを開いてください。ちなみにポーズ中だと色温度や明るさなどの変更ダイアログが開きます。

・左上の文字列、上記例では「Kylee」と表示されているのは、現在再生しているファイルが存在するフォルダ―名です。
・その下、左側の「2D:Mono」は、現在の動画再生フォーマットのマッピングとパッキングの設定を示します。再生中にラジアルメニュー左側を使って変更すると、マッピングの方は2D, 360, 180, Fish180が順に表示され、パッキングの方は、LR, TB, Monoが順に表示されます。
・その右横の、「1/4」は、現在再生中のファイルの番号と、総数を分数で表示しています。
・さらに右横の「01:18/01:30 00:12」は、現在再生中のファイルの長さは1分30秒で、再生位置は1分18秒。残り12秒であることを示します。

もし、現在再生中のファイル名を知りたい場合には、プロパティダイアログを開くとボタン上に表示されます。動画再生中ほとんどの場合、ファイル名を意識する必要は無いので、キャプション表示ではフォルダ名とファイル番号だけを表示しています。

#ChannelPlayer · VRソフト

動画のフォーマット選択、及びカメラの位置について

動画のマッピングおよびパッキングフォーマットについて

3D VR動画ファイルでは、撮影方法などによって、マッピングフォーマットに違いがあるものが存在し、大きく分けて360度と180度のものがあります。その他の角度のものも存在しますがマイナーであるので特にサポートしていません。また180度のものでは魚眼レンズを使ったFishEye形式のものがあります。Channel Playerでは、それらの対応に加えて2Dの動画ファイルの方が世の中全然多いので、2Dの動画ファイル再生に対応しています。

youtubeが採用しているEqui-angular Cubemap(EAC)というマッピングフォーマットも存在していますが、Channel Playerでは未だサポートしていません。

またステレオのパッキング方法にも違いがあり、左右の目に対する映像をSide by Sideと言う左右に分かれているものと、Top BottomあるいはUp Downと言った上下に分かれているものが存在します。

それらが動画ファイルの中にパラメーターとして保存されていれば良いのですが、パッキング方法ぐらいしか保存されておらず、Channel Playerでも使っているAVPro Video Assetでパッキングの自動判定機能があるので、Autoのモードにすれば自動判別しますが、マッピングフォーマットについては手動で合わせるしかないのが現状です。

Channel Playerでのフォーマット設定方法に関して

Channel Playerでは2通りの設定方法を用意しました。シアター画面での設定方法とプレイヤー画面での設定方法です。

シアター画面での設定方法

まずシアター画面では、コントローラーのYボタンを押して、プロパティダイアログから各動画ファイルに対して、再生する前に設定することが可能です。

以下に示すものがプロパティダイアログです。ここで向かって右端から2番目の縦の列がマッピングフォーマットに対する設定ボタンです。また右端の縦の列がパッキングフォーマットに対する設定ボタンとなります。

プロパティダイアログ

マッピングフォーマットを指定するには、各動画ファイルごとに右側にあるボタンを繰り返し押すと、表示が変わり以下のものが設定可能です。

NA未設定
360360度
180180度
FishEye180180度 FishEye
2D2D ファイル
マッピングフォーマット

また、パッキングフォーマットでは、各動画ファイルごとに右端にあるボタンを繰り返し押すと、表示が変わり以下のものが設定可能です。

NA未設定
Auto自動認識
TBTop Bottom, Up Down形式
LRSide by Side, Left Right形式
Monoモノ(ステレオではないひとつのカメラによる)形式
パッキングフォーマット

プレイヤー画面での設定方法

動画再生中にフォーマットを設定する方法として、左側のラジアルメニューを表示させて設定することが出来ます。ラジアルメニューを表示させるには、Oculus Touchコントローラーのグリップを握って左側のスティックをどちらかに倒せば表示されます。スティックを操作して選択しているボタンを変更し、そこでトリガーを引けばそのボタンを押して設定を変更することができます。

左側のラジアルメニュー1

上記の左側のラジアルメニュー1が表示されておらず、後述する左側のラジアルメニュー2が表示されている場合、右側の縦に3本ラインが入ったボタンを押して、左側のラジアルメニュー1に切り替えてください。

もし現在どの形式になっているか判りにくい場合には、まず左側のボタン「Reset 2D/Mono 180/LR」を押してください。現在VR形式のいずれかになっている場合には、2Dのスクリーンに表示させるモードになります。(その後、もう一度押すと180/LRの設定に変更するので、ほとんどの場合、それで設定終了となると思います。)

続いてVR形式の場合、上側のボタン「360/180/F180/2D」を押してください。押す度にマッピングフォーマットが変更されます。180度とFishEye180度はVR映像の歪み方が異なるだけで判りにくく、しかし誤っていると歪んだ映像になってしまいます。Reset 2D/Mono表示の際、映像が円になっている場合は、FishEye形式です。

続いて、下側のボタン「LR/TB/Mono/Auto」を押して、パッキングフォーマットを合わせてください。パッキングフォーマットはReset 2D/Mono表示とした際に、映像が左右に分かれているか、上下に分かれているかを見ておけば、そのままLR、TBを指定すれば良いです。

Autoを選択しても、その場で自動判別することはなく、次回再生するときに自動判別します。ただし判別に失敗する場合もあるので、そのときは手動で設定することになります。

2D動画ファイルの再生時のフォーマット変更を実施するには、左側のラジアルメニュー2を用いますが、あらかじめ、左側のボタン「Reset 2D/Mono」を押して、2Dスクリーン表示にしてから、ラジアルメニュー2に移ると設定がスムーズに行えます。

左側のラジアルメニュー2

上記の左側のラジアルメニュー2が表示されておらず、前述した左側のラジアルメニュー1が表示されている場合、右側の縦に3本ラインが入ったボタンを押して、左側のラジアルメニュー2に切り替えてください。

ここでは、上側のボタン「2D Rotate」を押す度に、2Dスクリーンを90度ずつ回転させます。また、下側のボタン「2D Aspect」を押すと、Default, Auto, 16:9, 4:3, 16:16, 9:16のアスペクト比の変更が実施できます。DefaultとAutoは、設定するアスペクト比としては同じであり、動画ファイルの縦横の大きさに比例させたアスペクト比になりますが、手動での未設定の場合のみ、Defaultという表示になります。また動画によっては16:9のアスペクト比のまま、90度回転させて、縦画面表示するものも存在するので、動画に合わせて指定してください。

左側のボタン「3D Slim」は、VR動画ファイル再生時に用いることが出来るボタンであり、VR動画で縦横の比率がおかしい場合に、少し左右を圧縮させてスリムに見せる設定となります。これは押す度にON/OFFがトグルします。

ファイル名でのフォーマット決定方式にも対応していますが、UIから設定できることや、一つ目のファイルさえ設定すれば、残りのファイルは同じフォーマットで再生するのが基本動作なので、ほぼ使うことは無いだろうと思います。

カメラの位置について

動画再生中にフォーマット形式を合わせることが出来ると、今度は、カメラ(自分の目)の位置を変更したい場合があります。例えば2D動画表示中は、映画館に居るようにちょっと下から見上げたいなどあると思います。

その場合には、Oculus Touchコントローラーの左右のスティックを使って、カメラの位置を変更できます。通常、動画再生中にAボタンを押してポーズしている際、カメラの移動が有効になっていると思います(シアター画面の設定ダイアログで、ポーズ中だけではなく常時操作できるよう変更可能です)。UIとしては、スクリーンを移動させる方法を採用しているアプリもありますが、このメタファーは自然ではないと感じたので、見ている人がスクリーンに近づくことで拡大表示としました。

まず、右側のスティックでカメラの向きを変更することができます。また左側のスティックでは左右上下に移動することが可能です。もし縦方向に移動したい場合には、左側のスティックを押しながら操作すれば、縦方向に移動できます。

カメラの位置の変更は、フォルダー単位で覚えているので、他のファイルの再生に移った際、元の位置に戻りたい場合には、Xボタンを押してRecenterを実施してください。Oculus Quest2の場合には、Oculus TouchコントローラーのOculusボタンを長押しすることで、カメラ位置を初期化できます。

シアター画面ではカメラの移動機能はオフにしていますが、たまに位置がずれることがあるので、その時にはRecenterを実施してみてください。

そのほかの操作方法の情報は、ヘルプドキュメント(シアター画面プレイヤー画面)をご覧ください。

#ChannelPlayer · VRソフト

Exiting Channel Player

There are multiple ways to exit Channel Player.

For theater room

  1. Open the setting dialog with the B button and press the application exit button at the bottom left.
  2. As in 1., when you open the setting dialog with the B button, press and hold the B button for 2 seconds to exit. This is the same for other dialogs.
  3. Press the Oculus button on your controller and select Exit to exit.

For player scene

To end it during playback, press the B button on the controller to end playback, return to the theater room, and end the app.

#ChannelPlayer · VRソフト

Channel Playerの終了方法

Channel Playerの終了方法は複数用意しました。

シアタールームの場合

  1. 設定ダイアログをBボタンで開いて、左下のアプリ終了ボタンを押します。
  2. 1.と同様に、設定ダイアログをBボタンで開いた際、Bボタンをそのまま2秒間押しっぱなしにすると終了します。これは他のダイアログでも同じです。
  3. コントローラーのOculusボタンを押して、終了を選ぶと終了します。

プレイヤーシーンの場合

再生中に終了させるには、コントローラーのBボタンを押して再生を終了させて、シアタールームに戻って、アプリ終了させてください。