إعادة طرح المرحلة المتأخرة

إعادة حماية المراحل المتأخرة (LSR) هي ميزة أجهزة تساعد على تثبيت الصور الثلاثية الأبعاد عند تحرك المستخدم.

من المتوقع أن تحافظ النماذج الثابتة على موضعها بصريا عند التنقل حولها. إذا بدت غير مستقرة، فقد يشير هذا السلوك إلى مشكلات LSR. ضع في اعتبارك أن التحويلات الديناميكية الإضافية، مثل الرسوم المتحركة أو طرق عرض الانفجار، قد تخفي هذا السلوك.

يمكنك الاختيار بين وضعي LSR مختلفين، وهما Planar LSR أو Depth LSR. يعمل كلا وضعي LSR على تحسين استقرار الصور الثلاثية الأبعاد، على الرغم من أن لديهم قيود مميزة. ابدأ بتجربة Depth LSR، حيث إنه يعطي نتائج أفضل في معظم الحالات.

كيفية تعيين وضع LSR

يتم تحديد أي من أوضاع LSR المستخدمة من خلال ما إذا كان تطبيق العميل يرسل مخزنا مؤقتا للعمق. إذا تم إرسال مخزن العمق المؤقت، فإنه يستخدم Depth LSR وPlanar LSR بخلاف ذلك.

توضح الفقرات التالية كيفية تقديم المخزن المؤقت للعمق في Unity والتطبيقات الأصلية على التوالي.

Unity

في محرر Unity، انتقل إلى File > Build Settings. حدد Player Settings في أسفل اليسار، ثم حدد ضمن Player > XR Settings > Virtual Reality SDKs > Windows Mixed Reality ما إذا كان Enable Depth Buffer Sharing محددا:

العلامة

إذا كان كذلك، فسيستخدم تطبيقك Depth LSR، وإلا فإنه سيستخدم Planar LSR.

عند استخدام OpenXR، يجب إرسال مخزن العمق المؤقت دائما. يمكن العثور على الإعداد في XR Plug-in Management > OpenXR. يمكن بعد ذلك تغيير وضع إعادة الحماية عبر ملحق في المكون الإضافي OpenXR:

using Microsoft.MixedReality.OpenXR;

public class OverrideReprojection : MonoBehaviour
{
    void OnEnable()
    {
        RenderPipelineManager.endCameraRendering += RenderPipelineManager_endCameraRendering;
    }
    void OnDisable()
    {
        RenderPipelineManager.endCameraRendering -= RenderPipelineManager_endCameraRendering;
    }

    // When using the Universal Render Pipeline, OnPostRender has to be called manually.
    private void RenderPipelineManager_endCameraRendering(ScriptableRenderContext context, Camera camera)
    {
        OnPostRender();
    }

    // Called directly when using Unity's legacy renderer.
    private void OnPostRender()
    {
        ReprojectionSettings reprojectionSettings = default;
        reprojectionSettings.ReprojectionMode = ReprojectionMode.PlanarManual; // Or your favorite reprojection mode.
        
        // In case of PlanarManual you also need to provide a focus point here.
        reprojectionSettings.ReprojectionPlaneOverridePosition = ...;
        reprojectionSettings.ReprojectionPlaneOverrideNormal = ...;
        reprojectionSettings.ReprojectionPlaneOverrideVelocity = ...;

        foreach (ViewConfiguration viewConfiguration in ViewConfiguration.EnabledViewConfigurations)
        {
            if (viewConfiguration.IsActive && viewConfiguration.SupportedReprojectionModes.Contains(reprojectionSettings.ReprojectionMode))
            {
                viewConfiguration.SetReprojectionSettings(reprojectionSettings);
            }
        }
    }
}

تطبيقات C++ الأصلية

يخضع إرسال المخزن المؤقت للعمق للتحكم الكامل في التعليمات البرمجية الأصلية لربط C++، بغض النظر عن إصدار WMR أو OpenXR. الشرط الوحيد الذي يجب تلبيته هو أنه في الوقت الذي GraphicsBinding::BlitRemoteFrame يتم استدعاؤه، يجب ربط مخزن مؤقت للعمق بواجهة برمجة تطبيقات الرسومات.

عمق LSR

لكي يعمل Depth LSR، يجب أن يوفر تطبيق العميل مخزنا مؤقتا صحيحا للعمق يحتوي على جميع الهندسة ذات الصلة التي يجب مراعاتها أثناء LSR.

