다음을 통해 공유


모델

Azure Remote Rendering의 ‘모델’은 엔터티구성 요소로 구성된 전체 개체 표현을 나타냅니다. 모델은 원격 렌더링 서비스에 사용자 지정 데이터를 가져오는 주요 방법입니다.

모델 구조

모델에는 루트 노드인 엔터티가 하나만 있습니다. 그 아래에 자식 엔터티의 임의 계층 구조가 있을 수 있습니다. 모델을 로드하면 이 루트 엔터티에 대한 참조가 반환됩니다.

각 엔터티에는 연결된 구성 요소가 있을 수 있습니다. 일반적으로 엔터티는 메시 리소스를 참조하는 MeshComponents를 포함합니다.

모델 만들기

FBX, GLTF 또는 E57과 같은 파일 형식의 입력 모델을 변환하여 런타임용 모델을 만들 수 있습니다. 변환 프로세스는 질감, 재질 및 메시와 같은 모든 리소스를 추출하고 최적화된 런타임 형식으로 변환합니다. 또한 구조적 정보를 추출하고 이를 ARR의 엔터티/구성 요소 그래프 구조로 변환합니다.

Important

모델 변환메시를 만드는 유일한 방법입니다. 메시는 런타임에 엔터티 간에 공유될 수 있지만 모델을 로드하는 것 외에는 다른 방법으로 메시를 런타임에 가져올 수 없습니다.

모델 로드

모델을 변환한 후에는 Azure Blob Storage에서 런타임으로 로드할 수 있습니다.

Blob Storage에서 자산을 처리하는 방법에 따라 다른 두 개의 개별 로딩 함수가 있습니다.

  • Blob Storage가 계정에 연결되어 있으면 Blob Storage 매개 변수로 직접 모델을 처리할 수 있습니다. 이 경우 매개 변수 LoadModelOptions와 관련된 로딩 함수는 LoadModelAsync입니다.
  • 모델은 SAS URI를 통해 처리됩니다. 매개 변수 LoadModelFromSasOptions와 관련된 로딩 함수는 LoadModelFromSasAsync입니다. 기본 제공 모델을 로드하는 경우에도 이 변형을 사용합니다.

다음 코드 조각은 두 함수 중 하나를 사용하여 모델을 로드하는 방법을 보여 줍니다. Blob Storage 매개 변수를 사용하여 모델을 로드하려면 아래와 같은 코드를 사용합니다.

async void LoadModel(RenderingSession session, Entity modelParent, string storageAccount, string containerName, string assetFilePath)
{
    // load a model that will be parented to modelParent
    var modelOptions = LoadModelOptions.CreateForBlobStorage(
        storageAccount, // storage account name + '.blob.core.windows.net', e.g., 'mystorageaccount.blob.core.windows.net'
        containerName,  // name of the container in your storage account, e.g., 'mytestcontainer'
        assetFilePath,  // the file path to the asset within the container, e.g., 'path/to/file/myAsset.arrAsset'
        modelParent
    );

    var loadOp = session.Connection.LoadModelAsync(modelOptions, (float progress) =>
    {
        Debug.WriteLine($"Loading: {progress * 100.0f}%");
    });

    await loadOp;
}
void LoadModel(ApiHandle<RenderingSession> session, ApiHandle<Entity> modelParent, std::string storageAccount, std::string containerName, std::string assetFilePath)
{
    LoadModelOptions modelOptions;
    modelOptions.Parent = modelParent;
    modelOptions.Blob.StorageAccountName = std::move(storageAccount);
    modelOptions.Blob.BlobContainerName = std::move(containerName);
    modelOptions.Blob.AssetPath = std::move(assetFilePath);

    ApiHandle<LoadModelResult> result;
    session->Connection()->LoadModelAsync(modelOptions,
        // completion callback
        [](Status status, ApiHandle<LoadModelResult> result)
        {
            printf("Loading: finished.");
        },
        // progress callback
        [](float progress)
        {
            printf("Loading: %.1f%%", progress * 100.f);
        }
    );
}

SAS 토큰을 사용하여 모델을 로드하려면 다음 코드 조각과 같은 코드를 사용합니다.

async void LoadModel(RenderingSession session, Entity modelParent, string modelUri)
{
    // load a model that will be parented to modelParent
    var modelOptions = new LoadModelFromSasOptions(modelUri, modelParent);

    var loadOp = session.Connection.LoadModelFromSasAsync(modelOptions, (float progress) =>
    {
        Debug.WriteLine($"Loading: {progress * 100.0f}%");
    });

    await loadOp;
}
void LoadModel(ApiHandle<RenderingSession> session, ApiHandle<Entity> modelParent, std::string modelUri)
{
    LoadModelFromSasOptions modelOptions;
    modelOptions.ModelUri = modelUri;
    modelOptions.Parent = modelParent;

    ApiHandle<LoadModelResult> result;
    session->Connection()->LoadModelFromSasAsync(modelOptions,
        // completion callback
        [](Status status, ApiHandle<LoadModelResult> result)
        {
            printf("Loading: finished.");
        },
        // progress callback
        [](float progress)
        {
            printf("Loading: %.1f%%", progress * 100.f);
        }
    );
}

이후에 엔터티 계층 구조를 트래버스하고 엔터티 및 구성 요소를 수정할 수 있습니다. 동일한 모델을 여러 번 로드하면 각각 엔터티/구성 요소 구조의 자체 복사본이 있는 여러 인스턴스가 생성됩니다. 메시, 재질 및 질감이 공유된 리소스이므로 데이터는 다시 로드되지 않습니다. 따라서 모델을 두 번 이상 인스턴스화하면 메모리 오버헤드가 비교적 적게 발생합니다.

API 설명서

다음 단계