HTC Viveのフロントカメラの映像を、カメラの向きと画角を考慮して配置したビルボードポリゴンに表示する方法をご紹介したいと思います。
まず、新規プロジェクトを作成し、アセットストアからSteamVR Pluginをインポートし、「Assets/SteamVR/Prefabs/[CameraRig]」をHierarchyに追加します。
また、Unity 5.6ではViveコントローラが認識しないので、「Camera (eye)」に「SteamVR_UpdatePoses」をアタッチします。
詳しくは、以下のサイトを参考にして下さい。
詳しくは、以下のサイトを参考にして下さい。
まず、不要なので「Main Camera」を削除します。
次に、スクリーンを表示するための「3D Object/Quad」を[CameraRig]の下に作成します。とりあえず名前を「ARScreen」に変更します。
「Mesh Collider」は不要なので削除します。
「Mesh Renderer」の「Light Probes」「Reflection Probes」「Cast Shadows」「Receive Shadows」は不要なのでオフにします。
「ARScreen」に「Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs」を追加し、「Material」に「Assets/SteamVR/Extras/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat」を設定し、「Target」に自分自身の「ARScreen」を設定します。
また、「Materials」の「Element 0」にも同じマテリアルを設定します。
次に、「Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs」を開き、コードを書き替えます。直接編集するのが嫌な場合はコピーしてから書き替えて下さい。
「SteamVR_TestTrackedCamera」クラスの最後に、以下のメソッドを追加します。
次に、スクリーンを表示するための「3D Object/Quad」を[CameraRig]の下に作成します。とりあえず名前を「ARScreen」に変更します。
「Mesh Collider」は不要なので削除します。
「Mesh Renderer」の「Light Probes」「Reflection Probes」「Cast Shadows」「Receive Shadows」は不要なのでオフにします。
「ARScreen」に「Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs」を追加し、「Material」に「Assets/SteamVR/Extras/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat」を設定し、「Target」に自分自身の「ARScreen」を設定します。
また、「Materials」の「Element 0」にも同じマテリアルを設定します。
次に、「Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs」を開き、コードを書き替えます。直接編集するのが嫌な場合はコピーしてから書き替えて下さい。
「SteamVR_TestTrackedCamera」クラスの最後に、以下のメソッドを追加します。
// プロジェクションのスケールを取得する
static Vector2 GetProjectionScale(SteamVR_TrackedCamera.VideoStreamTexture source)
{
Valve.VR.CVRTrackedCamera trackedCamera = Valve.VR.OpenVR.TrackedCamera;
if (trackedCamera == null) return Vector2.one;
// スケール値を取得するだけなので、Near/Farの値は何でも構わない
const float Near = 1.0f;
const float Far = 100.0f;
Valve.VR.HmdMatrix44_t ProjectionMatrix = new Valve.VR.HmdMatrix44_t();
if (trackedCamera.GetCameraProjection(source.deviceIndex, source.frameType, Near, Far, ref ProjectionMatrix) !=
Valve.VR.EVRTrackedCameraError.None)
{
return Vector2.one;
}
return new Vector2(ProjectionMatrix.m0, ProjectionMatrix.m5);
}
次に、Update()メソッドの、
target.localScale = new Vector3(1, 1.0f / aspect, 1);
// Apply the pose that this frame was recorded at.
if (source.hasTracking)
{
var t = source.transform;
target.localPosition = t.pos;
target.localRotation = t.rot;
}
この部分を、
// Apply the pose that this frame was recorded at.
if (source.hasTracking)
{
const float ProjectionZ = 1.0f;
Vector2 ProjectionScale = GetProjectionScale(source);
Vector2 LocalScale = new Vector2(2.0f * ProjectionZ / ProjectionScale.x, 2.0f * ProjectionZ / ProjectionScale.y);
target.localScale = new Vector3(LocalScale.x, LocalScale.y, 1.0f);
//
var t = source.transform;
target.localPosition = t.TransformPoint(new Vector3(0.0f, 0.0f, ProjectionZ));
target.localRotation = t.rot;
}
このように書き替えてビルドします。
この段階で実行すると、視界のやや下にカメラ映像のスクリーンが表示されると思います。
ただ、この状態だと、スクリーンより向こう側にあるオブジェクトが隠れて見えなくなるので、専用のシェーダを作成します。
とりあえず、「Assets」のルートで右クリックし、Create→Shader→Unlit Shaderを選択します。とりあえず、シェーダファイルの名前を「ARBackground」に変更しておきます。
その「ARBackground.shader」を開き、1行目を、
Shader "Custom/ARBackground"
に書き替え、Tagsブロックを、
Tags { "RenderType"="Opaque" "Queue"="Background" }
このように書き替え、Passブロックの先頭に、
Pass
{
ZWrite Off
CGPROGRAM
このように「Zwrite Off」を追加します。
ビルドして再びUnityに戻り、「ARScreen」の「SteamVR_TestTrackedCamera」の「Shader」を「Custom/ARBackground」に変更します。
「ARScreen」のインスペクタは最終的にこのようになります。
ビルドして再びUnityに戻り、「ARScreen」の「SteamVR_TestTrackedCamera」の「Shader」を「Custom/ARBackground」に変更します。
「ARScreen」のインスペクタは最終的にこのようになります。

最後に、「[CameraRig]/Camera (head)/Camera (eye)」のインスペクタを開き、「Camera」の「Clear Flags」を「Solid Color」に変更し、「Background」の色を#00000000に変更します。