Aracılığıyla paylaş


Grafik bağlama

Azure Remote Rendering'i özel bir uygulamada kullanabilmek için uygulamanın işleme işlem hattıyla tümleştirilmesi gerekir. Bu tümleştirme grafik bağlamasının sorumluluğundadır.

Grafik bağlaması ayarlandıktan sonra, işlenen görüntüyü etkileyen çeşitli işlevlere erişim verir. Bu işlevler iki kategoriye ayrılabilir: her zaman kullanılabilen genel işlevler ve yalnızca seçilen Microsoft.Azure.RemoteRendering.GraphicsApiTypeiçin uygun olan belirli işlevler.

Unity'de grafik bağlama

Unity'de bağlamanın tamamı içine RemoteManagerUnity.InitializeManagergeçirilen yapısı tarafından RemoteUnityClientInit işlenir. Grafik modunu ayarlamak için alanın GraphicsApiType seçilen bağlamaya ayarlanması gerekir. Alan, bir XRDevice olup olmadığına bağlı olarak otomatik olarak doldurulur. Davranış, aşağıdaki davranışlarla el ile geçersiz kılınabilir:

Unity için tek ilgili bölüm temel bağlamaya erişmektir, aşağıdaki diğer tüm bölümler atlanabilir.

Özel uygulamalarda grafik bağlama kurulumu

Grafik bağlaması seçmek için aşağıdaki iki adımı uygulayın: İlk olarak, program başlatıldığında grafik bağlamasının statik olarak başlatılması gerekir:

RemoteRenderingInitialization managerInit = new RemoteRenderingInitialization();
managerInit.GraphicsApi = GraphicsApiType.OpenXrD3D11;
managerInit.ConnectionType = ConnectionType.General;
managerInit.Right = ///...
RemoteManagerStatic.StartupRemoteRendering(managerInit);
RemoteRenderingInitialization managerInit;
managerInit.GraphicsApi = GraphicsApiType::OpenXrD3D11;
managerInit.ConnectionType = ConnectionType::General;
managerInit.Right = ///...
StartupRemoteRendering(managerInit); // static function in namespace Microsoft::Azure::RemoteRendering

Yukarıdaki çağrı, diğer Uzaktan İşleme API'lerine erişilmeden önce çağrılmalıdır. Benzer şekilde, diğer tüm Uzaktan İşleme nesneleri zaten yok edildikten sonra ilgili de-init işlevi RemoteManagerStatic.ShutdownRemoteRendering(); çağrılmalıdır. Herhangi bir holografik API çağrılmadan önce WMR'nin StartupRemoteRendering de çağrılması gerekir. OpenXR için aynı durum OpenXR ile ilgili tüm API'ler için de geçerlidir.

Grafik bağlamaya erişme

İstemci ayarlandıktan sonra, temel grafik bağlamaya RenderingSession.GraphicsBinding getter ile erişilebilir. Örneğin, son kare istatistikleri aşağıdaki gibi alınabilir:

RenderingSession currentSession = ...;
if (currentSession.GraphicsBinding != null)
{
    FrameStatistics frameStatistics;
    if (currentSession.GraphicsBinding.GetLastFrameStatistics(out frameStatistics) == Result.Success)
    {
        ...
    }
}
ApiHandle<RenderingSession> currentSession = ...;
if (ApiHandle<GraphicsBinding> binding = currentSession->GetGraphicsBinding())
{
    FrameStatistics frameStatistics;
    if (binding->GetLastFrameStatistics(&frameStatistics) == Result::Success)
    {
        ...
    }
}

Grafik API'leri

Şu anda seçilebilen üç grafik API'si vardır: OpenXrD3D11ve WmrD3D11SimD3D11. Dördüncü bir tane Headless var ancak istemci tarafında henüz desteklenmiyor.

OpenXR

GraphicsApiType.OpenXrD3D11 HoloLens 2'de çalıştırılacak varsayılan bağlamadır. Bağlamayı GraphicsBindingOpenXrD3d11 oluşturur. Bu modda Azure Uzaktan İşleme, kendisini OpenXR çalışma zamanıyla tümleştirmek için bir OpenXR API katmanı oluşturur.

