XR_EXT_frame_synthesis

מחרוזת שם

XR_EXT_frame_synthesis

סוג התוסף

תוסף למכונה

מספר השלוחה הרשום

212

גרסה

1

סטטוס האישור

לא אושר

תלויות של תוספים וגרסאות

OpenXR 1.0

שותפים ביצירת התוכן

Jian Zhang, Meta Platforms
Neel Bedekar, Meta Platforms
Xiang Wei, Meta Platforms
Guodong Rong, Meta Platforms
Trevor Dasch, Meta Platforms
Rémi Arnaud, Varjo
Paulo Gomes, Samsung Electronics
Bryce Hutchings, Microsoft
Rylie Pavlik, Collabora
Shuai Liu, ByteDance

סקירה כללית

התוסף הזה מספק תמיכה שמאפשרת סינתזת פריימים באפליקציות על סמך נתונים נוספים שהאפליקציה מספקת. האפליקציה יוצרת תמונות וקטוריות של תנועה ותמונות עומק, וסביבת זמן הריצה יכולה להשתמש בהן כדי לבצע אקסטרפולציה והקרנה מחדש של פריימים באיכות גבוהה, וכך ליצור פריים חדש. התהליך הזה מאפשר חוויה חלקה גם כשהאפליקציה פועלת בקצב פריימים לשנייה (FPS) נמוך מהיעד.

התוסף הזה נועד לפעול בנפרד מ-XR_KHR_composition_layer_depth, ואפשר להפעיל את שניהם ולהשתמש בהם בו-זמנית למטרות שונות. יכול להיות ש-XrFrameSynthesisInfoEXT :: depthSubImage ישתמש בנתוני עומק שמיועדים לסינתזת פריימים, והרזולוציה שלו עשויה להיות נמוכה יותר מ-XrCompositionLayerDepthInfoKHR :: subImage . במאמר XrFrameSynthesisConfigViewEXT מוסבר איך לפתור את הבעיה depthSubImage .

שליחת תמונות וקטוריות של תנועה ותמונות עומק

המבנה של XrFrameSynthesisInfoEXT מוגדר כך:

typedef struct XrFrameSynthesisInfoEXT {
    XrStructureType                 type;
    const void*                     next;
    XrFrameSynthesisInfoFlagsEXT    layerFlags;
    XrSwapchainSubImage             motionVectorSubImage;
    XrVector4f                      motionVectorScale;
    XrVector4f                      motionVectorOffset;
    XrPosef                         appSpaceDeltaPose;
    XrSwapchainSubImage             depthSubImage;
    float                           minDepth;
    float                           maxDepth;
    float                           nearZ;
    float                           farZ;
} XrFrameSynthesisInfoEXT;

