夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Unity Barracudaを触る。 Barracuda環境構築

本日はUnity調査枠です。

先日筆者の師であるガチ本さんとお会いした際に[Unity Barracuda]の話題が上がりました。

筆者は初めて聞く単語でどうやらUnityの話題の新機能のようなのでこの機会に触ってみます。

〇Unity Barracudaとは?

[Unity Barracuda]はUnity社によって提供されるUnity向けクロスプラットフォームニューラルネットワーク推論ライブラリのパッケージです。

docs.unity3d.com

ニューラルネットワークの言葉がさすように機械学習の環境を指します。

機械学習では大量のデータを学習させ学習済みモデルを作成することで、学習済みモデルを使用したアプリケーションで推論処理を実現します。

[Barracuda]ではデータを学習させることは想定されておらず、学習済みモデルを使用した推論実行を目的とした実行環境です。

この学習済みデータはBarracudaの場合[ONNX(Open Neural Network Exchange)]に対応しており、一般的に広く公開しているデータを使用できます。

www.youtube.com

Barracudaの環境構築

今回はUnity2020.3(LTS)を使用しています。

Barracudaの導入

BarracudaはUnityのPackageManager、Github等から導入することができます。

筆者の環境の場合PackageManagerで検索してもヒットしなかったことから今回はGitHub経由で導入していきます。

f:id:Holomoto-Sumire:20210726202256j:plain

エクスプローラーからUnityファイルがある階層から[Package]→[manifest.json]を開きます。

f:id:Holomoto-Sumire:20210726202654j:plain

②次の一文を追加します。

 "com.unity.barracuda" : "https://github.com/Unity-Technologies/barracuda-release.git"

f:id:Holomoto-Sumire:20210726203024j:plain

③Unityを開くとパッケージのインストールが始まります。 完了すると[Package]に[Barracuda]があります。

f:id:Holomoto-Sumire:20210726203828j:plain

以上でBarracudaを使用する準備ができました。

前述のようにBarracudaではONNXファイルと合わせて初めて動くことができます。次回はONNXの導入を見ていきます。

HLSLShaderのテンプレート

本日はShader枠です。

私事ですが、筆者の師匠に当たるかたとお会いしていました。話の中で8月にShaderに関するイベントを開催する流れになりました。

今回はShaderをゼロから学ぶ型や、自分自身が使いやすいように空のHLSLシェーダーのテンプレートを残します。

〇テンプレート

Shader "HoloMoto/HLSLTemplateShader"
{
    Properties
    {
        _MainColor("MainColor",color) = (1,1,1,1)       
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass{
        HLSLPROGRAM
        #pragma vertex vert
        #pragma  fragment frag
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"

        struct appdata_t
        {
            
        };

        struct v2f
        {
            
        };

        v2f vert (appdata_t v)
        {
            v2f o;

            return  o;
        }
        float4 frag(v2f i):SV_TARGET
        {
          float4 col = (1,1,1,1);
           return col;
        }
        ENDHLSL
      }
        
    }
}

〇HLSL

このShaderではURPで動かすことを想定しています。

URPでは[Package]の[com.unity.render-pipelines.universal/ShaderLibrary]にある[Core.hlsl]というHLSLファイルがあり、これがUnityでShaderを書く上で標準的な機能を提供します。

UnityにおけるC#の[Monobehavior]に当たるイメージです。

このHLSLを使用するためにCGPROGRAM~ENDCGではなくHLSLPROGRAM~ENDHLSLを使用しています。

〇Propertiesブロック

  Properties
    {
        _MainColor("MainColor",color) = (1,1,1,1)       
    }

PropertiesではUnityのマテリアルに表示したい変数を記述します。 このブロックに記述された変数はUnityのC#スクリプト側から変更できたり、マテリアルでGUIで編集できます。

〇 SubShader

SubShaderは実際のShaderの処理を記述します。

 このブロックの中にTagsブロックやPassなどがあります。

〇Tagsブロック

TagsブロックはShaderの性質を記述します。 α値(透明度)を扱うShaderやURP専用を意味するShader等属性を付けることができます。

〇Pass

Passは1回のレンダリングで処理されるShader処理を記述します。

Passブロックの中に頂点シェーダーやフラグメントシェーダーを記述します。

Passは複数記述することができ、以前記述したアウトラインを描くShaderではPassが二つ存在します。

