本日は HoloLens の小ネタ枠です。
HoloLens でユニティちゃんトゥーンシェーダーを利用してトゥーンシェーダの動作を試してみます。
ユニティちゃんトゥーンシェーダー
セル風3DCGアニメーションの制作現場での要望に応えるような形で設計された映像志向のトゥーンシェーダーです。
以下のサイトからダウンロード可能です。
unity-chan.com
サンプルプロジェクトの作成
HoloLens でユニティちゃんトゥーンシェーダーを試すため、MRTK を取り込んだサンプルプロジェクトを作成します。
MRTKのインポートと基本設定
MRTK のインポートと HoloLens 向けプロジェクトの基本設定を行います。
手順の詳細は以下の記事を参照してください。
bluebirdofoz.hatenablog.com
ユニティちゃんトゥーンシェーダーのインポート
上記サイトからダウンロードした UnityPackage を Unity プロジェクトにインポートします。
これで[Shader]欄から[UnityChanToonShader]が選択可能になります。
試しにホロモンモデルのマテリアルのシェーダを MRTK/Standard シェーダからユニティちゃんトゥーンシェーダーに差し替えてみました。
片目しか描写されない問題
このままプロジェクトをビルドして HoloLens で見た目を確認するとユニティちゃんトゥーンシェーダーを設定したオブジェクトが左目のみに描画される問題が発生します。
これはデフォルトの XR プラグイン設定では以下の記事で紹介したシングルパスインスタンシングレンダリングが利用されることが原因です。
bluebirdofoz.hatenablog.com
今回は上記の記事を参考に以下の4つのファイルをシングルパスインスタンシングレンダリングに対応させて問題を回避しました。
・UCTS_DoubleShadeWithFeather.cginc
・UCTS_Outline.cginc
・UCTS_ShadingGradeMap.cginc
・UCTS_ShadowCaster.cginc
以下は UCTS_Outline.cginc の対応例です。
・UCTS_Outline.cginc
// ------------ 中略 ------------ uniform sampler2D _ClippingMask; uniform float4 _ClippingMask_ST; uniform float _Clipping_Level; uniform fixed _Inverse_Clipping; uniform fixed _IsBaseMapAlphaAsClippingMask; #endif struct VertexInput { float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord0 : TEXCOORD0; // シングルパスインスタンシング対応のため挿入 --- ここから UNITY_VERTEX_INPUT_INSTANCE_ID // シングルパスインスタンシング対応のため挿入 --- ここまで }; struct VertexOutput { float4 pos : SV_POSITION; float2 uv0 : TEXCOORD0; float3 normalDir : TEXCOORD1; float3 tangentDir : TEXCOORD2; float3 bitangentDir : TEXCOORD3; // シングルパスインスタンシング対応のため挿入 --- ここから UNITY_VERTEX_OUTPUT_STEREO // シングルパスインスタンシング対応のため挿入 --- ここまで }; VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; // シングルパスインスタンシング対応のため挿入 --- ここから UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_OUTPUT(VertexOutput, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // シングルパスインスタンシング対応のため挿入 --- ここまで o.uv0 = v.texcoord0; float4 objPos = mul ( unity_ObjectToWorld, float4(0,0,0,1) ); float2 Set_UV0 = o.uv0; float4 _Outline_Sampler_var = tex2Dlod(_Outline_Sampler,float4(TRANSFORM_TEX(Set_UV0, _Outline_Sampler),0.0,0)); // ------------ 中略 ------------ return o; } float4 frag(VertexOutput i) : SV_Target{ // シングルパスインスタンシング対応のため挿入 --- ここから UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // シングルパスインスタンシング対応のため挿入 --- ここまで //v.2.0.5 _Color = _BaseColor; float4 objPos = mul ( unity_ObjectToWorld, float4(0,0,0,1) ); // ------------ 中略 ------------ return Set_Outline_Color; #endif }