Türetilmiş grafik bağlamalarına erişmek için tabanın GraphicsBinding yayınlanması gerekir. OpenXR bağlamasını kullanmak için yapılması gereken üç şey vardır:

Özel OpenXR katman json'larını paketleme

OpenXR ile Uzaktan İşleme'yi kullanmak için özel OpenXR API katmanının etkinleştirilmesi gerekir. Bu işlem, önceki bölümde bahsedilen çağrılarak StartupRemoteRendering yapılır. Ancak, önkoşul XrApiLayer_msft_holographic_remoting.json olarak yüklenebilmesi için uygulamayla birlikte paketlenmesi gerekir. Bir projeye "Microsoft.Azure.RemoteRendering.Cpp" NuGet paketi eklendiğinde bu işlem otomatik olarak yapılır.

Kullanılan XR Alanını Uzaktan İşlemeye Bildirme

Bu, uzak ve yerel olarak işlenmiş içeriği hizalamak için gereklidir.

RenderingSession currentSession = ...;
ulong space = ...; // XrSpace cast to ulong
GraphicsBindingOpenXrD3d11 openXrBinding = (currentSession.GraphicsBinding as GraphicsBindingOpenXrD3d11);
if (openXrBinding.UpdateAppSpace(space) == Result.Success)
{
    ...
}
ApiHandle<RenderingSession> currentSession = ...;
XrSpace space = ...;
ApiHandle<GraphicsBindingOpenXrD3d11> openXrBinding = currentSession->GetGraphicsBinding().as<GraphicsBindingOpenXrD3d11>();
#ifdef _M_ARM64
    if (openXrBinding->UpdateAppSpace(reinterpret_cast<uint64_t>(space)) == Result::Success)
#else
    if (openXrBinding->UpdateAppSpace(space) == Result::Success)
#endif
{
    ...
}

Yukarıdaki XrSpace , API'deki koordinatların ifade edildiği dünya uzay koordinat sistemini tanımlayan uygulama tarafından kullanılan yerdir.

Uzak görüntüyü işleme (OpenXR)

Her çerçevenin başında uzak çerçevenin arka arabellekte işlenmesi gerekir. Bu, her iki gözün renk ve derinlik bilgilerini şu anda bağlı olan işleme hedefine dolduracak olan çağrısıyla BlitRemoteFrameyapılır. Bu nedenle, tam geri arabelleği bir işleme hedefi olarak bağladıktan sonra bunu yapmak önemlidir.

Uyarı

Uzak görüntü arka bölmeye bölündükten sonra, yerel içerik tek geçişli stereo işleme tekniği kullanılarak (örneğin, SV_RenderTargetArrayIndex kullanılarak) işlenmelidir. Her gözü ayrı bir geçişte işleme gibi diğer stereo işleme tekniklerinin kullanılması, önemli performans düşüşlerine veya grafik yapıtlara neden olabilir ve bundan kaçınılmalıdır.

RenderingSession currentSession = ...;
GraphicsBindingOpenXrD3d11 openXrBinding = (currentSession.GraphicsBinding as GraphicsBindingOpenXrD3d11);
openXrBinding.BlitRemoteFrame();
ApiHandle<RenderingSession> currentSession = ...;
ApiHandle<GraphicsBindingOpenXrD3d11> openXrBinding = currentSession->GetGraphicsBinding().as<GraphicsBindingOpenXrD3d11>();
openXrBinding->BlitRemoteFrame();

Windows Mixed Reality

GraphicsApiType.WmrD3D11 , HoloLens 2'de çalıştırmak için daha önce kullanılan grafik bağlamasıdır. Bağlamayı GraphicsBindingWmrD3d11 oluşturur. Bu modda Azure Uzaktan İşleme doğrudan holografik API'lere bağlanıyor.

Türetilmiş grafik bağlamalarına erişmek için tabanın GraphicsBinding yayınlanması gerekir. WMR bağlamasını kullanmak için yapılması gereken iki şey vardır:

