HoloLens のバイザーには写真と動画 (PV) 用のカメラが付いており、Mixed Reality キャプチャ (MRC) のためと、カメラ フレームのピクセル座標から Unreal 空間内のオブジェクトを見つけるための両方に、使用することができます。
重要
Holographic Remoting では PV カメラはサポートされていませんが、お使いの PC に搭載のウェブ カメラを使用して、HoloLens PV カメラの機能をシミュレートできます。
PV カメラのフィードの設定
重要
PV カメラは、Windows Mixed Reality と OpenXR 両方のプラグインに実装されています。 ただし、OpenXR を使用するには Microsoft OpenXR プラグインをインストールする必要があります。 また、Unreal 4.26 の OpenXR には制限があり、カメラは DirectX11 RHI で動作できます。 この制限は、Unreal 4.27.1 以降で修正されています。
- [プロジェクト設定] > [HoloLens] で、[Web カメラ] 機能を有効にします。
- "CamCapture" という名前の新しいアクターを作成し、カメラ フィードをレンダリングするための平面を追加します。
- アクターをシーンに追加し、テクスチャ オブジェクト パラメーターとテクスチャ サンプルを使用して、CamTextureMaterial という名前の新しいマテリアルを作成します。 テクスチャの RGB データを出力放射色に送信します。
PV カメラ フィードのレンダリング
- CamCapture ブループリントで、PV カメラをオンにします。
- CamTextureMaterial から動的なマテリアル インスタンスを作成し、このマテリアルをアクターの平面に割り当てます。
- カメラ フィードからテクスチャを取得し、有効な場合はそれを動的マテリアルに割り当てます。 テクスチャが有効でない場合は、タイマーを開始し、タイムアウト後に再試行します。
- 最後に、カメラ画像の縦横比で平面を拡大縮小します。
ワールド空間でカメラの位置を検索する
HoloLens 2 のカメラは、デバイスの頭追跡から垂直方向にオフセットされます。 オフセットを考慮するために、ワールド空間内のカメラの位置を調べる関数がいくつかあります。
GetPVCameraToWorldTransform を使用すると、PV カメラのワールド空間内の変換が取得されて、カメラのレンズに配置されます。
GetWorldSpaceRayFromCameraPoint を使用すると、カメラ フレーム内のピクセルの内容を調べるため、カメラのレンズから Unreal ワールド空間内のシーンに光線がキャストされます。
GetPVCameraIntrinsics を使用すると、カメラの組み込み値が返されます。カメラ フレームでコンピューター ビジョン処理を行うときにそれを使用できます。
ワールド空間の特定のピクセル座標に存在するものを調べるには、ワールド空間光線でライン トレースを使用します。
ここでは、フレームの左上から ¼ のカメラス空間位置に向けて、カメラのレンズから 2 メートルの光線をキャストします。 次に、ヒット結果を使用して、ワールド空間内のオブジェクトが存在する場所に何かをレンダリングします。
空間マッピングを使用している場合、このヒット位置はカメラで見ているサーフェスと一致します。
C++ での PV カメラ フィードのレンダリング
- CamCapture という名前の新しい C++ アクターを作成します
- プロジェクトの build.cs で、"AugmentedReality" を PublicDependencyModuleNames リストに追加します。
PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"AugmentedReality"
});
- CamCapture.h で、ARBlueprintLibrary.h をインクルードします
#include "ARBlueprintLibrary.h"
- また、メッシュとマテリアルのローカル変数を追加する必要があります。
private:
UStaticMesh* StaticMesh;
UStaticMeshComponent* StaticMeshComponent;
UMaterialInstanceDynamic* DynamicMaterial;
bool IsTextureParamSet = false;
- CamCapture.cpp で、静的メッシュをシーンに追加するようにコンストラクターを更新します。
ACamCapture::ACamCapture()
{
PrimaryActorTick.bCanEverTick = true;
// Load a mesh from the engine to render the camera feed to.
StaticMesh = LoadObject<UStaticMesh>(nullptr, TEXT("/Engine/EngineMeshes/Cube.Cube"), nullptr, LOAD_None, nullptr);
// Create a static mesh component to render the static mesh
StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CameraPlane"));
StaticMeshComponent->SetStaticMesh(StaticMesh);
// Scale and add to the scene
StaticMeshComponent->SetWorldScale3D(FVector(0.1f, 1, 1));
this->SetRootComponent(StaticMeshComponent);
}
BeginPlay で、プロジェクトのカメラ マテリアルから動的マテリアルのインスタンスを作成し、それを静的メッシュ コンポーネントに適用して、HoloLens カメラを開始します。
エディターのコンテンツ ブラウザーで CamTextureMaterial を右クリックし、[参照のコピー] を選択して、CameraMatPath の文字列を取得します。
void ACamCapture::BeginPlay()
{
Super::BeginPlay();
// Create a dynamic material instance from the game's camera material.
// Right-click on a material in the project and select "Copy Reference" to get this string.
FString CameraMatPath("Material'/Game/Materials/CamTextureMaterial.CamTextureMaterial'");
UMaterial* BaseMaterial = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), nullptr, *CameraMatPath, nullptr, LOAD_None, nullptr);
DynamicMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this);
// Use the dynamic material instance when rendering the camera mesh.
StaticMeshComponent->SetMaterial(0, DynamicMaterial);
// Start the webcam.
UARBlueprintLibrary::ToggleARCapture(true, EARCaptureType::Camera);
}
Tick で、カメラからテクスチャを取得し、それを CamTextureMaterial マテリアルのテクスチャ パラメーターに設定して、カメラ フレームの縦横比で静的メッシュ コンポーネントを拡大縮小します。
void ACamCapture::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Dynamic material instance only needs to be set once.
if(IsTextureParamSet)
{
return;
}
// Get the texture from the camera.
UARTexture* ARTexture = UARBlueprintLibrary::GetARTexture(EARTextureType::CameraImage);
if(ARTexture != nullptr)
{
// Set the shader's texture parameter (named "Param") to the camera image.
DynamicMaterial->SetTextureParameterValue("Param", ARTexture);
IsTextureParamSet = true;
// Get the camera instrincs
FARCameraIntrinsics Intrinsics;
UARBlueprintLibrary::GetCameraIntrinsics(Intrinsics);
// Scale the camera mesh by the aspect ratio.
float R = (float)Intrinsics.ImageResolution.X / (float)Intrinsics.ImageResolution.Y;
StaticMeshComponent->SetWorldScale3D(FVector(0.1f, R, 1));
}
}
次の開発チェックポイント
用意されている Unreal 開発体験に従っている場合、Mixed Reality プラットフォームの機能と API を探索している段階にいます。 ここから、次のトピックを続けることができます。
または、デバイスまたはエミュレーターへのアプリの配置操作に直接移動します。
いつでも Unreal 開発チェックポイントに戻ることができます。