ZEDPostProcessingTools.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. //======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
  2. using UnityEngine;
  3. using UnityEngine.Rendering;
  4. /// <summary>
  5. /// Helper functions for the post processing effects applied to the final mixed reality image.
  6. /// Used by ZEDRenderingPlane when Post-Processing is enabled, and always used by GreenScreenManager.
  7. /// </summary>
  8. public class ZEDPostProcessingTools
  9. {
  10. /// <summary>
  11. /// Cached property ID for _horizontal. Use horizontalPropertyID property instead.
  12. /// </summary>
  13. private static int? _horizpropID;
  14. /// <summary>
  15. /// Cached shader ID for "_horizontal" property, to optimize shader assignment.
  16. /// We do this since this is a property we may set every frame.
  17. /// </summary>
  18. private static int horizontalPropertyID
  19. {
  20. get
  21. {
  22. if (_horizpropID == null)
  23. {
  24. _horizpropID = Shader.PropertyToID("horizontal");
  25. }
  26. return (int)_horizpropID;
  27. }
  28. }
  29. /// <summary>
  30. /// Returns the gaussian value for f(x) = (1/2*3.14*s)*e(-x*x/(2*s)).
  31. /// </summary>
  32. /// <param name="x"></param>
  33. /// <param name="sigma"></param>
  34. /// <returns></returns>
  35. public static float Gaussian(float x, float sigma)
  36. {
  37. return (1.0f / (2.0f * Mathf.PI * sigma)) * Mathf.Exp(-((x * x) / (2.0f * sigma)));
  38. }
  39. /// <summary>
  40. /// Computes weights to be sent to the blur shader.
  41. /// </summary>
  42. /// <param name="sigma"></param>
  43. /// <param name="weights_"></param>
  44. /// <param name="offsets_"></param>
  45. public static void ComputeWeights(float sigma, out float[] weights_, out float[] offsets_)
  46. {
  47. float[] weights = new float[5];
  48. float[] offsets = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f };
  49. weights_ = new float[5];
  50. offsets_ = new float[5] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f };
  51. // Calculate the weights
  52. weights[0] = Gaussian(0, sigma);
  53. if (sigma != 0)
  54. {
  55. float sum = weights[0];
  56. for (int i = 1; i < 5; ++i)
  57. {
  58. weights[i] = Gaussian(offsets[i], sigma);
  59. sum += 2.0f * weights[i];
  60. }
  61. for (int i = 0; i < 5; ++i)
  62. {
  63. weights[i] /= sum;
  64. }
  65. //Fix for just 3 fetches
  66. weights_[0] = weights[0];
  67. weights_[1] = weights[1] + weights[2];
  68. weights_[2] = weights[3] + weights[4];
  69. offsets_[0] = 0.0f;
  70. offsets_[1] = ((weights[1] * offsets[1]) + (weights[2] * offsets[2])) / weights_[1];
  71. offsets_[2] = ((weights[3] * offsets[3]) + (weights[4] * offsets[4])) / weights_[2];
  72. }
  73. }
  74. /// <summary>
  75. /// Blurs a render texture.
  76. /// </summary>
  77. /// <param name="source">Source RenderTexture.</param>
  78. /// <param name="dest">RenderTexture that the blurred version will be rendered into.</param>
  79. /// <param name="mat">Material used to blur.</param>
  80. /// <param name="pass">The pass used by the material.</param>
  81. /// <param name="numberIterations">More iterations means a more prominent blur.</param>
  82. /// <param name="downscale">The downscale of the source, which increases blur and decreases computation time.</param>
  83. public static void Blur(RenderTexture source, RenderTexture dest, Material mat, int pass, int numberIterations = -1, int downscale = 2)
  84. {
  85. if (numberIterations == -1 || numberIterations == 0)
  86. {
  87. Graphics.Blit(source, dest, mat, pass);
  88. return;
  89. }
  90. RenderTexture buffer = RenderTexture.GetTemporary(source.width / downscale, source.height / downscale, source.depth, source.format, RenderTextureReadWrite.Default);
  91. if (mat == null)
  92. {
  93. Graphics.Blit(source, buffer);
  94. Graphics.Blit(buffer, dest);
  95. }
  96. else
  97. {
  98. bool oddEven = false;
  99. //Create two buffers to make a multi-pass blur.
  100. RenderTexture buffer2 = RenderTexture.GetTemporary(source.width / downscale, source.height / downscale, source.depth, source.format, RenderTextureReadWrite.Default);
  101. Graphics.Blit(source, buffer);
  102. //To each pass, alternate the buffer, and set the blur direction.
  103. for (int i = 0; i < numberIterations * 2; i++)
  104. {
  105. //mat.SetInt("horizontal", System.Convert.ToInt32(oddEven));
  106. mat.SetInt(horizontalPropertyID, System.Convert.ToInt32(oddEven));
  107. if (i < numberIterations * 2 - 1)
  108. {
  109. Graphics.Blit(oddEven ? buffer2 : buffer, !oddEven ? buffer2 : buffer, mat, pass);
  110. oddEven = !oddEven;
  111. }
  112. else
  113. {
  114. //mat.SetInt("horizontal", System.Convert.ToInt32(oddEven));
  115. mat.SetInt(horizontalPropertyID, System.Convert.ToInt32(oddEven));
  116. //Copy the buffer to the final texture.
  117. if (oddEven)
  118. {
  119. Graphics.Blit(buffer2, dest, mat, pass);
  120. }
  121. else
  122. {
  123. Graphics.Blit(buffer, dest, mat, pass);
  124. }
  125. }
  126. }
  127. //Destroy all the temporary buffers.
  128. RenderTexture.ReleaseTemporary(buffer2);
  129. }
  130. RenderTexture.ReleaseTemporary(buffer);
  131. }
  132. /// <summary>
  133. /// Holds IDs of shader properties. Used because setting a property by ID is faster than
  134. /// setting it by a property name.
  135. /// </summary>
  136. static class Uniforms
  137. {
  138. internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
  139. internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
  140. internal static readonly int _TempRT2 = Shader.PropertyToID("_TempRT2");
  141. internal static readonly int _TempRT3 = Shader.PropertyToID("_TempRT3");
  142. }
  143. /// <summary>
  144. /// Blurs a render texture.
  145. /// </summary>
  146. /// <param name="cb">CommandBuffer from where the rendertexture is taken.</param>
  147. /// <param name="dest">RenderTexture to be blurred.</param>
  148. /// <param name="mat">Material used to blur</param>
  149. /// <param name="pass">The pass used by the material</param>
  150. /// <param name="numberIterations">More iterations means a more prominent blur</param>
  151. /// <param name="downscale">The downscale of the source, which increases blur and decreases computation time.</param>
  152. public static void Blur(CommandBuffer cb, RenderTexture texture, Material mat, int pass, int numberIterations = -1, int downscale = 2)
  153. {
  154. if (numberIterations == -1 || numberIterations == 0)
  155. {
  156. cb.GetTemporaryRT(Uniforms._TempRT, texture.width, texture.height, texture.depth);
  157. cb.Blit(texture, Uniforms._TempRT, mat, pass);
  158. cb.Blit(Uniforms._TempRT, texture);
  159. cb.ReleaseTemporaryRT(Uniforms._TempRT);
  160. return;
  161. }
  162. cb.GetTemporaryRT(Uniforms._TempRT, texture.width / downscale, texture.height / downscale, texture.depth, FilterMode.Bilinear, texture.format, RenderTextureReadWrite.Default);
  163. cb.GetTemporaryRT(Uniforms._TempRT2, texture.width / downscale, texture.height / downscale, texture.depth, FilterMode.Bilinear, texture.format, RenderTextureReadWrite.Default);
  164. bool oddEven = false;
  165. //Create two buffers to make a multi-pass blur
  166. cb.Blit(texture, Uniforms._TempRT);
  167. //To each pass alternate the buffer, and set the blur direction
  168. for (int i = 0; i < numberIterations * 2; i++)
  169. {
  170. //mat.SetInt("horizontal", System.Convert.ToInt32(oddEven));
  171. mat.SetInt(horizontalPropertyID, System.Convert.ToInt32(oddEven));
  172. if (i < numberIterations * 2 - 1)
  173. {
  174. cb.Blit(oddEven ? Uniforms._TempRT2 : Uniforms._TempRT, !oddEven ? Uniforms._TempRT2 : Uniforms._TempRT, mat, pass);
  175. oddEven = !oddEven;
  176. }
  177. else
  178. {
  179. //mat.SetInt("horizontal", System.Convert.ToInt32(oddEven));
  180. mat.SetInt(horizontalPropertyID, System.Convert.ToInt32(oddEven));
  181. //Copy the buffer to the final texture
  182. if (oddEven)
  183. {
  184. cb.Blit(Uniforms._TempRT2, texture, mat, pass);
  185. }
  186. else
  187. {
  188. cb.Blit(Uniforms._TempRT, texture, mat, pass);
  189. }
  190. }
  191. }
  192. //Destroy all the temporary buffers
  193. cb.ReleaseTemporaryRT(Uniforms._TempRT);
  194. cb.ReleaseTemporaryRT(Uniforms._TempRT2);
  195. }
  196. public static void ComposeMask(CommandBuffer cb, RenderTexture mask, Material matStencilToMask, Material matComposeMask)
  197. {
  198. cb.GetTemporaryRT(Uniforms._TempRT, mask.width, mask.height, mask.depth, mask.filterMode, mask.format, RenderTextureReadWrite.Default);
  199. cb.GetTemporaryRT(Uniforms._TempRT2, -1, -1, 24);
  200. cb.Blit(mask, Uniforms._TempRT);
  201. //This is fine, set up the target and clear.
  202. cb.SetRenderTarget(Uniforms._TempRT2);
  203. cb.ClearRenderTarget(false, true, Color.black);
  204. //To keep the stencil in post process.
  205. cb.SetRenderTarget(Uniforms._TempRT2, BuiltinRenderTextureType.CurrentActive);
  206. cb.Blit(BuiltinRenderTextureType.CameraTarget, Uniforms._TempRT2, matStencilToMask);
  207. //Compose the second mask retrieved in the forward pass. The shader should set the stencil to 148.
  208. //cb.Blit(mask, Uniforms._TempRT);
  209. cb.SetGlobalTexture("_Mask", Uniforms._TempRT);
  210. // matComposeMask.set("_Mask", Uniforms._TempRT);
  211. cb.Blit(Uniforms._TempRT2, mask, matComposeMask);
  212. }
  213. }