你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
模型
Azure 远程渲染中的模型指的是一个完整的对象表示法,由多个实体和组件构成。 模型是将自定义数据引入远程渲染服务的主要方式。
模型结构
一个模型恰好有一个实体作为其根节点。 在该实体之下,可能有任意层次结构的子实体。 加载模型时,系统将返回对此根实体的引用。
每个实体都可能有附加的组件。 在最常见的情况下,实体具有 MeshComponents,该组件引用了网格资源。
创建模型
通过从文件格式(例如 FBX、GLTF 和 E57)转换输入模型来创建运行时模型。 转换过程将提取所有资源,例如纹理、材料和网格,并将其转换为优化的运行时格式。 该过程还将提取结构信息,并将其转换为 ARR 的实体/组件图结构。
加载模型
转换模型后,可将其从 Azure Blob 存储加载到运行时。
这里有两种不同的加载函数,它们在 Blob 存储中对资产的寻址方式不同:
- 如果 Blob 存储已关联到帐户,则可直接按 Blob 存储参数直接对模型进行寻址。 在本例中,相关的加载函数为具有参数
LoadModelOptions
的LoadModelAsync
。 - 可以通过模型的 SAS URI 对模型进行寻址。 相关的加载函数为
LoadModelFromSasAsync
,其参数为LoadModelFromSasOptions
。 加载内置模型时也使用此变体。
以下代码片段演示了如何使用这两个函数加载模型。 要使用 Blob 存储参数加载模型,请使用类似以下的代码:
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 文档
- C# RenderingConnection.LoadModelAsync()
- C# RenderingConnection.LoadModelFromSasAsync()
- C++ RenderingConnection::LoadModelAsync()
- C++ RenderingConnection::LoadModelFromSasAsync()