[https://redhologerbera.hatenablog.com/entry/2021/05/27/211303:embed:cite]

これは一回目のレンダリング時にアウトラインを記述し、二回目でオブジェクト本来の姿を記述するというように処理しているためです。

Passをふやすことで複雑なShaderを記述することもできますが、レンダリング時の処理がその分増えることになるのでコストと引き換えになります。

〇HLSLPROGRAM~ENDHLSL

HLSLPRPOGRAM、ENDHLSLはShaderLab言語内で、この内部でCg/HLSL言語で記述することを意味します。

例えばHLSLPROGRAMの前にあるPropertiesブロックでは、次の様に変数の終わりに;が記述されていません。

  Properties
    {
        _MainColor("MainColor",color) = (1,1,1,1)       
    }

これはShaderLab言語と呼ばれるUnity独自の形式で記述しているためです。

HLSLPROGRAM~ENDHLSL間に記述される変数ではC、C#同様末尾に[;]を付ける必要があります。

          float4 col = (1,1,1,1);

〇struct appdata_t

[struct]はC言語などで見られる構造体を指し、[appdata_t構造体]という意味になります。

[appdata]等表されることやそもそも記述が無く[include]で使用しているコアpackageからそのまま引用することもあります。

このブロックではShaderで描画されるオブジェクトの持つ基礎情報を保持します。

〇struct v2f

[v2f構造体]は一般的に使用される頂点シェーダーで処理したデータをフラグメントシェーダーに渡すために格納する構造体です。

vertex To fragmentを略し一般的にv2fと使用されることが多いです。

〇頂点シェーダー

頂点シェーダーでは3Dモデルの頂点を処理するShaderです。

ここではオブジェクトをUnityの座標系に処理し、オブジェクトとして描画できるようにすることなどを処理します。

  v2f vert (appdata_t v)
        {
            v2f o;

            return  o;
        }

例えば次のアウトラインを描画するShaderではPassの一つで頂点を法線(頂点の持つベクトル)に拡張展開し、元の3Dモデルより大きなオブジェクトを描画することでアウトラインを描画しています。

redhologerbera.hatenablog.com

〇フラグメントシェーダー

フラグメントシェーダーでは色情報を処理します。

        float4 frag(v2f i):SV_TARGET
        {
          float4 col = (1,1,1,1);
           return col;
        }

この色情報とはデバイスごとのピクセル(解像度の単位)ごとに処理されます。

例えば、100ピクセルがあった場合、100回に分けてピクセルごとの色を出力し描画します。

以上がテンプレートのShaderになります。

UnityではShaderを新規作成することでテンプレートを使用することができますが、ここでは筆者がゼロから学ぶ型に教えやすいように用意しました。

今後開催されるイベントに関しては本ブログでも情報を載せます。

Unity Tiling,Offsetを扱うShaderを書く

本日はUnity Shader枠です。

UnityのShaderではテクスチャを用いることで単一のマテリアルで様々な表現を行うことができます。

f:id:Holomoto-Sumire:20210724200609j:plain

テクスチャを使用しているマテリアルのプロパティを見ると[Tiling]と[Offset]のプロパティがあります。

f:id:Holomoto-Sumire:20210724201327j:plain

[Tiling]と[Offset]はそれぞれ[画像を何枚並べるか]、[どの場所に画像を並べるか]に相当します。

[Tiling]を使用することでUVのx,yにそれぞれ画像を並べることができます。次の画像の例ではCubeの1面につき5×5=25のテクスチャが並べられています。

f:id:Holomoto-Sumire:20210724202154j:plain

[Offset]を使用することでUVをずらすことができます。下の画像の例では0.5ずつ画像をずらして配置していることでEdge部で面を挟んで画像がつながっているようになりました。

f:id:Holomoto-Sumire:20210724203807j:plain

〇ShaderでTiling,Offsetを扱う

今回自作のShaderでこのTiling,Offsetがマテリアルのプロパティで表示されているものの機能しない問題がり、簡単な原因でしたが備忘録として残します。

f:id:Holomoto-Sumire:20210724204524j:plain

今回は次のような簡単なコードを書きました。

Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = TransformObjectToHClip(v.vertex);
                o.uv=v.uv;
                return o;
            }

            half4 frag (v2f i) : SV_Target
            {
                half4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDHLSL
        }
    }
}

〇_MainTex_ST

[MainTex_ST]はShader内で画像を扱う際に[(画像の変数名)ST]という形で記述する4次の変数です。