Kullanılan koordinat sistemini Uzaktan İşleme'ye bildirme

Bu, uzak ve yerel olarak işlenmiş içeriği hizalamak için gereklidir.

RenderingSession currentSession = ...;
IntPtr ptr = ...; // native pointer to ISpatialCoordinateSystem
GraphicsBindingWmrD3d11 wmrBinding = (currentSession.GraphicsBinding as GraphicsBindingWmrD3d11);
if (wmrBinding.UpdateUserCoordinateSystem(ptr) == Result.Success)
{
    ...
}
ApiHandle<RenderingSession> currentSession = ...;
void* ptr = ...; // native pointer to ISpatialCoordinateSystem
ApiHandle<GraphicsBindingWmrD3d11> wmrBinding = currentSession->GetGraphicsBinding().as<GraphicsBindingWmrD3d11>();
if (wmrBinding->UpdateUserCoordinateSystem(ptr) == Result::Success)
{
    ...
}

Burada yukarıdaki ptr , API'deki koordinatların ifade edildiği dünya uzay koordinat sistemini tanımlayan yerel ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem bir nesnenin işaretçisi olmalıdır.

Uzak görüntüyü işleme (WMR)

Yukarıdaki OpenXR örneğinde dikkat edilmesi gerekenler burada da geçerlidir. API çağrıları şöyle görünür:

RenderingSession currentSession = ...;
GraphicsBindingWmrD3d11 wmrBinding = (currentSession.GraphicsBinding as GraphicsBindingWmrD3d11);
wmrBinding.BlitRemoteFrame();
ApiHandle<RenderingSession> currentSession = ...;
ApiHandle<GraphicsBindingWmrD3d11> wmrBinding = currentSession->GetGraphicsBinding().as<GraphicsBindingWmrD3d11>();
wmrBinding->BlitRemoteFrame();

Simülasyon

GraphicsApiType.SimD3D11 benzetimi bağlamadır ve seçilirse grafik bağlamasını GraphicsBindingSimD3d11 oluşturur. Bu arabirim, örneğin bir masaüstü uygulamasında baş hareketini simüle etmek için kullanılır ve monoskopik bir görüntü işler.

Simülasyon bağlamasını uygulamak için, yerel kamera ile uzak çerçeve arasındaki farkı kamera sayfasında açıklandığı gibi anlamak önemlidir.

İki kamera gerekir:

  • Yerel kamera: Bu kamera, uygulama mantığı tarafından yönetilen geçerli kamera konumunu temsil eder.
  • Ara kamera: Bu kamera, sunucu tarafından gönderilen geçerli Uzak Çerçeve ile eşleşir. Çerçeve isteyen istemci ile gelmesi arasında bir süre gecikme olduğundan, Uzak Çerçeve her zaman yerel kameranın hareketinin biraz gerisindedir.

Buradaki temel yaklaşım, hem uzak görüntünün hem de yerel içeriğin proxy kamera kullanılarak ekran dışı bir hedefe işlenmesidir. Ara sunucu görüntüsü daha sonra yerel kamera alanına yeniden oluşturulur ve bu da geç aşama yeniden oluşturmada daha ayrıntılı bir şekilde açıklanır.

GraphicsApiType.SimD3D11 ayrıca aşağıdaki kurulum çağrısı sırasında etkinleştirilmesi gereken stereoskopik işlemeyi InitSimulation de destekler. Kurulum biraz daha karmaşıktır ve aşağıdaki gibi çalışır:

Ara sunucu işleme hedefi oluşturma

Uzak ve yerel içeriğin işlev tarafından sağlanan ara sunucu kamera verileri kullanılarak 'proxy' olarak adlandırılan ekran dışı bir renk / derinlik işleme hedefine GraphicsBindingSimD3d11.Update işlenmesi gerekir.

