Appareil photo/vidéo HoloLens dans Unreal

Le casque HoloLens a une caméra photo/vidéo (PV) sur la visière, qui peut être utilisée à la fois pour la capture de réalité mixte et pour localiser des objets dans l’espace universel Unreal à partir des coordonnées de pixels dans le cadre de la caméra.

Important

L’appareil photo/vidéo n’est pas pris en charge avec la communication à distance holographique, mais il est possible d’utiliser une webcam connectée à votre PC pour simuler la fonctionnalité d’appareil photo/vidéo HoloLens.

Configuration du flux de la caméra PV

Important

La caméra PV est implémentée dans les plug-ins Windows Mixed Reality et OpenXR. Cependant, OpenXR a besoin que le plug-in Microsoft OpenXR soit installé. En outre, OpenXR pour Unreal 4,26 a une limitation : la caméra peut fonctionner avec DirectX11 RHI. Cette limitation est corrigée dans 4.27.1 ou ultérieur.

  • Dans Project Settings > HoloLens, activez la fonctionnalité Webcam :

Capture d’écran des paramètres du projet HoloLens avec la propriété Webcam mise en surbrillance

  • Créez un acteur appelé « CamCapture » et ajoutez un plan pour rendre le flux de la caméra :

Capture d’écran d’un acteur avec un plan ajouté

  • Ajoutez l’acteur à votre scène, créez un matériau appelé CamTextureMaterial avec un paramètre d’objet de texture et un échantillon de texture. Envoyez les données RVB de la texture à la couleur d’émission en sortie :

Blueprint d’un échantillon de matériau et de texture

Rendu du flux de la caméra PV

  • Dans le blueprint CamCapture, activez la caméra PV :

Blueprint de la fonction Activer/désactiver ARCapture avec la caméra PV activée

  • Créez une instance de matériau dynamique à partir de CamTextureMaterial et affectez ce matériau au plan de l’acteur :

Blueprint de la fonction Créer une instance de matériau dynamique

  • Récupérez la texture du flux de la caméra, et affectez-la au matériau dynamique, si elle est valide. Si la texture n’est pas valide, démarrez un minuteur, puis réessayez une fois le délai d’expiration écoulé :

Blueprint de la texture du flux de la caméra affectée au matériau dynamique

  • Enfin, mettez à l’échelle le plan selon les proportions de l’image de la caméra :

Blueprint du plan mis à l’échelle par rapport aux proportions des images de la caméra

Rechercher des positions de la caméra dans l’espace universel

La caméra sur le casque HoloLens 2 est décalée verticalement par rapport au suivi de la tête de l’appareil. Pour tenir compte du décalage, il existe quelques fonctions qui permettent de localiser la caméra dans l’espace universel.

GetPVCameraToWorldTransform obtient la transformation dans l’espace universel de la caméra PV, et est positionné sur l’objectif de la caméra :

Blueprint de la fonction Obtenir la transformation de la caméra PV en monde

GetWorldSpaceRayFromCameraPoint diffuse un rayon de l’objectif de la caméra vers la scène dans l’espace universel Unreal pour rechercher le contenu d’un pixel dans le cadre de la caméra :

Blueprint de la fonction Obtenir un rayon de l’espace universel depuis un point de la caméra

GetPVCameraIntrinsics retourne les valeurs intrinsèques de la caméra, qui peuvent être utilisées lors du traitement de la vision par ordinateur sur un cadre de la caméra :

Blueprint de fonctions intrinsèques de la caméra PV

Pour trouver ce qui existe dans l’espace universel à une coordonnée d’un pixel particulier, utilisez un suivi de ligne avec le rayon d’espace universel :

Blueprint du rayon d’espace universel utilisé pour déterminer ce qui existe dans l’espace universel à une coordonnée particulière

Nous convertissons ici un rayon à 2 mètres de l’objectif de la caméra en une position dans l’espace de la caméra à ¼ à partir du coin supérieur gauche du cadre. Nous utilisons ensuite le résultat du pointage pour rendre quelque chose là où l’objet existe dans l’espace universel :

Blueprint de la conversion d’un rayon à 2 mètres de l’objectif de la caméra en une position dans l’espace de la caméra à 1/4 à partir du coin supérieur gauche du cadre.

Quand vous utilisez le mappage spatial, cette position du pointage correspond à la surface vue par la caméra.

Rendu du flux de la caméra PV en C++

  • Créer un acteur C++ appelé CamCapture
  • Dans le fichier build.cs du projet, ajoutez « AugmentedReality » à la liste PublicDependencyModuleNames :
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • Dans CamCapture. h, incluez ARBlueprintLibrary.h
#include "ARBlueprintLibrary.h"
  • Vous devez aussi ajouter des variables locales pour le maillage et le matériau :
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • Dans CamCapture.cpp, mettez à jour le constructeur en ajoutant un maillage statique à la scène :
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);
}

Dans BeginPlay, créez une instance de matériau dynamique à partir du matériau de la caméra du projet, appliquez-la au composant de maillage statique et démarrez la caméra HoloLens.

Dans l’éditeur, cliquez avec le bouton droit sur CamTextureMaterial dans l’explorateur de contenu, puis sélectionnez Copy Reference pour obtenir la chaîne de 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);
}

Dans Tick, récupérez la texture de la caméra, définissez-la sur le paramètre de texture dans le matériau CamTextureMaterial et mettez à l’échelle le composant de maillage statique selon les proportions du cadre de la caméra :

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

Point de contrôle de développement suivant

Si vous suivez le parcours de développement Unreal que nous avons mis en place, vous explorez actuellement les API et les fonctionnalités de la plateforme Mixed Reality. À partir d’ici, vous pouvez passer au sujet suivant :

Ou accéder directement au déploiement de votre application sur un appareil ou un émulateur :

Vous pouvez revenir aux points de contrôle de développement Unreal à tout moment.

Voir aussi