يحاول Depth LSR تثبيت إطار الفيديو استنادا إلى محتويات المخزن المؤقت للعمق المتوفر. ونتيجة لذلك، لا يمكن تعديل المحتوى الذي لم يتم عرضه عليه، مثل الكائنات الشفافة، بواسطة LSR وقد يظهر عدم الاستقرار وإعادة الحماية من البيانات الاصطناعية.

للتخفيف من عدم استقرار إعادة الحماية للكائنات الشفافة، يمكنك فرض كتابة المخزن المؤقت للعمق. راجع علامة المادة الشفافيةWritesDepth لمواد اللون وPBR. ومع ذلك، لاحظ أن الجودة المرئية لتفاعل الكائن الشفاف/المبهم قد تعاني عند تمكين هذه العلامة.

Planar LSR

لا يحتوي Planar LSR على معلومات العمق لكل بكسل، كما يفعل Depth LSR. بدلا من ذلك، فإنه يعيد مشروع جميع المحتويات استنادا إلى مستوى يجب توفير كل إطار.

تعيد Planar LSR مشروع تلك الكائنات الأفضل التي تقع بالقرب من الطائرة التي تم توفيرها. كلما كان الكائن بعيدا، كلما كان غير مستقر سيبدو. بينما يكون Depth LSR أفضل في إعادة حماية الكائنات في أعماق مختلفة، قد يعمل Planar LSR بشكل أفضل للمحتوى الذي يحاذي المستوى بشكل جيد.

تكوين Planar LSR في Unity

يتم اشتقاق معلمات المستوى من ما يسمى نقطة التركيز. عند استخدام WMR، يجب تعيين نقطة التركيز في كل إطار من خلال UnityEngine.XR.WSA.HolographicSettings.SetFocusPointForFrame. راجع Unity Focus Point API للحصول على التفاصيل. بالنسبة إلى OpenXR، يجب تعيين نقطة التركيز عبر الموضح ReprojectionSettings في القسم السابق. إذا لم تقم بتعيين نقطة تركيز، اختيار احتياطي لك. ومع ذلك، غالبا ما يؤدي التراجع التلقائي إلى نتائج دون المستوى الأمثل.

يمكنك حساب نقطة التركيز بنفسك، على الرغم من أنه قد يكون من المنطقي أن تستند إلى النقطة المحسوبة من قبل مضيف Remote Rendering. اتصل RemoteManagerUnity.CurrentSession.GraphicsBinding.GetRemoteFocusPoint للحصول على ذلك.

عادة ما يعرض كل من العميل والمضيف محتوى لا يدركه الجانب الآخر، مثل عناصر واجهة المستخدم على العميل. لذلك، قد يكون من المنطقي دمج نقطة التركيز عن بعد مع نقطة محسوبة محليا.

يمكن أن تختلف نقاط التركيز المحسوبة في إطارين متتاليين كثيرا. يمكن أن يؤدي استخدامها ببساطة كما هي إلى الصور المجسمة التي تظهر على أنها تقفز حولها. لمنع هذا السلوك، ينصح بالاستنتاج بين نقاط التركيز السابقة والحالية.

أوضاع وضع إعادة الحماية

يمكن ذكر نطاق المشكلة العامة مع العرض المختلط على هذا النحو: المحتويات البعيدة والمحلية تقع ضمن وضعيات مميزة (أي مسافات الإحداثيات) لأن الوضع البعيد يتم التنبؤ به من قبل الخادم بينما تكون الوضعية المحلية هي الوضع الحالي الفعلي. ومع ذلك، في نهاية إطار العرض، يجب محاذاة المحتوى البعيد والمحلي وتقديمه إلى العرض. يوضح الرسم التوضيحي التالي مثالا حيث تتم ترجمة الوضعين المحلي والنائية مقارنة بمنفذ عرض العرض:

رسم تخطيطي يوضح الوضعية البعيدة والمحلية فيما يتعلق بمنفذ العرض الهدف.