Ara sunucu, arka arabelleğin çözünürlüğüyle eşleşmeli ve DXGI_FORMAT_R8G8B8A8_UNORM veya DXGI_FORMAT_B8G8R8A8_UNORM biçiminde olmalıdır. Stereoskopik işleme söz konusu olduğunda hem renk ara sunucusu dokusu hem de derinlik kullanılırsa derinlik ara sunucusu dokusunun bir yerine iki dizi katmanı olması gerekir. Oturum hazır olduğunda, GraphicsBindingSimD3d11.InitSimulation oturuma bağlanmadan önce çağrılmaları gerekir:

RenderingSession currentSession = ...;
IntPtr d3dDevice = ...; // native pointer to ID3D11Device
IntPtr color = ...; // native pointer to ID3D11Texture2D
IntPtr depth = ...; // native pointer to ID3D11Texture2D
float refreshRate = 60.0f; // Monitor refresh rate up to 60hz.
bool flipBlitRemoteFrameTextureVertically = false;
bool flipReprojectTextureVertically = false;
bool stereoscopicRendering = false;
GraphicsBindingSimD3d11 simBinding = (currentSession.GraphicsBinding as GraphicsBindingSimD3d11);
simBinding.InitSimulation(d3dDevice, depth, color, refreshRate, flipBlitRemoteFrameTextureVertically, flipReprojectTextureVertically, stereoscopicRendering);
ApiHandle<RenderingSession> currentSession = ...;
void* d3dDevice = ...; // native pointer to ID3D11Device
void* color = ...; // native pointer to ID3D11Texture2D
void* depth = ...; // native pointer to ID3D11Texture2D
float refreshRate = 60.0f; // Monitor refresh rate up to 60hz.
bool flipBlitRemoteFrameTextureVertically = false;
bool flipReprojectTextureVertically = false;
bool stereoscopicRendering = false;
ApiHandle<GraphicsBindingSimD3d11> simBinding = currentSession->GetGraphicsBinding().as<GraphicsBindingSimD3d11>();
simBinding->InitSimulation(d3dDevice, depth, color, refreshRate, flipBlitRemoteFrameTextureVertically, flipReprojectTextureVertically, stereoscopicRendering);

Init işlevinin yerel d3d cihazının yanı sıra ara sunucu işleme hedefinin renk ve derinlik dokusuna yönelik işaretçilerle sağlanması gerekir. Başlatıldıktan RenderingSession.ConnectAsync sonra ve Disconnect birden çok kez çağrılabilir, ancak farklı bir oturuma geçildiğinde, GraphicsBindingSimD3d11.DeinitSimulation başka bir oturumda çağrılmadan önce GraphicsBindingSimD3d11.InitSimulation eski oturumda çağrılmaları gerekir.

İşleme döngüsü güncelleştirmesi

İşleme döngüsü güncelleştirmesi birden çok adımdan oluşur:

  1. Herhangi bir işleme gerçekleşmeden önce her kare, GraphicsBindingSimD3d11.Update işlenecek sunucuya gönderilen geçerli kamera dönüşümüyle çağrılır. Aynı zamanda, proxy işleme hedefine işlemek için proxy kameraya döndürülen ara sunucu dönüşümü uygulanmalıdır. Döndürülen proxy güncelleştirmesi SimulationUpdate.frameId null ise, henüz uzak veri yoktur. Bu durumda, ara sunucu işleme hedefinde işlemek yerine, tüm yerel içerik geçerli kamera verileri kullanılarak doğrudan arka arabelleğe işlenmelidir ve sonraki iki adım atlanır.
  2. Uygulama artık ara sunucu işleme hedefini bağlamalı ve çağırmalıdır GraphicsBindingSimD3d11.BlitRemoteFrameToProxy. Bu, uzak renk ve derinlik bilgilerini ara sunucu işleme hedefine doldurur. Artık tüm yerel içerikler ara sunucu kamera dönüşümü kullanılarak ara sunucuya işlenebilir.
  3. Ardından, arka arabelleğin bir işleme hedefi olarak bağlanması ve GraphicsBindingSimD3d11.ReprojectProxy bu noktada arka arabelleğin sunulabilmesi için çağrılması gerekir.
