ar_passthrough.rst 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. .. _doc_openxr_passthrough:
  2. AR / Passthrough
  3. ================
  4. Augmented Reality is supported through various methods depending on the capabilities of the hardware.
  5. Headsets such as the Magic Leap and glasses such as TiltFive show the rendered result on
  6. `see-through displays <https://en.wikipedia.org/wiki/See-through_display>`__ allowing the user
  7. to see the real world.
  8. Headsets such as the Quest, HTC Elite, and Lynx R1 implement this through a technique called video passthrough,
  9. where cameras record the real world and these images are used as the background on top of which our rendered
  10. result is used.
  11. .. note::
  12. Passthrough is implemented very differently across platforms.
  13. In Godot 4.3 we have implemented a unified approach that is explained on this help page
  14. so you don't need to worry about these differences, the :ref:`XRInterface <class_xrinterface>`
  15. implementation is now responsible for applying the correct platform-dependent method [#]_.
  16. For headsets such as the Meta Quest and HTC Elite you will need to use the
  17. `OpenXR vendors plugin v3.0.0 <https://github.com/GodotVR/godot_openxr_vendors/releases>`__
  18. or later to enable video passthrough.
  19. For backwards compatibility the old API for passthrough is still available but it is recommended
  20. to follow the new instructions below.
  21. Environment blend modes
  22. -----------------------
  23. The way we configure VR or AR functionality is through setting the environment blend mode.
  24. This mode determines how the (real world) environment is blended with the virtual world.
  25. .. list-table:: Blend modes
  26. :widths: 35 65
  27. :header-rows: 1
  28. * - Blend mode
  29. - Description
  30. * - XR_ENV_BLEND_MODE_OPAQUE
  31. - The rendered image is opaque, we do not see the real world. We're in VR mode.
  32. This will turn off passthrough if video-passthrough is used.
  33. * - XR_ENV_BLEND_MODE_ADDITIVE
  34. - The rendered image is added to the real world and will look semi transparent.
  35. This mode is generally used with see-through devices that are unable to obscure
  36. the real world.
  37. This will turn on passthrough if video-passthrough is used.
  38. * - XR_ENV_BLEND_MODE_ALPHA_BLEND
  39. - The rendered image is alpha blended with the real world.
  40. On see-through devices that support this, the alpha will control the translucency
  41. of the optics.
  42. On video-passthrough devices alpha blending is applied with the video image.
  43. passthrough will also be enabled if applicable.
  44. You can set the environment blend mode for your application through the ``environment_blend_mode``
  45. property of the :ref:`XRInterface <class_xrinterface>` instance.
  46. You can query the supported blend modes on the hardware using the
  47. ``get_supported_environment_blend_modes`` property on the same instance.
  48. Configuring your background
  49. ---------------------------
  50. When setting the blend mode to ``XR_ENV_BLEND_MODE_ALPHA_BLEND`` you must set
  51. the ``transparent_bg`` property on :ref:`Viewport <class_viewport>` to true.
  52. When using the ``XR_ENV_BLEND_MODE_ADDITIVE`` blend mode you should set your
  53. background color to black.
  54. Either solution will result in the background rendering not contributing to lighting.
  55. It is thus also recommended you adjust your environment settings accordingly and ensure
  56. there is adequate ambient light set to illuminate your scene.
  57. .. note::
  58. Some AR SDKs do provide ambient lighting information or even provide a full radiance
  59. map to allow for real world reflections in your virtual objects.
  60. The core Godot XR functionality doesn't currently have support for this, however this
  61. functionality can be exposed through plugins.
  62. OpenXR specific
  63. ---------------
  64. In OpenXR you can configure the default blend mode you want to use.
  65. Godot will select this blend mode at startup if available.
  66. If not available Godot will default to the first supported blend mode provided
  67. by the XR runtime.
  68. .. image:: img/openxr_default_blend_mode.webp
  69. For passthrough devices OpenXR requires additional settings to be configured.
  70. These settings are platform-dependent and provided through the OpenXR vendors plugin.
  71. For example, these are the settings required on Meta Quest:
  72. .. image:: img/openxr_export_passthrough.webp
  73. The ``Passthrough`` setting defines whether passthrough is supported or even required.
  74. The ``Boundary Mode`` allows you to define whether the guardian is needed,
  75. disabling this fully requires passthrough to be enabled at all times.
  76. Putting it together
  77. -------------------
  78. Putting the above together we can use the following code as a base:
  79. .. code-block:: gdscript
  80. @onready var viewport : Viewport = get_viewport()
  81. @onready var environment : Environment = $WorldEnvironment.environment
  82. func switch_to_ar() -> bool:
  83. var xr_interface: XRInterface = XRServer.primary_interface
  84. if xr_interface:
  85. var modes = xr_interface.get_supported_environment_blend_modes()
  86. if XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND in modes:
  87. xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND
  88. viewport.transparent_bg = true
  89. elif XRInterface.XR_ENV_BLEND_MODE_ADDITIVE in modes:
  90. xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_ADDITIVE
  91. viewport.transparent_bg = false
  92. else:
  93. return false
  94. environment.background_mode = Environment.BG_COLOR
  95. environment.background_color = Color(0.0, 0.0, 0.0, 0.0)
  96. environment.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
  97. return true
  98. func switch_to_vr() -> bool:
  99. var xr_interface: XRInterface = XRServer.primary_interface
  100. if xr_interface:
  101. var modes = xr_interface.get_supported_environment_blend_modes()
  102. if XRInterface.XR_ENV_BLEND_MODE_OPAQUE in modes:
  103. xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_OPAQUE
  104. else:
  105. return false
  106. viewport.transparent_bg = false
  107. environment.background_mode = Environment.BG_SKY
  108. environment.ambient_light_source = Environment.AMBIENT_SOURCE_BG
  109. return true
  110. Shadow to opacity
  111. -----------------
  112. Shadow to opacity is a render mode for Godot spatial shaders
  113. that was introduced in Godot 3 specifically for AR.
  114. It is a special render mode where the more a surface is in shadow,
  115. the more opaque the surface becomes. When a surface is fully lit,
  116. the surface becomes fully transparent and thus shows the real world.
  117. However the surface is rendered during the opaque state effectively.
  118. This has two consequences:
  119. * As both the depth buffer and color buffer are written to, we occlude
  120. any geometry behind our surface even when fully transparent.
  121. * As we are making the surface opaque if in shadow, we can have virtual
  122. objects cast shadows on real world objects [#]_.
  123. .. figure:: img/xr_passthrough_example.webp
  124. :alt: Image showing shadow to opacity being used to show the users desk.
  125. Image showing shadow to opacity being used to show the users desk.
  126. This enabled the following use cases:
  127. * You can render a box mesh around a real world table, this ensures the
  128. table remains visible even if a virtual object is placed underneath it.
  129. The virtual object will be correctly occluded.
  130. Placing a virtual object on top of the real world table, will result in
  131. a shadow being cast on the table.
  132. * You can use a shader with this render mode when render a hand mesh
  133. using the hand tracking functionality, and ensure your hands properly
  134. occlude virtual objects.
  135. The following shader code is a good base for this functionality:
  136. .. code-block:: glsl
  137. shader_type spatial;
  138. render_mode blend_mix, depth_draw_opaque, cull_back, shadow_to_opacity;
  139. void fragment() {
  140. ALBEDO = vec3(0.0, 0.0, 0.0);
  141. }
  142. .. [#] Restrictions may apply depending on XR interface implementation.
  143. .. [#] This feature is still being perfected.