夜風のMixedReality

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

Substance PainterとMRGTのChannelMapを使用してUnityでビジュアルをリアルにする (サンプル配布)

本日はUnityでのMRGT応用枠です。

MRGTで提供されているコア機能のGraphicsTools StandardシェーダーとSubstance Painterの機能を応用していく手法を紹介します。

今回はモデリングツールとSubstancePainter、そしてUnityを使用していきますが、メインとしてMRGTの機能紹介記事のためサンプルとして以下のリンクより素材を無料で入手できるようにしています。 

holomotoranger.booth.pm

〇完成品

こちらがUnityでのビジュアルになります。

〇SubstancePainterでグラフィックを作成

前提条件としてSubstanePainterではUV展開はできないためBlender等のモデリングツールでモデリングを行う際にUV展開を終えている必要があります

①SubstancePainterに3Dモデルを読み込みます。

②ベイクを行います。

③テクスチャを作成します。ここではSubstancePainterの解説は割愛します。

④上部タブファイルからテクスチャを書き出しを選択します。

これによってテクスチャが書き出されます。

〇ChannnelMapの作成

 Substance Painterから出力された段階では基本色となるMainMapのほかにMetalicMap、RoughnessMap、AlphaMap、EmissionMapが出力されます。

 これらをUnityのマテリアルで扱う際はそれぞれのパラメータに画像を指定することになりますが、画像数が増えるほどGPU上のメモリーに情報が保持される為パフォーマンスが落ちていきます。

 PCアプリケーション等では問題にならない場合がありますが、xRアプリケーションの場合は特に高コストな処理として避けられがちになります。

 そこでGraphicsTools StandardシェーダーにはChannnelMapと呼ばれる機能が提供されています。

redhologerbera.hatenablog.com

ChannnelMapは上述のテクスチャのうち、MetalicMap、RoughnessMap、EmissionMapに加えAOMapをまとめた一枚の画像のことを指します。

 金属感や光沢、AO、発光といった情報は金属ー非金属、つるつるーざらざら、明るいーくらい、光っているー光っていないとそれぞれ0~1の情報で扱うことができます。

 唯一、発光に関しては何色に発光しているのか?という情報が必要になりますが、これはEmissionという別のパラメータで発光色を決めることができるためChannnelMapでは上記の情報をそれぞれR,G,B,A(透明度)として画像が持てる形にまとめたテクスチャとして使用することができます。

 重なる点もありますがChannnelMapを簡単に表すと、4枚必要であった画像を1枚の画像で済むようにして3枚分の画像処理分のパフォーマンスを向上させるというものです。

 ChannnelMapを作成するためにはTextureMargeを使用することが一番早いと思われます。

 TextureMargeは以下のGitHubで入手することができる有志が開発したOSSのソフトウェアになります。

①TextureMerge.exeを起動します。

②赤にメタリック、緑にオクリュージョン(今回は無し)、青にEmission、アルファにラフネスと各スロットに対応する画像をD&Dします。

オクリュージョンには真っ白な画像をアタッチします。これはオクリュージョンの場合影のように値を出力の値に掛け合わせるため白=1であれば結果に影響することがありません。

  Mergeを選択することでChannelMapが作成されます。

〇MRGTシェーダーでUnity上でビジュアルを構築

MRGTの導入に関しては以下の記事を参考にしてください。

redhologerbera.hatenablog.com

Unity2020以降のバージョンであればビルドイン、URPどちらのプロジェクトでも実行することができます。23年現在HDRPのみ対応していません。

①モデルとChannelMapおよびMainMap、NormalMapの3枚をインポートします。

②新規でマテリアルを作成します。

③マテリアルのシェーダーをGraphicsTools Standardに変更します。

④ChannelMapにチェックを入れ有効化し、作成したChannelMapをアタッチします。

これで一気に深い見た目となったことがわかると思います。

作業は以上です。

これで一気に深みのあるビジュアルが再現できました。

使いこなすことで荒れた金属肌のような表現なども行えます。

本日は以上です。

HoloLens2でキオスクモードを使用する(23年版) キオスクモードの設定

本日はHoloLensのキオスクモードを紹介します。

〇キオスクモードとは?

キオスクモードとはWindowsデバイスで使用できる店頭やデモンストレーションの場などでお客さんが使用することを前提に機能を制限した端末のモードを指します。

 一般的な例では図書館の検索システムなどがあります。

 

 図書館においてある検索用のPCは一般的にWindowsOSが搭載されていますが、お客さんは検索アプリ以外のWindowsの機能を使用することはできません。

 このようにPCから指定したアプリのみが動くようになるモードがキオスクモードです。