اعتمادا على GraphicsBinding المستخدم، يوفر ARR ما يصل إلى ثلاثة أوضاع لإعادة الحماية تعمل بشكل تقويمي إلى وضع LSR الذي تمت مناقشته أعلاه. يشار إلى هذه الأوضاع باسم Remote pose modeو Local pose modeو.Passthrough pose mode على عكس وضع LSR، تحدد أوضاع الوضع كيفية دمج المحتوى البعيد والمحلي. اختيار الوضع يتداول الجودة المرئية للمحتوى المحلي لأداء وقت التشغيل، لذلك يجب أن تنظر التطبيقات بعناية في الخيار المناسب. راجع الاعتبارات أدناه.

Remote pose mode

Remote pose mode هو الوضع الافتراضي في ARR. في هذا الوضع، يتم عرض المحتوى المحلي أعلى دفق الصور البعيدة الواردة باستخدام الوضع البعيد من الإطار البعيد. ثم تتم إعادة توجيه النتيجة المجمعة إلى نظام التشغيل لإعادة المشروع النهائي. بينما يستخدم هذا الأسلوب إعادة حماية واحدة فقط، يعتمد التصحيح النهائي على الفاصل الزمني ذهابا وإيابا بحيث يتم تطبيق خطأ إعادة الحماية الكامل على المحتوى المحلي أيضا. ونتيجة لذلك، قد تؤدي دلتا التصحيح الكبيرة إلى تشوهات كبيرة في الهندسة المحلية بما في ذلك عناصر واجهة المستخدم.

باستخدام الرسم التوضيحي أعلاه، يتم تطبيق التحويل التالي في Remote pose mode:

خطوات إعادة الحماية في وضع الوضع البعيد.

Local pose mode

في هذا الوضع، يتم تقسيم إعادة الحماية إلى خطوتين متميزتين: في الخطوة الأولى، تتم إعادة مشروع المحتوى البعيد إلى مساحة وضع محلية، أي المساحة التي يتم عرض المحتوى المحلي بها على أجهزة الواقع الافتراضي/AR بشكل افتراضي. بعد ذلك، يتم عرض المحتوى المحلي أعلى هذه الصورة التي تم تحويلها مسبقا باستخدام الوضع المحلي المعتاد. في الخطوة الثانية، تتم إعادة توجيه النتيجة المجمعة إلى نظام التشغيل لإعادة المشروع النهائي. نظرا لأن إعادة الحماية الثانية هذه لا تتحمل سوى دلتا صغيرة - في الواقع نفس الدلتا التي سيتم استخدامها إذا لم يكن ARR موجودا - يتم التخفيف من آثار التشويه على المحتوى المحلي بشكل كبير.

وفقا لذلك، يبدو الرسم التوضيحي كما يلي:

خطوات إعادة الحماية في وضع الوضع المحلي.

Passthrough pose mode

يعمل وضع الوضع هذا بشكل أساسي بنفس Remote pose modeسلوك ، مما يعني دمج المحتوى المحلي والنائية في المساحة البعيدة. ومع ذلك، لن تتم إعادة مشروع المحتوى بعد الجمع ولكن يبقى في مساحة وضعية بعيدة. الميزة الرئيسية لهذا الوضع هي أن الصورة الناتجة لن تتأثر بالأدوات إعادة الحماية.

من الناحية المفاهيمية، يمكن مقارنة هذا الوضع بتطبيقات تدفق السحابة التقليدية. نظرا إلى زمن الانتقال العالي الذي يتطلبه، فهو غير مناسب للسيناريوهات المثبتة على الرأس، ولكنه بديل قابل للتطبيقات الأخرى لسطح المكتب وتطبيقات الشاشة المسطحة الأخرى حيث تكون جودة الصورة أعلى مطلوبة. لذلك فهي متاحة GraphicsBindingSimD3D11 فقط في الوقت الحالي.

اعتبارات الأداء والجودة

اختيار وضع الوضع له جودة بصرية وتأثيرات الأداء. تبلغ تكلفة وقت التشغيل الإضافية على جانب العميل لإجراء إعادة الحماية الإضافية على Local pose mode جهاز HoloLens 2 حوالي 1 مللي ثانية لكل إطار من وقت وحدة معالجة الرسومات. يجب وضع هذه التكلفة الإضافية في الاعتبار إذا كان تطبيق العميل قريبا بالفعل من ميزانية الإطار البالغة 16 مللي ثانية. من ناحية أخرى، هناك أنواع من التطبيقات التي لا يوجد بها محتوى محلي أو محتوى محلي غير عرضة للتشويه. في هذه الحالات Local pose mode لا تكتسب أي فائدة مرئية لأن جودة إعادة حماية المحتوى عن بعد لا تتأثر.

