AndroidSinglePassViewportShader.shader 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // <copyright file="VideoUnlitShader.cs" company="Google Inc.">
  2. // Copyright (C) 2017 Google Inc. All Rights Reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. // </copyright>
  16. // This shader is a modified version of VideoUnlitShader.cs from the Unity Google VR SDK.
  17. // It's the same as AndroidViewportShader.shader, except its vertex shader is
  18. // modified to work with single-pass stereo rendering on Android.
  19. // Thanks to Tom Neumann at Rendever (@Mandelboxed) for this solution:
  20. // https://forum.unity.com/threads/unity_stereoeyeindex-with-glsl-single-pass-implementation-details.592990/#post-3982708
  21. Shader "Vuplex/Android Single Pass Stereo Viewport Shader" {
  22. Properties {
  23. _MainTex ("Base (RGB)", 2D) = "white" {}
  24. [Toggle(FLIP_X)] _FlipX ("Flip X", Float) = 0
  25. [Toggle(FLIP_Y)] _FlipY ("Flip Y", Float) = 0
  26. [Header(Properties set programmatically)]
  27. _VideoCutoutRect("Video Cutout Rect", Vector) = (0, 0, 0, 0)
  28. _CropRect("Crop Rect", Vector) = (0, 0, 0, 0)
  29. // Include these UI properties from UI-Default.shader
  30. // in order to support UI Scroll Views.
  31. _StencilComp ("Stencil Comparison", Float) = 8
  32. _Stencil ("Stencil ID", Float) = 0
  33. _StencilOp ("Stencil Operation", Float) = 0
  34. _StencilWriteMask ("Stencil Write Mask", Float) = 255
  35. _StencilReadMask ("Stencil Read Mask", Float) = 255
  36. _ColorMask ("Color Mask", Float) = 15
  37. }
  38. SubShader {
  39. Pass {
  40. Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
  41. // Include these UI properties from UI-Default.shader
  42. // in order to support UI Scroll Views.
  43. Stencil {
  44. Ref [_Stencil]
  45. Comp [_StencilComp]
  46. Pass [_StencilOp]
  47. ReadMask [_StencilReadMask]
  48. WriteMask [_StencilWriteMask]
  49. }
  50. Lighting Off
  51. ZWrite Off
  52. Blend SrcAlpha OneMinusSrcAlpha
  53. ColorMask [_ColorMask]
  54. GLSLPROGRAM
  55. #pragma multi_compile ___ FLIP_X
  56. #pragma multi_compile ___ FLIP_Y
  57. #pragma multi_compile _ UNITY_COLORSPACE_GAMMA
  58. #ifdef VERTEX
  59. #version 300 es
  60. #extension GL_OVR_multiview2 : require
  61. #extension GL_OES_EGL_image_external : require
  62. #extension GL_OES_EGL_image_external_essl3 : enable
  63. uniform vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
  64. uniform vec4 _MainTex_ST;
  65. layout(std140) uniform UnityStereoGlobals {
  66. vec4 hlslcc_mtx4x4unity_StereoMatrixP[8];
  67. vec4 hlslcc_mtx4x4unity_StereoMatrixV[8];
  68. vec4 hlslcc_mtx4x4unity_StereoMatrixInvV[8];
  69. vec4 hlslcc_mtx4x4unity_StereoMatrixVP[8];
  70. vec4 hlslcc_mtx4x4unity_StereoCameraProjection[8];
  71. vec4 hlslcc_mtx4x4unity_StereoCameraInvProjection[8];
  72. vec4 hlslcc_mtx4x4unity_StereoWorldToCamera[8];
  73. vec4 hlslcc_mtx4x4unity_StereoCameraToWorld[8];
  74. vec3 unity_StereoWorldSpaceCameraPos[2];
  75. vec4 unity_StereoScaleOffset[2];
  76. };
  77. layout(num_views = 2) in;
  78. in highp vec4 in_POSITION0;
  79. in highp vec2 in_TEXCOORD0;
  80. out highp vec2 uv;
  81. vec4 u_xlat0;
  82. int u_xlati1;
  83. vec4 u_xlat2;
  84. // Pass the vertex color to the fragment shader
  85. // so that it can be used for calculating alpha.
  86. // This is needed, for example, to allow CanvasGroup.alpha
  87. // to control the alpha.
  88. varying vec4 vertexColor;
  89. void main() {
  90. vec2 untransformedUV = in_TEXCOORD0;
  91. vertexColor = gl_Color;
  92. u_xlati1 = int(gl_ViewID_OVR) << 2;
  93. #ifdef FLIP_X
  94. untransformedUV.x = 1.0 - untransformedUV.x;
  95. #endif
  96. #ifdef FLIP_Y
  97. untransformedUV.y = 1.0 - untransformedUV.y;
  98. #endif
  99. // Handle single pass stereo rendering
  100. uv.xy = untransformedUV.xy * _MainTex_ST.xy + _MainTex_ST.zw;
  101. u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
  102. u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0] * in_POSITION0.xxxx + u_xlat0;
  103. u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2] * in_POSITION0.zzzz + u_xlat0;
  104. u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
  105. u_xlat2 = u_xlat0.yyyy * hlslcc_mtx4x4unity_StereoMatrixVP[(u_xlati1 + 1)];
  106. u_xlat2 = hlslcc_mtx4x4unity_StereoMatrixVP[u_xlati1] * u_xlat0.xxxx + u_xlat2;
  107. u_xlat2 = hlslcc_mtx4x4unity_StereoMatrixVP[(u_xlati1 + 2)] * u_xlat0.zzzz + u_xlat2;
  108. gl_Position = hlslcc_mtx4x4unity_StereoMatrixVP[(u_xlati1 + 3)] * u_xlat0.wwww + u_xlat2;
  109. }
  110. #endif
  111. #ifdef FRAGMENT
  112. // A port of GammaToLinearSpace from UnityCG.cginc
  113. vec3 GammaToLinearSpace (vec3 sRGB) {
  114. return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
  115. }
  116. uniform samplerExternalOES _MainTex;
  117. uniform vec4 _VideoCutoutRect;
  118. uniform vec4 _CropRect;
  119. varying vec2 uv;
  120. varying vec4 vertexColor;
  121. void main() {
  122. vec4 col = texture2D(_MainTex, uv);
  123. float cutoutWidth = _VideoCutoutRect.z;
  124. float cutoutHeight = _VideoCutoutRect.w;
  125. #ifdef FLIP_X
  126. float nonflippedX = 1.0 - uv.x;
  127. #else
  128. float nonflippedX = uv.x;
  129. #endif
  130. #ifdef FLIP_Y
  131. float nonflippedY = uv.y;
  132. #else
  133. float nonflippedY = 1.0 - uv.y;
  134. #endif
  135. // Make the pixels transparent if they fall within the video rect cutout and the they're black.
  136. // Keeping non-black pixels allows the video controls to still show up on top of the video.
  137. bool pointIsInCutout = cutoutWidth != 0.0 &&
  138. cutoutHeight != 0.0 &&
  139. nonflippedX >= _VideoCutoutRect.x &&
  140. nonflippedX <= _VideoCutoutRect.x + cutoutWidth &&
  141. nonflippedY >= _VideoCutoutRect.y &&
  142. nonflippedY <= _VideoCutoutRect.y + cutoutHeight;
  143. if (pointIsInCutout) {
  144. // Use a threshold of 0.15 to consider a pixel as black.
  145. bool pixelIsBlack = all(lessThan(col.xyz, vec3(0.15, 0.15, 0.15)));
  146. if (pixelIsBlack) {
  147. col = vec4(0.0, 0.0, 0.0, 0.0);
  148. }
  149. }
  150. float cropWidth = _CropRect.z;
  151. float cropHeight = _CropRect.w;
  152. bool pointIsOutsideOfCrop = cropWidth != 0.0 &&
  153. cropHeight != 0.0 &&
  154. (nonflippedX < _CropRect.x || nonflippedX > _CropRect.x + cropWidth || nonflippedY < _CropRect.y || nonflippedY > _CropRect.y + cropHeight);
  155. if (pointIsOutsideOfCrop) {
  156. col = vec4(0.0, 0.0, 0.0, 0.0);
  157. }
  158. // Place color correction last so it doesn't effect cutout rect functionality.
  159. #ifndef UNITY_COLORSPACE_GAMMA
  160. col = vec4(GammaToLinearSpace(col.xyz), col.w);
  161. #endif
  162. // Multiply the alpha by the vertex color's alpha to support CanvasGroup.alpha.
  163. gl_FragColor = vec4(col.xyz, col.w * vertexColor.w);
  164. }
  165. #endif
  166. ENDGLSL
  167. }
  168. }
  169. Fallback "Unlit/Texture"
  170. }