これは画像のTiling、Offsetに関する値を保持する変数となります。

上述のコードでは[_MainTex_ST]を宣言しているものの内部で使用していません。

そのためuvにこの[_MainTex_ST]を掛け合わせることでTiling,Offsetを使用することができるようになります。

    v2f vert (appdata v)
            {
                v2f o;
                o.vertex = TransformObjectToHClip(v.vertex);
                o.uv=v.uv*_MainTex_ST;
                return 

f:id:Holomoto-Sumire:20210724203807j:plain

逆にTiling、Offsetを使用したくない場合は

 o.uv = v.uv

のようにオブジェクトの持つuvをそのままで使用することで実装できます。

簡単なことですが理解できるまで時間がかかりました。

HoloLensでBloomが実機で見れない現象

本日はトラブルシューティング枠です。

URP(UniversalRenderPipeline)を使用したプロジェクトでは[Bloom]のポストプロセッシングを使用することによって発光のマテリアルのグロー効果を実装することができます。

今回は一部環境でこのBloomが使用できないことが分かったので原因は不明ですが備忘録として残します。

〇Bloomとは?

[Bloom]は輝きを意味する言葉でUnityのポストプロセッシングでは発光現象を用いることができます。

Unityの描画では、Shaderで提供される機能に基づきマテリアルのパラメータを操作することで描画が行われます。

このマテリアルでEmittionもしくはそれに準する機能が提供されている場合Unityでは発光として扱うことができます。

具体的にはShader内でRGBAの値が1以上になる場合Emittionとして扱われます。(一般的にRGBは0~255で表されますが、Shaderでは0~1で表されます。)

Bloomを使用しない場合の発光表現は次のようになります。

f:id:Holomoto-Sumire:20210722204156j:plain

目のマテリアルに発光を使用していますが、光っているようにはあまり見えません。

ここで使用されるものがBloomです。

Bloomのポストプロセスを使用することでグロー効果を表現することができ空間に光がにじみ出るような表現が行えます。

f:id:Holomoto-Sumire:20210722205943j:plain

youtu.be

〇Unity2019.4(LTS)で動かない問題

Unity2019.4.18f1でBloomを使用した場合、Unityエディタ上では発光を確認することができるものの実機でBloomが現れない問題がありました。

Unityのバージョンを2020.3.13f1にアップグレードすることで実機でも確認することができるようになりました。

これはURPがUnityのバージョンに依存しているという問題が影響していると考えられます。

もしBloomを実機で見たい方はUnity2020.3を使用されることをお勧めします。

XRミーティング21年7月に参加、登壇しました。

本日はイベント枠です。

〇XRミーティングとは?

XRミーティングは関西を拠点に活動するxRコミュニティ[大阪駆動開発]や北海道を中心に活動する[DoMCN]など全国のxRコミュニティが集まって毎月第三水曜日の夜に情報共有や発表を目的としたイベントです。

筆者は大体の会で登壇させていただいています。

osaka-driven-dev.connpass.com

HoloLens Meetupなどと比べxR全般が話題になっている点や比較的少人数でシェアできる点が魅力です。

〇Holoニュース

HoloLens界隈で活躍されている山地さんの登壇した。

山地さんの最近の活動やxR界隈のニュースに関してシェアされました。

 公共事業でのHoloLensを用いた取り組みや五輪関連の画像にHoloLensがあるなど非常にマニアックな情報がシェアされました。

〇MixedReality関連のSDKの状況を調べてみた

 二人目もHoloLens界隈で活動される宮浦さんの発表です。    最近のSDKの概要と筆者のほうでも最近使用している[MixedReality Featire Tool]で提供されるSDKに関する解説が行われました。

iPhone LiDARで始める3Dスキャン

三名目はiwamaさんです。

趣味でiPhoneLiDARを触っておりその知見がシェアされました。

 iPhoneLiDARは、誰でも簡単に、どこでも、そしてiPhoneなのでモデルの共有が簡単にできるという魅了区がありります。

 欠点としてスキャンレンジが5mと短くまた精度が実測値の1~2%の誤差であり、精密さには難点があるようです。

〇WebRTCを使ったMR配信

4人目は上田さんの登壇です。nReal Lightを使用した配信システムの発表でした。

10人でMRライブ配信を見ることができたそうです。

一方的に配信するだけではなく音声通話やペイント、ARタグや3Dオブジェクトといったインタラクティブな仕組みを構築したそうです。

〇HoloLens×URP​ HoloLensで光らせたい!

 筆者の登壇では筆者が最近取り組んでいるURPに関する情報をシェアしました。

 URPは情報が少ないため以前より抱えているURPのキャプチャ映像に関する問題をシェアしました。

redhologerbera.hatenablog.com

DICOMデータをBlenderに取り込む その② 

本日は3DCGに関する記事です。

昨日は[invesalius]を導入してDICOMファイルを読み込む時点でフリーズしてしまい進めませんでした。

redhologerbera.hatenablog.com

サポートへメールを送ったところ「ファイルに問題があるかもしれない、別のファイルを試してみて」と返ってきました。(英語ですが1時間ほどで返してくれとても素早いサポートです。)

今回はまずIncesaliusのダウンロードページに並んでいるサンプルデータを用いてみます。

〇Incesaliusでサンプルデータを読み込む

①今回は狐のデータを使用します。

f:id:Holomoto-Sumire:20210719084419j:plain

②[医療画像を読み込み]からFoxの画像を入れたフォルダを選択し読み込みます。

f:id:Holomoto-Sumire:20210719084925j:plain

③前回ではこの時点でフリーズしてしまいましたが今回はきちんと読み込むことができました。

f:id:Holomoto-Sumire:20210719085053j:plain

④[Import]を選択します。

f:id:Holomoto-Sumire:20210719085230j:plain

⑤マスクを作成しモデル化するパーツを選択します。これは手動で行うこともできますが、今回は[Bone]できれいに骨が抽出できたためこのまま進めます。

f:id:Holomoto-Sumire:20210719085413j:plain

⑥[Create Surface(サーフェイスを作成)]を選択します。

f:id:Holomoto-Sumire:20210719085433j:plain

⑦3D表示が行われます。

f:id:Holomoto-Sumire:20210719085508j:plain

⑧[Export Surface]を選択し書き出します。

f:id:Holomoto-Sumire:20210719085540j:plain

ここではSTLとして出力されるためそのまま3Dプリンターで印刷することができます。

Blenderで読み込むことで3Dモデルとして扱うことができました。

f:id:Holomoto-Sumire:20210719205725j:plain

本日は動物のサンプルモデルを読み込んだので次回以降は人を読み込んでみたいです。

DICOMデータをBlenderに取り込む その①

本日は3D枠です。

本日献血を受けてまいりました。その際に医療に関する興味がわき、CTスキャンMRIなどの医療で用いられるデータをBlenderで読み込めないかと興味を持ちトライします。

〇DICOMとは?

 [DICOM…Digital Imaging and COmmunications in Medicine]はCTやMRIなどで使用される医療用画像データのフォーマットです。

 通常医療機関やそれに属する企業で用いられるデータ形式ですが、診察後などで申し込めばCD-ROMなどに焼いてデータをもらえることもあるようです。

 このDICOMの規格にそってやり取りされているようです。

ja.wikipedia.org

〇DICOMのサンプルデータを取得する。

 今回は受信していないため自分のデータを持っていないためインターネット上に広がっている公開されているデータを探しました。

 今回以下のサイトから取得します。   www.jira-net.or.jp

 

〇InVesalius

Blenderでは多くの拡張子のファイルを読み込むことができますが、DICOMが未対応です。

今回は別のソフトを挟んで変換していきます。

今回[InVesalius]と呼ばれるソフトを使用します。

①下リンクからダウンロードを行います。

invesalius.github.io

②ダウンロードしたexeファイルをクリックするとインストーラーが起動します。 現時点で日本語は対応していないようです。

f:id:Holomoto-Sumire:20210718210012j:plain

利用規約などを読み、インストールを完了させます。

⑤インストール後に言語で日本語が選択できました。

f:id:Holomoto-Sumire:20210718210112j:plain

⑥[医療画像を読み込み]からDicomデータが入っているフォルダを選択します。

f:id:Holomoto-Sumire:20210718210523j:plain

フォルダ内のすべてのファイルが読み込まれるため、Dicomフォルダを作っておく必要があります。

筆者環境ではこの画面でフリーズしてしまう問題がありました。

f:id:Holomoto-Sumire:20210718211952j:plain

なんどやっても、PCを変えても同様の問題が発生しているため一度サポートへメールを送りました。

続きはその②でお送りします。