〇HoloLens 2の場合

HoloLens2の場合はジェスチャによってシステムを操作します。

また装着者の見ている映像はキャスティング(ミラーリング)を行っていない場合は外部から把握することは困難です。

 こうした都合上キオスクモードを設定していない場合お客さんが意図せずホーム画面を開いてしまうことやアプリケーションを落としてしまうということがあります。

☆余談 勝手にブルームするなよ

 『勝手にブルームするなよ』とは私の師であるがち本さんの体験により生まれた言葉です。

 HoloLens 1st時代はホーム画面への移行ジェスチャはブルームという動作によって行われていました。

 がち本さんはデモ中に(HoloLensを知っている)お客さんによって意図的にブルーム動作をされるということがあったようで、その際に生まれた言葉が『勝手にブルームするなよ』になります。

 HoloLens 1st時代はHoloLens装着者の隣で別の人がブルームジェスチャをした場合も反応することがあり、この場合も『勝手にブルームするなよ』というミームを使用していました。

〇デバイスポータルへの接続

 キオスクモードへ設定するためにはWindowsPCからHoloLensのデバイスポータルへ接続する必要があります。

 USBによる有線接続とWindowsPCとHoloLens2が同じネットワークに接続している場合に使用できる無線接続があります。

 今回は無線接続を紹介します。

①HoloLens2の設定アプリでネットワークと更新から開発者モードを有効にしてデバイスポータルの機能を有効にします。(初回のみ)

  ②HoloLens側のIPアドレスを調べます。

IPアドレスを知る方法はいくつかありますが一番早いのは音声コマンドによるものです。

英語のシステムを使用している場合は「What's is a my IP address」。日本語のシステムを使用している場合は「私のIPアドレスを教えて」と発音して認識させることでポップアップで知ることができます。

そのほかに設定アプリのネットワークからも確認できます。

これは接続しているネットワークのPropertiesを押し詳細から見れます。

③WindowsPC側でEdgeやChromeなどのブラウザでIPアドレスを入力します。

ブラウザによる警告が表示されることがありますが、[詳細設定]からページへ進むことができます。

 また初回時にパスワードの設定などを行う必要がありますが、指示に従うことでデバイスポータルへ接続することができます。

 デバイスポータルのパスワードは3回間違えることで再設定をすることができるため正直パスワードとしてあってないようなものとなっています。

参考

redhologerbera.hatenablog.com

〇キオスクモードの設定

ここから本題のキオスクモードを設定していきます。

①デバイスポータルのサイドタブSystemからキオスクモードを設定できます。

Enable Kiosk Modeにチェックを入れStartup appでキオスクモードとして使用したいアプリケーションを指定することで次回起動時からキオスクモードが有効化されます。

キオスクモードではHoloLens起動後にパスワード(デバイスのログイン)の画面の後通常であればホーム画面が開きますが、いきなり指定したアプリケーションが起動します。

また通常であれば表示されるはずの手首のWindowsボタンが非表示になり、手首をタップしてもホーム画面が起動することやアプリケーションが落ちることがなくなります。

以上がキオスクモードの設定になります。

キオスクモードを解除する際は設定時同様にデバイスポータルからEnable KioskModeのチェックを外し保存します。

なお注意点として一度キオスクモードが有効化されると無効化されるまでは音声コマンドや設定アプリによるIPアドレスの把握ができなくなります。

 このためIPアドレスは控えておく方がよさそうです。

ゼロから始めるUnityShader開発 第五章 透明度のシェーダーを書く その③一般的なAlphaBlending

本日はシェーダー枠です。

 昨日は透明度を持った半透明なオブジェクトの描画を行いました。

 キーポイントとして透明度を持ったオブジェクトの描画には以下の二つがあります。

・不透明なオブジェクトが描画された後に描画する

・すでに描画されているピクセルと半透明シェーダーによって計算されたピクセルの色をどのように混ぜるかというAlphaBlendingの設定

 先日の状態ではこのAlphaBlendingがOne Oneですでに描画されたピクセルに対して加算する形で混ぜていたため明るく描画されていました。

 

今回はこのAlphaBlendingについてみていきます。

〇AlphaBlendingとは?

AlphaBlendingとはシェーダーで描画した色をどのようにすでに描画されている色に合成するかというパラメータになります。

docs.unity3d.com

〇SrcColor DstColor