תיאורי חברים

  • ‫type הוא ה-XrStructureType של המבנה הזה.
  • ‫next הוא NULL או מצביע למבנה הבא בשרשרת מבנים.
  • ‫layerFlags היא מסכת ביטים של XrFrameSynthesisInfoFlagsEXT .
  • ‫motionVectorSubImage מזהה את התמונה הווקטורית של התנועה XrSwapchainSubImage שתשמש לסינתזת הפריימים.
  • ‫motionVectorScale הוא XrVector4f שמשנה את קנה המידה של הפרשנות של וקטור התנועה ב-motionVectorSubImage .
  • ‫motionVectorOffset הוא XrVector4f שמקזז את הפרשנות של וקטור התנועה ב-motionVectorSubImage .
  • ‫appSpaceDeltaPose הוא הטרנספורמציה המצטברת שהאפליקציה החילה, אם יש כזו, שמשפיעה על התצוגה מאז הפריים הקודם. חוויות של תנועה מלאכותית (תנועה מתוסרטת, טלפורטציה וכו') כוללות את האפליקציה שמשנה את כל XrCompositionLayerProjection :: space מתנוחה אחת של מרחב האפליקציה לתנוחה אחרת בין פריימים, ומשפיעה על התצוגה ביותר מהתנועה במעקב בין פריימים. הערך של appSpaceDeltaPose חייב להיות זהה כשאין טרנספורמציה של XrCompositionLayerProjection :: space באפליקציה. ‫XrPosef :: position ב-appSpaceDeltaPose חייב להיות יחסי ל-XrCompositionLayerProjection :: space של האפליקציה הנוכחית.
  • ‫depthSubImage מזהה את תמונת העומק XrSwapchainSubImage שתשמש לסינתזת הפריימים.
  • ‫minDepth ו-maxDepth הם טווח ערכי העומק ב-depthSubImage , וחייבים להיות בטווח [0.0,1.0] . זה דומה לערכי המינימום והמקסימום של glDepthRange ב-OpenGL, אבל עם הדרישה ש-maxDepth ≥ minDepth .
  • ‫nearZ הוא המרחק החיובי במטרים של הערך minDepth בשרשרת ההחלפה של העומק. אפליקציות יכולות להשתמש בערך nearZ שגדול מ-farZ כדי לציין שערכי העומק הפוכים. nearZ עשוי להיות אינסופי.
  • ‫farZ הוא המרחק החיובי במטרים של הערך maxDepth בשרשרת ההחלפה של העומק. farZ עשוי להיות אינסופי. זמן הריצה חייב להחזיר את השגיאה XR_ERROR_VALIDATION_FAILURE אם nearZ == farZ

כששולחים תמונות של וקטור תנועה ותמונות עומק יחד עם שכבות היטל, צריך להוסיף מבנה XrFrameSynthesisInfoEXT לשרשרת XrCompositionLayerProjectionView :: next, לכל מבנה XrCompositionLayerProjectionView בשכבה הנתונה.

זמן הריצה חייב לפרש את נתוני וקטור התנועה בערוצי ה-RGB של motionVectorSubImage, ששונו על ידי motionVectorScale ו-motionVectorOffset באופן הבא: motionVector = motionVectorSubImage rgb * motionVectorScale xyz + motionVectorOffset xyz . המערכת מתעלמת מהרכיבים motionVectorSubImage a , ‏ motionVectorScale w ו-motionVectorOffset w.

וקטור התנועה מייצג את התנועה של פיקסל מאז XrFrameEndInfo ::displayTime של הפריים הקודם עד XrFrameEndInfo ::displayTime של הפריים הנוכחי. יכול להיות שסביבת זמן הריצה תשתמש במידע הזה כדי להסיק מהפריים שעבר רינדור לגבי פריים עתידי.

וקטור התנועה חייב להיות נגזרת של מרחב קואורדינטות מנורמלות של המכשיר (NDC), שבהקשר הזה משתמש במוסכמות בסגנון Vulkan: טווח ה-NDC מוגדר כ-‎[-1, -1, 0] עד [1, 1, 1], בניגוד לטווח ה-NDC של OpenGL. עם זאת, וקטור התנועה עצמו לא מוגבל לטווח הזה. הערכים שלו תלויים בתנועת הפיקסל ויכולים לחרוג מגבולות מרחב ה-NDC. לדוגמה, נניח שה-NDC של פיקסל בפריים הקודם הוא PrevNDC, ובפריים הנוכחי הוא CurrNDC, ואין קנה מידה או היסט, אז הערך של וקטור התנועה הוא " (CurrNDC - PrevNDC) xyz ".

שימוש תקין (משתמע)

הערה

יש הרבה דרכים שונות ליצור את motionVectorSubImage ואת depthSubImage . לדוגמה, האפליקציה יכולה לעבד אותם ברזולוציה נמוכה יותר במעבר וקטור תנועה ייעודי (ראו XrFrameSynthesisConfigViewEXT לרזולוציה מומלצת), או לעבד אותם במעבר התצוגה הראשי באמצעות MRT (יעדי עיבוד מרובים). האפליקציה היא זו שקובעת את הגישה הספציפית. מומלץ להשתמש בפורמטים של ערוצים עם נקודה צפה (float) של 16 ביט עם סימן לכל פיקסל בשביל motionVectorSubImage .

הגדרות של סינתזת פריימים

typedef XrFlags64 XrFrameSynthesisInfoFlagsEXT;

// Flag bits for XrFrameSynthesisInfoFlagsEXT
static const XrFrameSynthesisInfoFlagsEXT XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT = 0x00000001;
static const XrFrameSynthesisInfoFlagsEXT XR_FRAME_SYNTHESIS_INFO_REQUEST_RELAXED_FRAME_INTERVAL_BIT_EXT = 0x00000002;

תיאורי הדגלים

  • ‫XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT מציין שנעשה שימוש בנתוני וקטור תנועה דו-ממדיים.
  • המאפיין XR_FRAME_SYNTHESIS_INFO_REQUEST_RELAXED_FRAME_INTERVAL_BIT_EXT מספק רמז לזמן הריצה שהאפליקציה מעדיפה זמן נוסף כדי לעבד כל פריים, עם הפשרה שזמן הריצה יסנתז יותר פריימים. זה יכול להיות שימושי לאפליקציות שמעדיפות לחסוך בשימוש ב-CPU וב-GPU (למשל, כדי להאריך את חיי הסוללה) או להגדיל את תקציב המחשוב של כל פריים. יכול להיות שזמן הריצה יבקש פריימים בכל מרווח זמן, בלי קשר לערך של הדגל הזה.

כברירת מחדל, סביבת זמן הריצה מצפה לנתוני וקטור תנועה בתלת-ממד, ולכן נעשה שימוש ב-motionVectorSubImage rgb , ב-motionVectorScale xyz וב-motionVectorOffset xyz, כפי שמתואר ב-XrFrameSynthesisInfoEXT .

כשהאפשרות XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT מופעלת ב-XrFrameSynthesisInfoEXT layerFlags , זמן הריצה מפרש את תמונת הווקטור של התנועה שנשלחה כנתוני וקטור של תנועה דו-ממדית, שמייצגים תנועת פיקסלים דו-ממדית מהפריים הקודם לפריים הנוכחי. ערכי הפיקסלים מפורשים באופן הבא עבור נתוני וקטור תנועה דו-ממדיים: motionVector = motionVectorSubImage rg * motionVectorScale xy + motionVectorOffset xy . המערכת מתעלמת מהרכיבים motionVectorSubImage ba , ‏ motionVectorScale zw ו-motionVectorOffset zw. שימוש בנתוני וקטור תנועה דו-ממדיים במקום תלת-ממדיים עלול להפחית את האיכות של הפריימים המסונתזים.

המבנה של XrFrameSynthesisConfigViewEXT מוגדר כך:

typedef struct XrFrameSynthesisConfigViewEXT {
    XrStructureType    type;
    void*              next;
    uint32_t           recommendedMotionVectorImageRectWidth;
    uint32_t           recommendedMotionVectorImageRectHeight;
} XrFrameSynthesisConfigViewEXT;

תיאורי חברים

  • ‫type הוא ה-XrStructureType של המבנה הזה.
  • ‫next הוא NULL או מצביע למבנה הבא בשרשרת מבנים.
  • ‫recommendedMotionVectorImageRectWidth : הרוחב המומלץ של וקטור התנועה ותמונת העומק.
  • ‫recommendedMotionVectorImageRectHeight : הגובה המומלץ של וקטור התנועה ותמונת העומק.

כשהתוסף הזה מופעל, אפליקציה יכולה להעביר מבנה XrFrameSynthesisConfigViewEXT בשרשרת XrViewConfigurationView :: next כשמתבצעת קריאה ל-xrEnumerateViewConfigurationViews כדי לקבל מידע על הרזולוציה המומלצת של תמונת וקטור התנועה.

שימוש תקין (משתמע)

מבנים חדשים

קבועי Enum חדשים

  • XR_EXT_FRAME_SYNTHESIS_EXTENSION_NAME
  • XR_EXT_frame_synthesis_SPEC_VERSION
  • הרחבה של XrStructureType :

    • XR_TYPE_FRAME_SYNTHESIS_CONFIG_VIEW_EXT
    • XR_TYPE_FRAME_SYNTHESIS_INFO_EXT

בעיות

היסטוריית גרסאות

  • גרסה 1, 31.1.2022 (Jian Zhang)

    • תיאור התוסף הראשוני, שהומר מ-fb_space_warp
    • שיתוף פעולה עם תורמים כדי לשפר את ממשקי התוספים.