Unreal での HoloLens 写真/ビデオ カメラ

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 カメラ] 機能を有効にします。

Screenshot of the HoloLens project settings with the Webcam property highlighted

  • "CamCapture" という名前の新しいアクターを作成し、カメラ フィードをレンダリングするための平面を追加します。

Screenshot of the an actor with an added plane

  • アクターをシーンに追加し、テクスチャ オブジェクト パラメーターとテクスチャ サンプルを使用して、CamTextureMaterial という名前の新しいマテリアルを作成します。 テクスチャの RGB データを出力放射色に送信します。

Blueprint of a material and texture sample

PV カメラ フィードのレンダリング

  • CamCapture ブループリントで、PV カメラをオンにします。

Blueprint of the Toggle ARCapture function with the PV Camera turned on

  • CamTextureMaterial から動的なマテリアル インスタンスを作成し、このマテリアルをアクターの平面に割り当てます。

Blueprint of the Create Dynamic Material Instance function

  • カメラ フィードからテクスチャを取得し、有効な場合はそれを動的マテリアルに割り当てます。 テクスチャが有効でない場合は、タイマーを開始し、タイムアウト後に再試行します。

Blueprint of camera feed texture assigned to the dynamic material

  • 最後に、カメラ画像の縦横比で平面を拡大縮小します。

Blueprint of plane scaled relative to the camera images aspect ratio

ワールド空間でカメラの位置を検索する

HoloLens 2 のカメラは、デバイスの頭追跡から垂直方向にオフセットされます。 オフセットを考慮するために、ワールド空間内のカメラの位置を調べる関数がいくつかあります。

GetPVCameraToWorldTransform を使用すると、PV カメラのワールド空間内の変換が取得されて、カメラのレンズに配置されます。

Blueprint of the Get PVCamera to World Transform function

GetWorldSpaceRayFromCameraPoint を使用すると、カメラ フレーム内のピクセルの内容を調べるため、カメラのレンズから Unreal ワールド空間内のシーンに光線がキャストされます。

Blueprint of the Get World Space Ray from Camera Point

GetPVCameraIntrinsics を使用すると、カメラの組み込み値が返されます。カメラ フレームでコンピューター ビジョン処理を行うときにそれを使用できます。

Blueprint of Get PVCamera Intrinsics functions

ワールド空間の特定のピクセル座標に存在するものを調べるには、ワールド空間光線でライン トレースを使用します。

Blueprint of the world space ray being used to find out what exists in the world space at a particular coordinate

ここでは、フレームの左上から ¼ のカメラス空間位置に向けて、カメラのレンズから 2 メートルの光線をキャストします。 次に、ヒット結果を使用して、ワールド空間内のオブジェクトが存在する場所に何かをレンダリングします。

Blueprint of a 2-meter ray cast from the camera lens to the camera-space position 1/4 from the top left of the frame

空間マッピングを使用している場合、このヒット位置はカメラで見ているサーフェスと一致します。

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 開発チェックポイントに戻ることができます。

関連項目