CubemapToEquirectangular.shader 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Originally By James O'Hare, from his Gist: https://gist.github.com/Farfarer/5664694
  2. // This takes in the cubemap generated by your cubemap camera and feeds back out an equirectangular image.
  3. // Create a new material and give it this shader. Then give that material to the "cubemapToEquirectangularMateral" property of the dynamicAmbient.js script in this gist.
  4. // You could probably abstract this to C#/JS code and feed it in a pre-baked cubemap to sample and then spit out an equirectangular map if you don't have render textures.
  5. Shader "Hidden/CubemapToEquirectangular"
  6. {
  7. Properties
  8. {
  9. _MainTex ("Cubemap (RGB)", CUBE) = "" {}
  10. //
  11. _Face_Left ("_Face_Left", 2D) = "white" {}
  12. _Face_Right ("_Face_Right", 2D) = "white" {}
  13. _Face_Up ("_Face_Up", 2D) = "white" {}
  14. _Face_Down ("_Face_Down", 2D) = "white" {}
  15. _Face_Front ("_Face_Front", 2D) = "white" {}
  16. _Face_Back ("_Face_Back", 2D) = "white" {}
  17. }
  18. CGINCLUDE
  19. #include "UnityCG.cginc"
  20. struct appdata
  21. {
  22. float4 vertex : POSITION;
  23. float2 texcoord : TEXCOORD0;
  24. };
  25. struct v2f
  26. {
  27. float4 pos : SV_POSITION;
  28. float2 uv : TEXCOORD0;
  29. };
  30. #ifndef USE_BLENDING
  31. uniform samplerCUBE _MainTex;
  32. #else
  33. uniform sampler2D _Face_Left;
  34. uniform sampler2D _Face_Right;
  35. uniform sampler2D _Face_Up;
  36. uniform sampler2D _Face_Down;
  37. uniform sampler2D _Face_Front;
  38. uniform sampler2D _Face_Back;
  39. uniform float _inverseOverlap;
  40. #endif
  41. uniform float _FlipX;
  42. #define PI 3.141592653589793
  43. #define HALFPI 1.57079632679
  44. v2f vert(appdata v )
  45. {
  46. v2f o;
  47. o.pos = UnityObjectToClipPos(v.vertex);
  48. #if STEREOPACK_TOP
  49. o.pos.y = (o.pos.y / 2.0) - 0.5;
  50. #elif STEREOPACK_BOTTOM
  51. o.pos.y = (o.pos.y / 2.0) + 0.5;
  52. #elif STEREOPACK_LEFT
  53. o.pos.x = (o.pos.x / 2.0) - 0.5;
  54. #elif STEREOPACK_RIGHT
  55. o.pos.x = (o.pos.x / 2.0) + 0.5;
  56. #endif
  57. float2 uv = v.texcoord.xy;
  58. if (_FlipX > 0.5)
  59. {
  60. uv.x = 1.0 - uv.x;
  61. }
  62. #if defined(LAYOUT_EQUIRECT180)
  63. uv = uv * float2(1.0, 2.0) - float2(0.0, 1.0);
  64. #else
  65. uv = uv * 2.0 - float2(0.5, 1.0);
  66. #endif
  67. uv *= float2(PI, HALFPI);
  68. o.uv = uv;
  69. return o;
  70. }
  71. #if USE_BLENDING
  72. fixed4 texCUBE_Face(sampler2D tex, float3 normal, float inverseOverlap = 1.0f)
  73. {
  74. float2 original = (normal.xy * (inverseOverlap / normal.z));
  75. float2 weight = smoothstep(1.0f, inverseOverlap, abs(original));
  76. float2 uv = ((original + 1.0f) * 0.5f);
  77. uv.y = (1.0f - uv.y);
  78. fixed4 colour;
  79. // RJT TODO: Better blending?
  80. colour.a = /*length(weight);*/min(weight.x, weight.y);
  81. colour.rgb = (tex2D(tex, uv) * colour.a);
  82. return colour;
  83. }
  84. #endif
  85. fixed4 frag(v2f i) : COLOR
  86. {
  87. float cosy = cos(i.uv.y);
  88. float3 normal;
  89. normal.x = cos(i.uv.x) * cosy;
  90. normal.y = i.uv.y;
  91. normal.z = cos(i.uv.x - HALFPI) * cosy;
  92. #ifndef USE_BLENDING
  93. return texCUBE(_MainTex, /*normalize*/(normal));
  94. #else
  95. fixed4 colour;
  96. float3 absNormal = abs(normal);
  97. #if 0 // Individual faces, no blending
  98. if ((absNormal.y <= absNormal.x) && (absNormal.z <= absNormal.x)) // X
  99. {
  100. float3 _normal = float3((normal.z * -sign(normal.x)), normal.y, absNormal.x);
  101. if (normal.x < 0.0f) { colour = texCUBE_Face(_Face_Left, _normal); }
  102. else { colour = texCUBE_Face(_Face_Right, _normal); }
  103. }
  104. else if (absNormal.z <= absNormal.y) // Y
  105. {
  106. float3 _normal = float3(normal.x, (normal.z * -sign(normal.y)), absNormal.y);
  107. if (normal.y < 0.0f) { colour = texCUBE_Face(_Face_Down, _normal); }
  108. else { colour = texCUBE_Face(_Face_Up, _normal); }
  109. }
  110. else // Z
  111. {
  112. float3 _normal = float3((normal.x * sign(normal.z)), normal.y, absNormal.z);
  113. if (normal.z < 0.0f) { colour = texCUBE_Face(_Face_Back, _normal); }
  114. else { colour = texCUBE_Face(_Face_Front, _normal); }
  115. }
  116. #else // Individual faces, with blending
  117. colour = fixed4(0.0f, 0.0f, 0.0f, 0.0f);
  118. float3 originalAbsNormal = (absNormal * _inverseOverlap);
  119. if ((originalAbsNormal.y <= absNormal.x) && (originalAbsNormal.z <= absNormal.x)) // X
  120. {
  121. float3 _normal = float3((normal.z * -sign(normal.x)), normal.y, absNormal.x);
  122. if (normal.x < 0.0f) { colour += texCUBE_Face(_Face_Left, _normal, _inverseOverlap); }
  123. else { colour += texCUBE_Face(_Face_Right, _normal, _inverseOverlap); }
  124. }
  125. if ((originalAbsNormal.x <= absNormal.y) && (originalAbsNormal.z <= absNormal.y)) // Y
  126. {
  127. float3 _normal = float3(normal.x, (normal.z * -sign(normal.y)), absNormal.y);
  128. if (normal.y < 0.0f) { colour += texCUBE_Face(_Face_Down, _normal, _inverseOverlap); }
  129. else { colour += texCUBE_Face(_Face_Up, _normal, _inverseOverlap); }
  130. }
  131. if ((originalAbsNormal.x <= absNormal.z) && (originalAbsNormal.y <= absNormal.z)) // Z
  132. {
  133. float3 _normal = float3((normal.x * sign(normal.z)), normal.y, absNormal.z);
  134. if (normal.z < 0.0f) { colour += texCUBE_Face(_Face_Back, _normal, _inverseOverlap); }
  135. else { colour += texCUBE_Face(_Face_Front, _normal, _inverseOverlap); }
  136. }
  137. colour.rgb /= colour.a;
  138. #endif
  139. colour.a = 1.0;
  140. return colour;
  141. #endif // #ifndef USE_BLENDING #else
  142. }
  143. ENDCG
  144. Subshader
  145. {
  146. ZTest Always
  147. Cull Off
  148. ZWrite Off
  149. Fog{ Mode off }
  150. Pass
  151. {
  152. CGPROGRAM
  153. #pragma shader_feature USE_BLENDING
  154. #pragma multi_compile __ STEREOPACK_TOP STEREOPACK_BOTTOM STEREOPACK_LEFT STEREOPACK_RIGHT
  155. #pragma multi_compile LAYOUT_EQUIRECT360 LAYOUT_EQUIRECT180
  156. #pragma vertex vert
  157. #pragma fragment frag
  158. ENDCG
  159. }
  160. }
  161. Fallback Off
  162. }