RenderingSession currentSession = ...;
GraphicsBindingSimD3d11 simBinding = (currentSession.GraphicsBinding as GraphicsBindingSimD3d11);
SimulationUpdateParameters updateParameters = new SimulationUpdateParameters();
// Fill out camera data with current camera data
// (see "Simulation Update structures" section below)
...
SimulationUpdateResult updateResult = new SimulationUpdateResult();
simBinding.Update(updateParameters, out updateResult);
// Is the frame data valid?
if (updateResult.FrameId != 0)
{
    // Bind proxy render target
    simBinding.BlitRemoteFrameToProxy();
    // Use proxy camera data to render local content
    ...
    // Bind back buffer
    simBinding.ReprojectProxy();
}
else
{
    // Bind back buffer
    // Use current camera data to render local content
    ...
}
ApiHandle<RenderingSession> currentSession;
ApiHandle<GraphicsBindingSimD3d11> simBinding = currentSession->GetGraphicsBinding().as<GraphicsBindingSimD3d11>();

SimulationUpdateParameters updateParameters;
// Fill out camera data with current camera data
// (see "Simulation Update structures" section below)
...
SimulationUpdateResult updateResult;
simBinding->Update(updateParameters, &updateResult);
// Is the frame data valid?
if (updateResult.FrameId != 0)
{
    // Bind proxy render target
    simBinding->BlitRemoteFrameToProxy();
    // Use proxy camera data to render local content
    ...
    // Bind back buffer
    simBinding->ReprojectProxy();
}
else
{
    // Bind back buffer
    // Use current camera data to render local content
    ...
}

Benzetim Güncelleştirme yapıları

Önceki bölümde yer alan İşleme döngüsü güncelleştirmesi , yerel kameraya karşılık gelen bir dizi kamera parametresini girmenizi gerektirir ve kullanılabilir bir sonraki karenin kamerasına karşılık gelen bir dizi kamera parametresi döndürür. Bu iki küme sırasıyla ve SimulationUpdateResult yapılarında SimulationUpdateParameters yakalanır:

public struct SimulationUpdateParameters
{
    public int FrameId;
    public StereoMatrix4x4 ViewTransform;
    public StereoCameraFov FieldOfView;
};

public struct SimulationUpdateResult
{
    public int FrameId;
    public float NearPlaneDistance;
    public float FarPlaneDistance;
    public StereoMatrix4x4 ViewTransform;
    public StereoCameraFov FieldOfView;
};

Yapı üyeleri şu anlama sahiptir:

Üye Açıklama
Çerçeve Kimliği Sürekli çerçeve tanımlayıcısı. SimulationUpdateParameters girişi için gereklidir ve her yeni çerçeve için sürekli olarak artırılmalıdır. Henüz kullanılabilir bir çerçeve verisi yoksa SimulationUpdateResult içinde 0 olur.
ViewTransform Çerçevenin kamera görünümü dönüştürme matrislerinin sol-sağ stereo çifti. Monoskopik işleme için yalnızca Left üye geçerlidir.
Fieldofview OpenXR görüntüleme alanı kuralında çerçeve kamerasının görüş alanlarının sol-sağ stereo çifti. Monoskopik işleme için yalnızca Left üye geçerlidir.
NearPlaneDistance geçerli uzak çerçevenin projeksiyon matrisi için kullanılan yakın düzlem uzaklığı.
FarPlaneDistance geçerli uzak çerçevenin projeksiyon matrisi için kullanılan uzak düzlem uzaklığı.

Stereo-çiftler ViewTransform ve FieldOfView stereoskopik işlemenin etkinleştirilmesi durumunda her iki göz kamerası değerinin ayarlanmasına izin verir. Aksi takdirde, Right üyeler yoksayılır. Gördüğünüz gibi yalnızca kameranın dönüşümü düz 4x4 dönüştürme matrisleri olarak geçirilirken projeksiyon matrisleri belirtilmez. Gerçek matrisler Azure Uzaktan İşleme tarafından, belirtilen görünüm alanları ve Kamera Ayarlar API'sinde geçerli yakın düzlem ve uzak düzlem kümesi kullanılarak dahili olarak hesaplanır.

