OverlayCamera.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using SXR;
  5. using UnityEngine.Rendering;
  6. namespace Ximmerse.XR.Rendering
  7. {
  8. /// <summary>
  9. /// 用于渲染随头UI/3D 物体的组件。
  10. /// </summary>
  11. public class OverlayCamera : MonoBehaviour
  12. {
  13. /// <summary>
  14. /// Culling mask of the overlay camera
  15. /// </summary>
  16. [Tooltip("Culling mask of the overlay camera")]
  17. public LayerMask cullingMask = 1 << 5;
  18. /// <summary>
  19. /// Depth of the overlay camera
  20. /// </summary>
  21. [Tooltip("Depth of the overlay camera")]
  22. public int depth = 1;
  23. [Range(0.1f, 1)]
  24. public float renderScale = 1;
  25. const int kBufferCount = 1;
  26. RenderTexture[] renderTexturesL = new RenderTexture[kBufferCount];
  27. RenderTexture[] renderTexturesR = new RenderTexture[kBufferCount];
  28. private int rtIndex = 0;
  29. Transform eyeTrans;
  30. Camera overlayCamL, overlayCamR;
  31. /// <summary>
  32. /// Background color of overlay camera
  33. /// </summary>
  34. Color m_overlayBackgroundColor = new Color(0, 0, 0, 0);
  35. public Color overlayBackgroundColor
  36. {
  37. get => m_overlayBackgroundColor;
  38. set
  39. {
  40. m_overlayBackgroundColor = value;
  41. if (overlayCamL)
  42. overlayCamL.backgroundColor = value;
  43. if (overlayCamR)
  44. overlayCamR.backgroundColor = value;
  45. }
  46. }
  47. public void FadeIn(float duration)
  48. {
  49. this.enabled = true;
  50. this.StartCoroutine(fadeIn(duration));
  51. }
  52. public void FadeOut(float duration)
  53. {
  54. this.enabled = true;
  55. this.StartCoroutine(fadeOut(duration));
  56. }
  57. // Start is called before the first frame update
  58. void Start()
  59. {
  60. if (!eyeTrans)
  61. {
  62. eyeTrans = Camera.main.transform;
  63. }
  64. if (!eyeTrans)
  65. {
  66. Debug.LogError("MainCamera is not found , overlay camera failed to start !");
  67. return;
  68. }
  69. bool isAndroid = Application.platform == RuntimePlatform.Android;
  70. Matrix4x4 projectionMatrix = default(Matrix4x4);
  71. float ipd = 0.062f;
  72. if (isAndroid)
  73. {
  74. float l = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_Frustum_Left_FLOAT);
  75. float r = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_Frustum_Right_FLOAT);
  76. float t = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_Frustum_Top_FLOAT);
  77. float b = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_Frustum_Bottom_FLOAT);
  78. float n = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_Frustum_Near_FLOAT);
  79. float f = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_Frustum_Far_FLOAT);
  80. projectionMatrix = GetPerspectiveProjectionMatrix(l, r, b, t, n, f);
  81. ipd = ParamLoader.ParamLoaderGetFloat((int)ParamType.Render_IPD_FLOAT);
  82. }
  83. else
  84. {
  85. projectionMatrix = Matrix4x4.Perspective(Camera.main.fieldOfView, Camera.main.aspect, 0.01f, 1000);
  86. }
  87. //Instantiate overlay cameras:
  88. for (int i = 0; i < kBufferCount; i++)
  89. {
  90. renderTexturesL[i] = new RenderTexture((int)(Screen.width * renderScale), (int)(Screen.height * renderScale), 24, RenderTextureFormat.Default);
  91. if (!renderTexturesL[i].IsCreated())
  92. {
  93. renderTexturesL[i].Create();
  94. }
  95. renderTexturesR[i] = new RenderTexture((int)(Screen.width * renderScale), (int)(Screen.height * renderScale), 24, RenderTextureFormat.Default);
  96. if (!renderTexturesR[i].IsCreated())
  97. {
  98. renderTexturesR[i].Create();
  99. }
  100. }
  101. GameObject overlayCamLGo = new GameObject("Overlay Camera L", new System.Type[] { typeof(Camera) });
  102. GameObject overlayCamRGo = new GameObject("Overlay Camera R", new System.Type[] { typeof(Camera) });
  103. overlayCamL = overlayCamLGo.GetComponent<Camera>();
  104. overlayCamL.clearFlags = CameraClearFlags.SolidColor;
  105. overlayCamL.depth = this.depth;
  106. overlayCamL.backgroundColor = new Color(0, 0, 0, 0);
  107. overlayCamL.cullingMask = this.cullingMask;
  108. overlayCamL.targetTexture = renderTexturesL[0];
  109. overlayCamL.projectionMatrix = projectionMatrix;
  110. overlayCamR = overlayCamRGo.GetComponent<Camera>();
  111. overlayCamR.clearFlags = CameraClearFlags.SolidColor;
  112. overlayCamR.depth = this.depth;
  113. overlayCamR.cullingMask = this.cullingMask;
  114. overlayCamR.backgroundColor = new Color(0, 0, 0, 0);
  115. overlayCamR.targetTexture = renderTexturesR[0];
  116. overlayCamR.projectionMatrix = projectionMatrix;
  117. overlayCamLGo.transform.SetParent(eyeTrans.transform, false);
  118. overlayCamRGo.transform.SetParent(eyeTrans.transform, false);
  119. overlayCamLGo.transform.localPosition = new Vector3(-ipd * 0.5f, 0, 0);
  120. overlayCamRGo.transform.localPosition = new Vector3(ipd * 0.5f, 0, 0);
  121. if (isAndroid)
  122. {
  123. XimmerseXR.OverlayRendering = true;
  124. XimmerseXR.SetOverlayRendererTextureID(overlayCamL.targetTexture.GetNativeTexturePtr().ToInt32(), overlayCamR.targetTexture.GetNativeTexturePtr().ToInt32());
  125. //StartCoroutine(swapFrame());
  126. }
  127. }
  128. private void OnDisable()
  129. {
  130. EnableOverlayCameras(false);
  131. }
  132. private void OnEnable()
  133. {
  134. EnableOverlayCameras(true);
  135. }
  136. private void EnableOverlayCameras(bool enabled)
  137. {
  138. if (overlayCamL)
  139. {
  140. overlayCamL.enabled = enabled;
  141. }
  142. if (overlayCamR)
  143. {
  144. overlayCamR.enabled = enabled;
  145. }
  146. if (Application.platform == RuntimePlatform.Android)
  147. XimmerseXR.OverlayRendering = enabled;
  148. }
  149. //private void OnDestroy()
  150. //{
  151. // // StopCoroutine(swapFrame());
  152. //}
  153. //IEnumerator swapFrame()
  154. //{
  155. // WaitForEndOfFrame eof = new WaitForEndOfFrame();
  156. // while (true)
  157. // {
  158. // yield return eof;
  159. // rtIndex = (rtIndex + 1) % kBufferCount;
  160. // overlayCamL.targetTexture = this.renderTexturesL[rtIndex];
  161. // overlayCamR.targetTexture = this.renderTexturesR[rtIndex];
  162. // XimmerseXR.SetOverlayRendererTextureID(overlayCamL.targetTexture.GetNativeTexturePtr().ToInt32(), overlayCamR.targetTexture.GetNativeTexturePtr().ToInt32());
  163. // }
  164. //}
  165. static Matrix4x4 GetPerspectiveProjectionMatrix(float left, float right, float bottom, float top, float near, float far)
  166. {
  167. float x = 2.0F * near / (right - left);
  168. float y = 2.0F * near / (top - bottom);
  169. float a = (right + left) / (right - left);
  170. float b = (top + bottom) / (top - bottom);
  171. float c = -(far + near) / (far - near);
  172. float d = -(2.0F * far * near) / (far - near);
  173. float e = -1.0F;
  174. Matrix4x4 m = new Matrix4x4();
  175. m[0, 0] = x;
  176. m[0, 1] = 0;
  177. m[0, 2] = a;
  178. m[0, 3] = 0;
  179. m[1, 0] = 0;
  180. m[1, 1] = y;
  181. m[1, 2] = b;
  182. m[1, 3] = 0;
  183. m[2, 0] = 0;
  184. m[2, 1] = 0;
  185. m[2, 2] = c;
  186. m[2, 3] = d;
  187. m[3, 0] = 0;
  188. m[3, 1] = 0;
  189. m[3, 2] = e;
  190. m[3, 3] = 0;
  191. return m;
  192. }
  193. /// <summary>
  194. /// 逐渐变透明
  195. /// </summary>
  196. /// <returns></returns>
  197. IEnumerator fadeIn(float time)
  198. {
  199. EnableOverlayCameras(true);
  200. float st = Time.time;
  201. while ((Time.time - st) <= time)
  202. {
  203. float _alpha = 1 - (Time.time - st / 1);
  204. overlayBackgroundColor = new Color(0, 0, 0, _alpha);
  205. // Debug.LogFormat("FadeIn setting overlay alpha: {0}", _alpha);
  206. yield return null;
  207. }
  208. overlayBackgroundColor = new Color(0, 0, 0, 0);
  209. EnableOverlayCameras(false);
  210. }
  211. /// <summary>
  212. /// 逐渐变黑
  213. /// </summary>
  214. /// <returns></returns>
  215. IEnumerator fadeOut(float time)
  216. {
  217. EnableOverlayCameras(true);
  218. float st = Time.time;
  219. while ((Time.time - st) <= time)
  220. {
  221. float _alpha = (Time.time - st) / time;
  222. overlayBackgroundColor = new Color(0, 0, 0, _alpha);
  223. // Debug.LogFormat("FadeOut setting overlay alpha: {0}", _alpha);
  224. yield return null;
  225. }
  226. overlayBackgroundColor = new Color(0, 0, 0, 1);
  227. EnableOverlayCameras(true);
  228. }
  229. }
  230. }