ومن ثم فإن النصيحة العامة هي اختبار الأوضاع على أساس كل حالة استخدام ومعرفة ما إذا كان الكسب في الجودة البصرية يبرر النفقات الإضافية للأداء. من الممكن أيضا تبديل الوضع ديناميكيا، على سبيل المثال تمكين الوضع المحلي فقط عند عرض واجهات المستخدم المهمة.

كيفية تغيير في Pose mode وقت التشغيل

يمكن استخدام واجهة برمجة تطبيقات العميل التالية لتغيير الوضع في وقت التشغيل:

RenderingSession session = ...;
session.GraphicsBinding.SetPoseMode(PoseMode.Local); // set local pose mode
ApiHandle<RenderingSession> session = ...;
session->GetGraphicsBinding()->SetPoseMode(PoseMode::Local); // set local pose mode

بشكل عام، يمكن تغيير الوضع في أي وقت يتوفر فيه كائن ربط الرسومات. هناك تمييز مهم ل GraphicsBindingSimD3D11: لا يمكن تغيير وضع الوضع إلا إلى PoseMode.Remote، إذا تمت تهيئته باستخدام مواد الوكيل. إذا لم يكن الأمر كذلك، فلا يمكن تبديل وضع الوضع إلا بين PoseMode.Local و PoseMode.Passthrough حتى تتم إعادة تهيئة ربط الرسومات. راجع التحميلين الزائدين ل GraphicsBindingSimD3d11.InitSimulation، والتي تأخذ إما المؤشرات الأصلية إلى كائنات ID3D11Texture2D (مسار الوكيل) أو width منفذ height عرض المستخدم المطلوب (مسار غير وكيل).

اعتبارات وقت تشغيل Desktop Unity

نظرا للخلفية GraphicsBindingSimD3D11 التقنية ل وحقيقة كيفية عمل العرض خارج الشاشة في Unity، يتطلب وقت تشغيل ARR Unity من المستخدم تحديد وضع الوضع المطلوب عند بدء التشغيل RemoteManagerUnity على النحو التالي:

public static void InitRemoteManager(Camera camera)
{
    RemoteUnityClientInit clientInit = new RemoteUnityClientInit(camera, PoseMode.Remote);
    RemoteManagerUnity.InitializeManager(clientInit);
}

إذا PoseMode.Remote تم تحديده، تهيئة ربط الرسومات باستخدام مواد وكيل خارج الشاشة، وستتم إعادة توجيه جميع عمليات العرض من الكاميرا الرئيسية لمشهد Unity إلى كاميرا وكيل. يوصى باستخدام مسار التعليمات البرمجية هذا فقط إذا كان وضع PoseMode.Remote وضع وضع وقت التشغيل مطلوبا. إذا لم يتم تحديد وضع الوضع، فسيحدد وقت تشغيل ARR Unity افتراضيا مناسبا اعتمادا على النظام الأساسي الحالي.

تحذير

قد تكون إعادة توجيه كاميرا الوكيل غير متوافقة مع ملحقات Unity الأخرى، والتي تتوقع تقديم المشهد مع الكاميرا الرئيسية. يمكن استرداد كاميرا الوكيل عبر الخاصية RemoteManagerUnity.ProxyCamera إذا كانت بحاجة إلى الاستعلام عنها أو تسجيلها في مكان آخر. خصيصا للمكون Cinemachine الإضافي، راجع إدخال استكشاف الأخطاء وإصلاحها هذا: لا يعمل المكون الإضافي Unity Cinemachine في وضع الوضع عن بعد.

إذا تم PoseMode.Local استخدام أو PoseMode.Passthrough بدلا من ذلك، فلن تتم تهيئة ربط الرسومات باستخدام مواد وكيل خارج الشاشة، وسيتم استخدام مسار سريع باستخدام الكاميرا الرئيسية لمشهد Unity للعرض. إذا كانت حالة الاستخدام المعنية تتطلب وضع وضع الوضع عن بعد في وقت التشغيل، PoseMode.Remote يجب تحديدها عند RemoteManagerUnity التهيئة. العرض المباشر باستخدام الكاميرا الرئيسية ل Unity أكثر كفاءة ويمكن أن يمنع المشكلات مع ملحقات Unity الأخرى. لذلك، يوصى باستخدام مسار العرض غير الوكيل.

الخطوات التالية