Kamera HoloLens v unrealu

HoloLens má na cloně fotoaparát foto/video (PV), který lze použít pro Mixed Reality Capture (MRC) a umístění objektů v prostoru Unreal world ze souřadnic pixelů v rámečku fotoaparátu.

Důležité

Fotovoltaická kamera není u holografické vzdálené komunikace podporovaná, ale je možné použít webkameru připojenou k počítači k simulaci funkce holoLens PV Camera.

Nastavení kanálu kamery PV

Důležité

Fotovoltaika je implementována v Windows Mixed Reality i OpenXR pluginech. OpenXR ale potřebuje nainstalovat modul plug-in Microsoft OpenXR . OpenXR pro Unreal 4.26 má také omezení: kamera může pracovat s Rozhraním DirectX11 RHI. Toto omezení je opraveno ve verzi Unreal 4.27.1 nebo novější.

  • V nastavení > projektu HoloLens povolte funkci Webkamery :

Snímek obrazovky s nastavením projektu HoloLens se zvýrazněnou vlastností Webcam

  • Vytvořte nového aktéra s názvem CamCapture a přidejte rovinu pro vykreslení kanálu kamery:

Snímek obrazovky s objektem actor s přidanou rovinou

  • Přidejte objekt actor do scény, vytvořte nový materiál s názvem CamTextureMaterial s parametrem objektu textury a vzorkem textury. Odešlete data rgb textury do barvy výstupu emissive:

Podrobný plán vzorku materiálu a textury

Vykreslení kanálu fotovoltaické kamery

  • V podrobném plánu CamCapture zapněte fotovoltaické kamery:

Podrobný plán funkce Toggle ARCapture se zapnutou fotovoltakou

  • Vytvořte instanci dynamického materiálu z CamTextureMaterial a přiřaďte tento materiál k rovině aktéra:

Podrobný plán funkce Create Dynamic Material Instance

  • Získejte texturu z kanálu kamery a přiřaďte ji dynamickému materiálu, pokud je platná. Pokud textura není platná, spusťte časovač a zkuste to znovu po vypršení časového limitu:

Podrobný plán textury podávání kamery přiřazené k dynamickému materiálu

  • Nakonec měřítko roviny podle poměru stran obrázku fotoaparátu:

Podrobný plán roviny s měřítkem vzhledem k poměru stran obrázků z fotoaparátu

Hledání pozic kamery v oblasti World Space

Kamera na HoloLens 2 je posunutá svisle od sledování hlavy zařízení. Existuje několik funkcí pro umístění kamery ve světovém prostoru, aby se zohlednil posun.

GetPVCameraToWorldTransform získá transformaci ve světovém prostoru PV kamery a bude umístěn na objektiv fotoaparátu:

Podrobný plán funkce Get PVCamera to World Transform

GetWorldSpaceRayFromCameraPoint vysadí paprsek z objektivu fotoaparátu do scény v prostoru Unreal World a najde obsah pixelu v rámečku fotoaparátu:

Blueprint of the Get World Space Ray from Camera Point

Funkce GetPVCameraIntrinsics vrátí vnitřní hodnoty kamery, které se dají použít při zpracování počítačového zpracování obrazu na snímku kamery:

Podrobný plán funkce Get PVCamera Intrinsics

Pokud chcete zjistit, co se nachází ve světovém prostoru na konkrétní souřadnici pixelu, použijte trasování čar s prostorovým paprskem světa:

Podrobný plán vesmírného paprsku světa, který se používá k zjištění toho, co existuje ve světovém prostoru na konkrétní souřadnici

Zde jsme odlili 2-m paprsku z objektivu fotoaparátu do umístění prostoru kamery 1/4 z levé horní části snímku. Výsledek hledání pak použijte k vykreslení něčeho, kde se objekt nachází ve světovém prostoru:

Podrobný plán 2metrového paprsku odlitého z objektivu fotoaparátu do pozice prostoru kamery 1/4 z levého horního okraje snímku

Při použití prostorového mapování bude tato pozice stisknutí odpovídat povrchu, který kamera vidí.

Vykreslování informačního kanálu fotovoltaické kamery v C++

  • Vytvoření nového objektu C++ s názvem CamCapture
  • V souboru build.cs projektu přidejte do seznamu PublicDependencyModuleNames rozšířenou realitu:
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • V souboru CamCapture.h zahrňte ARBlueprintLibrary.h.
#include "ARBlueprintLibrary.h"
  • Musíte také přidat místní proměnné pro síť a materiál:
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • V souboru CamCapture.cpp aktualizujte konstruktor tak, aby do scény přidal statickou síť:
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);
}

V části BeginPlay vytvořte instanci dynamického materiálu z materiálu kamery projektu, použijte ji na součást statické sítě a spusťte kameru HoloLens.

V editoru klikněte pravým tlačítkem na CamTextureMaterial v prohlížeči obsahu a vyberte Kopírovat odkaz, abyste získali řetězec pro 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);
}

V části Tick získejte texturu z kamery, nastavte ji na parametr textury v materiálu CamTextureMaterial a škálujte komponentu statické sítě podle poměru stran snímku kamery:

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));
    }
}

Další kontrolní bod vývoje

Pokud se chystáte na cestu unreal developmentu, kterou jsme si vytyčili, jste uprostřed zkoumání Mixed Reality funkcí a rozhraní API platformy. Odtud můžete pokračovat k dalšímu tématu:

Nebo přejděte přímo k nasazení aplikace do zařízení nebo emulátoru:

K kontrolním bodům Unreal Development se můžete kdykoli vrátit.

Viz také