本日はMetaQuest3の技術調査枠です。
MRTKv2.xを使ってMetaQuest3向けのUnityプロジェクト作成を行う手順を記事にします。
本記事はMRTKv2.xのシェーダをオクルージョンに対応させる手順です。
前提条件
本記事では以下の記事で作成したUnity プロジェクトを基に設定を行います。
bluebirdofoz.hatenablog.com
MRTKv2.xのシェーダをオクルージョンに対応させる
独自のシェーダをオクルージョンで利用する場合、シェーダコードにいくつかの修正を加える必要があります。
シェーダの修正手順は以下のReadMeに解説されています。
github.com
MRTKv2.xのシェーダは以下のフォルダにインポートされています。
Assets/MRTK/Shaders
今回はボタンなどの基本UXをオクルージョンさせたいのでMixedRealityStandard.shaderを変更します。
186行目と194行目に以下を追加します。
// DepthAPI Environment Occlusion #pragma multi_compile _ HARD_OCCLUSION SOFT_OCCLUSION
#include "Packages/com.meta.xr.depthapi/Runtime/BiRP/EnvironmentOcclusionBiRP.cginc"
325行目に以下を追加します。
META_DEPTH_VERTEX_OUTPUT(8) // the number should stand for the previous TEXCOORD# + 1
592行目に以下を追加します。
// v.vertex (object space coordinate) might have a different name in your vert shader META_DEPTH_INITIALIZE_VERTEX_OUTPUT(o, v.vertex);
778行目に以下を追加します。
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
1103行目に以下を追加します。
// Third field is for environment depth bias. 0.0 means the occlusion will be calculated with depths as they are. META_DEPTH_OCCLUDE_OUTPUT_PREMULTIPLY(i, output, 0.0);
これでシェーダの改変は完了です。
動作確認のため、以下のMRTKのボタンUXをシーンに配置しました。
Packages/MixedRealityToolkitFoundation/SDK/Features/UX/Interactable/Prefabs/PressableButtonHoloLens2_32x96.prefab
ビルドと動作確認
これで設定は完了です。
以下の記事を参考にプロジェクトのビルドとQuest3へのデプロイを実行してください。
bluebirdofoz.hatenablog.com
アプリを起動時してボタンに手をかざすとオクルージョンが行われます。
キャプチャの通り、上記の手順だけではテキスト部分は別のシェーダが使われているため、オクルージョンが行われません。
テキスト部分もオクルージョンさせるには以下のシェーダについても同様の修正を行う必要があります。
MixedRealityTextMeshPro.shader
カスタムシェーダの実装手順
シェーダの修正手順のReadMeを日本語訳したものを以下に記述します。
github.com
カスタムシェーダーでオクルージョンを実装する
独自のシェーダーを利用する場合はいくつかの変更を適用することで、それらをオクルージョン可能なものに変換できます。
ビルドインレンダーパイプラインの場合は、次の include ステートメントを使用します。
#include "Packages/com.meta.xr.depthapi/Runtime/BiRP/EnvironmentOcclusionBiRP.cginc"
ユニバーサルレンダーパイプラインの場合は、次の include ステートメントを使用します。
#include "Packages/com.meta.xr.depthapi/Runtime/URP/EnvironmentOcclusionURP.hlsl"
1.オクルージョンキーワードを追加する
#pragma multi_compile _ HARD_OCCLUSION SOFT_OCCLUSION
2.構造体にマクロとワールド座標(SV_POSITION)を追加します。ワールド座標は既に登録済みの場合、スキップします。
struct v2f { float4 vertex : SV_POSITION; float4 someOtherVarying : TEXCOORD0; META_DEPTH_VERTEX_OUTPUT(1) // the number should stand for the previous TEXCOORD# + 1 UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO // required for stereo };
v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // required to support stereo // v.vertex (object space coordinate) might have a different name in your vert shader META_DEPTH_INITIALIZE_VERTEX_OUTPUT(o, v.vertex); return o; }
3.フラグメントシェーダでオクルージョンの計算処理を追加する
half4 frag(v2f i) { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // this is something your shader will return without occlusions half4 fragmentShaderResult = someColor; // Third field is for environment depth bias. 0.0 means the occlusion will be calculated with depths as they are. META_DEPTH_OCCLUDE_OUTPUT_PREMULTIPLY(i, fragmentShaderResult, 0.0); return fragmentShaderResult; }
フラグメントシェーダーに渡されるワールド座標に変化がある場合は、次のマクロを使用できます。
META_DEPTH_OCCLUDE_OUTPUT_PREMULTIPLY_WORLDPOS(yourWorldPosition, fragmentShaderResult, 0.0);