よく見かける例としてはBlend SrcColor DstColorです。

    SubShader
    {
        Tags { "RenderType"="Transparent" }
        LOD 100

        Blend SrcColor DstColor
        Pass
        {
        ・・・
        }

SrcColorはシェーダーによって出力される生の色を指します。

DstColorはすでに描画されている色を指します。

つまりこのシェーダーで描画した色をすでに描画している色と混ぜ合わせる処理になります。

これはガラスなどの物理的な透明度表現などによく使用されます。

〇SrcAlpha OneMinusSrcAlpha

こちらもよく見るブレンドです。

    SubShader
    {
        Tags { "RenderType"="Transparent" }
        LOD 100

        Blend SrcAlpha OneMinusSrcAlpha
        BlendOp Add 
        Pass
        {

OneMinusSrcAlpha1からSrcAlphaを引いた値になります。

SrcAlphaとはシェーダーで計算されたアルファを意味しています。

例えば次のようなシェーダーの場合SrcAlpha0.6OneMinusSrcAlpha0.4となります。

 float4 frag (v2f i) : SV_Target
            {
                float4 col = tex2D(_MainTex, i.uv);
                col.a = 0.6f;
                return col;
            }

こちらは最終的な色味が必ず1になるため明るくも暗くもなることがなくポピュラーな透過に向いています。

〇One OneMinusSrcAlpha

    SubShader
    {
        Tags { "RenderType"="Transparent" }
        LOD 100

        Blend One OneMinusSrcAlpha
        BlendOp Add 
        Pass
        {

Oneは数値の1を示しています。

 この処理では特徴としてcol.a = 0.0f;としても以下のように完全に透明になることはありません。 ただしテクスチャで黒の部分は完全に透明になっているのが確認できると思います。

筆者としてまだ完全にマニュアルを解いて理解できたわけではありませんが、上記の表現が最も一般的なようです。

ゼロから始めるUnityShader開発 第五章 透明度 半透明なシェーダーを書く

本日はシェーダー学習枠です。

〇不透明なオブジェクトの描画順

描画処理が行われる際は一般的に遠くにあるものから塗りつぶされるように描画が行われています。

 半透明なオブジェクトは不透明なオブジェクトの描画が完了した後に処理が実行されます

 これはRenderDocなどのデバッグツールを使用することで実際に目にすることができます。

 

DrawOpaqueObjectsで不透明なオブジェクトが描画

必ず不透明なオブジェクトの後にDrawTransparentObjectsが描画される

これは不透明なオブジェクトがシェーダーによって計算されたピクセルをそのまま塗りつぶすのに対して、半透明なオブジェクトはシェーダーによって描画される際にすでに描画されているピクセル色の影響を考慮して計算結果が描画される仕組みになっているためです。

 まずは上記の例でDrawTransparentObjectsに含めるようにする必要があります。

〇RenderType Transparent

RenderTypeはShaderLabのTagsブロックで記述できるシェーダーの属性です。

        Tags { "RenderType"="Transparent" }

 上記のように記述することでRender Queueが3000へとデフォルトで指定されるようになりDrawTransparentObjectsのイベントで処理が行われるようになります。

Render Queueは描画順番に関する値ですが、2000番は不透明オブジェクト、3000番は半透明オブジェクトのように値によって描画イベントを変える仕組みがあります。

〇AlphaBlend

 RenderTypeをTransparentに変えるだけでは処理の場所が変わるだけで透明度を扱うことはできません。

 透明度を扱うためにはすでに描画されたピクセルと新たにシェーダーによって計算されたピクセルをどのように合成するかという設定が必要です。

この設定をAlphaBlendと呼びます。

ja.wikipedia.org

UnityではShaderLab内のSubShader内で*Blender 〇〇**のように定義します。

  SubShader
    {
        Tags { "RenderType"="Transparent" }
        LOD 100

        Blend One One//追加
        Pass
        {
      ・・・・
        }

Blendは2つの引数を使用でき、第一引数でBlend操作、第二引数でBlend係数として定義できます。

今回の場合はOneを使用しており、これはシェーダーによって計算した色をそのまま使用することを示します。

これによって半透明なシェーダーが完成します。

今回の場合One Oneのため、DrawOpaqueObjectsで計算されたピクセル色にDrawTransparentObjectsの計算結果を合成しています。

一般的なペイントソフトなどではこの処理をオーバーレイと呼びます。

docs.unity3d.com

〇ソースコード

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

        Blend One One
        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 = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            float4 frag (v2f i) : SV_Target
            {
                // sample the texture
                float4 col = tex2D(_MainTex, i.uv);
                col.a = 0.5f;
                return col;
            }
            ENDHLSL
        }
    }
}

Adobe Substance 3Dの導入方法 体験期間、買い切り版などについて

本日はモデリング枠です。

筆者はオープンソースで自由に使うことができるBlenderから始め仕事でもモデリングを行うようになってからはフリーのソフトウェアだけではなくMarvelousDesiginerやMarmosetToolbags等の有料ソフトウェアも手を出して学ぶようにしています。

 今回はその一環としてAdobeのSubstance 3Dを導入しましたので紹介します。

〇Substance 3Dとは?

 3D業界では有名なツールですが、筆者は聞いたことがあるものの実際に触るのは今回が初めてになります。

Adobeの提供する3D関連ツールは以下のようになります。

・Substance Painter

Substance Painterは3Dペイントツールです。

www.adobe.com

現実空間でプラモデルを塗装するように3Dアセットをペイントすることができます。

・Substance Designer

Substance DesingnerはUnityArtEngineなアドと同様にノードベースのテクスチャ作成ツールです。

パラメトリック3Dアセット、モデル、マテリアル、パターンを制作する、3Dデザインソフトウェアの決定版 | Adobe Substance 3D Designer

・Substance Sampler

SubstanceSamplerは写真からテクスチャを作成するソフトウェアです。

写真をインポートすることで自動でPBIなマテリアルを作成します。

・Substance 3D Assets

Substance 3D Assetsは3Dライブラリです。

サブスクリプションに応じて月ごとのダウンロード数が異なってきますが、3Dアセットを入手することができます。

substance3d.adobe.com

・Substance 3D Stager

Substance 3D Stagerはソフトウェア内の仮想的空間にオブジェクトを配置して3Dシーンを構築するソフトウェアのようです。

レンダラーのようなものでしょうか?

www.adobe.com

・Substance 3D Modeler

Substance 3D ModelerはSubstance製品の中のモデリングソフトウェアです。

ポリゴンモデリングとスカルプトによるモデリングが可能で、特徴として最初からVR空間でモデリングを行うことを想定しています。(VRがなくデスクトップでモデリングも可能)

〇ライセンスの形

以前はSteamによる買い切り版が提供されていたようですが、2023年1月現在ではストアでの新たな販売は終了されAdobe公式のサブスクリプションのみの提供になるようです。

22年夏までは販売が行われていたようで、筆者は機会を逃してしまっていました。

価格は3D関連のすべてが含まれるSubstance 3D Collectionが月に6028円、筆者が今回導入したSubstance 3D Texturingが2038円になります。

それぞれの違いはソフトウェアとしてはSuvstance 3D CollectionSubstance 3D Texturingに比べSubstance 3D StagerSubstance 3D Stagerが含まれる点、また月々に入手することができる3Dアセットが30→50になっている点になります。

〇体験版の導入

Adobeの製品として30日間の体験期間が用意されています。

www.adobe.com

Adobeのアカウントで上記リンクから無料で始めるを選択することで体験を開始することができます。

注意点としてクレジットカード情報を登録する必要があり、30日の無料期間終了後選択した販売形態(月額払いor年間払い)で自動的に課金が行われます。

Adobe Substance 3DCreative Cloud Desktop3DとARからインストール・起動することができます。

以上で導入が完了しました。

Blenderと合わせて今年は使っていきたいと思います。

プラットフォームによってShaderのUV座標が上下反転する問題

本日はShaderのトラブル解消を行います。

先日MixedRealityGraphicsToolsの拡大鏡機能をHoloLensで実行した際にUV座標のV座標が反転する現象を確認しました。

redhologerbera.hatenablog.com

 取り急ぎの対処としてV座標に-1をかけ合わせてトラブルを回避しました。

redhologerbera.hatenablog.com

この方法ではHoloLens 2実機に合わせてShaderを書き換えたため今度はUntiyEditorや他のプラットフォームでV座標が反転する問題が発生します。

〇プラットフォーム毎よってUV座標が反転する原因

今回の原因はグラフィックスAPIによる座標系の定義の違いです。

redhologerbera.hatenablog.com

 HoloLens 2ではDirectX、QuestなどのAndroidデバイスではOpenGL やVulkanなどが使用されています。

UV座標に関しての原点(0,0)はそれぞれ次のように定義されています。

〇UNITY_UV_STARTS_AT_TOP

UNITY_UV_STARTS_AT_TOPはUnityで提供されている定義済みマクロ(条件コンパイル)です。

 返り値として0or1が定まっていますが、実行環境のプラットフォームによって自動的に割り振られます。

この仕組みはマルチプラットフォームでの稼働を想定して設計されているGraphicsTools/Standardシェーダーにも採用されています。

MixedReality-GraphicsTools-Unity/GraphicsToolsStandardProgram.hlsl at 9f4e35db81b680060d70609e61a47e0efddba1de · microsoft/MixedReality-GraphicsTools-Unity · GitHub

 GraphicsToolsStandardシェーダーでもブラーなどのスクリーン座標の処理が行われており、同様の仕組みが実装されています、。

#if defined(_UV_SCREEN)
    output.uvScreen = ComputeScreenPos(output.position);
    // Flip vertical UV for orthographic projections (if not already flipped) to ensure the image is not upside down.
#if defined(UNITY_UV_STARTS_AT_TOP)
    output.uvScreen.y = unity_OrthoParams.w ? (1.0 - output.uvScreen.y) : output.uvScreen.y;
#else
    output.uvScreen.y = unity_OrthoParams.w ? output.uvScreen.y : (1.0 - output.uvScreen.y);
#endif
#elif (_BLUR_TEXTURE_PREBAKED_BACKGROUND)
    output.uvBackgroundRect = float2((vertexPosition.x - _BlurBackgroundRect.x) / (_BlurBackgroundRect.z - _BlurBackgroundRect.x), 
                                     (vertexPosition.y - _BlurBackgroundRect.y) / (_BlurBackgroundRect.w - _BlurBackgroundRect.y));
#endif 

DirectX環境であるHoloLensではUNITY_UV_STARTS_AT_TOPの処理が走り、スクリーン座標のV座標が反転されるようになっています。

#if defined(UNITY_UV_STARTS_AT_TOP)
    output.uvScreen.y = unity_OrthoParams.w ? (1.0 - output.uvScreen.y) : output.uvScreen.y;
#else

unity_OrthoParamsはカメラが遠視投影を使用している場合は1,平行投影を使用している場合は0が返され、通常の場合 (1.0 - output.uvScreen.y)が実行されV座標が反転されています。

docs.unity3d.com

スクリーン座標を使用する場合同様の仕組みを実装することであらゆるプラットフォームで対応できるシェーダーになりそうです。

〇参考

以下の記事を参考にさせていただきました。

dench.flatlib.jp

 またUNITY_UV_STARTS_AT_TOPに関しては先日の拡大鏡機能に関するバグレポートを提出した際にリーダーのCameronさんより教えていただきました。

github.com

Blenderで他のメッシュと交差関係にあるメッシュを可視化する

本日はBlenderモデリング枠です。

筆者は仕事でも趣味でもモデリングをしていますが、先日仕事で作ったモデルのFightingが発生しているモデルの改修依頼が来ました。

ZFightingとはUnityやBlender上で描画を行う際にメッシュが同じ座標に張られていることで描画がおかしくなってしまう問題です。

Unity上で発生したZFightingの例

ZFightingが発生する原因としてメッシュが張られている座標が同一であるほかにカメラの設定があります。

今回はBlenderで交差関係にあるメッシュを可視化してZFightingが発生しやすい箇所を把握できるようにします。

〇Blenderで交差関係にあるメッシュを可視化する。

今回は次のような家具を例に紹介します。

この家具は3つの棚を一つのオブジェクトとして統合しています。

今回の場合棚同士のつなぎ目の場所のメッシュが重なっています。

今回はわかりやすい例としていますが、多くの3Dモデルの場合は今回のように単純な重なりというわけではなく非常に複雑でわかりにくい場所に発生します。

こうしたメッシュを見つけるためにメッシュ分析を行うことができます。

メッシュ分析を使用するために編集モードの状態でビューポートオーバーレイを選択します。

メッシュ分析のチェックボックスにチェックを入れタイプを交差に指定します。

これによりメッシュとほかのメッシュが交差しているメッシュが赤く表示されます。

冒頭で紹介した棚同士が重なっている面も赤く表示されますので、Gキーで棚を移動させ赤表示が消えるまでずらします。

これによってメッシュが重なることによるZFightingが発生しやすい場所を把握して修正することができます。

 例えば次の部分では一見交差がないように見えても赤く交差されていると判定がされています。

対象の面を選択してSキー+Zキー+0で高さをそろえることで交差の判定が解消されます。

 つまり一見板のように平らになっているように見えても微妙に歪んていたことがわかります。

 メッシュ分析を行うことで紹介したようにモデルとして使用する際に起こりゆるエラーを予測して未然に修正することやすでに発生したトラブルを対処する際に素早く問題をチェックできます。