Çalışma zamanı sırasında Kamera Ayarlar yakın düzlemi ve uzak düzlemi istediğiniz gibi değiştirebileceğinizden ve hizmet bu ayarları zaman uyumsuz olarak uyguladığından, her SimulationUpdateResult ilgili çerçevenin işlenmesi sırasında kullanılan belirli bir yakın düzlemi ve uzak düzlemi de taşır. Bu düzlem değerlerini kullanarak yerel nesneleri işlemek için projeksiyon matrislerinizi uzak çerçeve işlemeyle eşleşecek şekilde uyarlayabilirsiniz.

Son olarak, Simülasyon Güncelleştirmesi çağrısı OpenXR kuralında görüntüleme alanını gerektirirken, standartlaştırma ve algoritmik güvenlik nedenleriyle, aşağıdaki yapı popülasyon örneklerinde gösterilen dönüştürme işlevlerini kullanabilirsiniz:

public SimulationUpdateParameters CreateSimulationUpdateParameters(int frameId, Matrix4x4 viewTransform, Matrix4x4 projectionMatrix)
{
    SimulationUpdateParameters parameters = default;
    parameters.FrameId = frameId;
    parameters.ViewTransform.Left = viewTransform;
    if (parameters.FieldOfView.Left.FromProjectionMatrix(projectionMatrix) != Result.Success)
    {
        // Invalid projection matrix
        throw new ArgumentException("Invalid projection settings");
    }
    return parameters;
}

public void GetCameraSettingsFromSimulationUpdateResult(SimulationUpdateResult result, out Matrix4x4 projectionMatrix, out Matrix4x4 viewTransform, out int frameId)
{
    projectionMatrix = default;
    viewTransform = default;
    frameId = 0;

    if (result.FrameId == 0)
    {
        // Invalid frame data
        return;
    }

    // Use the screenspace depth convention you expect for your projection matrix locally
    if (result.FieldOfView.Left.ToProjectionMatrix(result.NearPlaneDistance, result.FarPlaneDistance, DepthConvention.ZeroToOne, out projectionMatrix) != Result.Success)
    {
        // Invalid field-of-view
        return;
    }
    viewTransform = result.ViewTransform.Left;
    frameId = result.FrameId;
}
SimulationUpdateParameters CreateSimulationUpdateParameters(uint32_t frameId, Matrix4x4 viewTransform, Matrix4x4 projectionMatrix)
{
    SimulationUpdateParameters parameters;
    parameters.FrameId = frameId;
    parameters.ViewTransform.Left = viewTransform;
    if (FovFromProjectionMatrix(projectionMatrix, parameters.FieldOfView.Left) != Result::Success)
    {
        // Invalid projection matrix
        return {};
    }
    return parameters;
}

void GetCameraSettingsFromSimulationUpdateResult(const SimulationUpdateResult& result, Matrix4x4& projectionMatrix, Matrix4x4& viewTransform, uint32_t& frameId)
{
    if (result.FrameId == 0)
    {
        // Invalid frame data
        return;
    }

    // Use the screenspace depth convention you expect for your projection matrix locally
    if (FovToProjectionMatrix(result.FieldOfView.Left, result.NearPlaneDistance, result.FarPlaneDistance, DepthConvention::ZeroToOne, projectionMatrix) != Result::Success)
    {
        // Invalid field-of-view
        return;
    }
    viewTransform = result.ViewTransform.Left;
    frameId = result.FrameId;
}

Bu dönüştürme işlevleri, yerel işleme gereksinimlerinize bağlı olarak görünüm alanı belirtimi ile düz 4x4 perspektif projeksiyon matrisi arasında hızlı geçişe olanak sağlar. Bu dönüştürme işlevleri doğrulama mantığı içerir ve giriş projeksiyon matrislerinin veya giriş görünüm alanlarının geçersiz olması durumunda geçerli bir sonuç ayarlamadan hatalar döndürür.

API belgeleri

Sonraki adımlar