BloomAndFlares.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. using System;
  2. using UnityEngine;
  3. namespace UnityStandardAssets.ImageEffects
  4. {
  5. public enum LensflareStyle34
  6. {
  7. Ghosting = 0,
  8. Anamorphic = 1,
  9. Combined = 2,
  10. }
  11. public enum TweakMode34
  12. {
  13. Basic = 0,
  14. Complex = 1,
  15. }
  16. public enum HDRBloomMode
  17. {
  18. Auto = 0,
  19. On = 1,
  20. Off = 2,
  21. }
  22. public enum BloomScreenBlendMode
  23. {
  24. Screen = 0,
  25. Add = 1,
  26. }
  27. [ExecuteInEditMode]
  28. [RequireComponent(typeof(Camera))]
  29. [AddComponentMenu("Image Effects/Bloom and Glow/BloomAndFlares (3.5, Deprecated)")]
  30. public class BloomAndFlares : PostEffectsBase
  31. {
  32. public TweakMode34 tweakMode = 0;
  33. public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
  34. public HDRBloomMode hdr = HDRBloomMode.Auto;
  35. private bool doHdr = false;
  36. public float sepBlurSpread = 1.5f;
  37. public float useSrcAlphaAsMask = 0.5f;
  38. public float bloomIntensity = 1.0f;
  39. public float bloomThreshold = 0.5f;
  40. public int bloomBlurIterations = 2;
  41. public bool lensflares = false;
  42. public int hollywoodFlareBlurIterations = 2;
  43. public LensflareStyle34 lensflareMode = (LensflareStyle34)1;
  44. public float hollyStretchWidth = 3.5f;
  45. public float lensflareIntensity = 1.0f;
  46. public float lensflareThreshold = 0.3f;
  47. public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
  48. public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
  49. public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
  50. public Color flareColorD = new Color(0.8f, 0.4f, 0.0f, 0.75f);
  51. public Texture2D lensFlareVignetteMask;
  52. public Shader lensFlareShader;
  53. private Material lensFlareMaterial;
  54. public Shader vignetteShader;
  55. private Material vignetteMaterial;
  56. public Shader separableBlurShader;
  57. private Material separableBlurMaterial;
  58. public Shader addBrightStuffOneOneShader;
  59. private Material addBrightStuffBlendOneOneMaterial;
  60. public Shader screenBlendShader;
  61. private Material screenBlend;
  62. public Shader hollywoodFlaresShader;
  63. private Material hollywoodFlaresMaterial;
  64. public Shader brightPassFilterShader;
  65. private Material brightPassFilterMaterial;
  66. public override bool CheckResources()
  67. {
  68. CheckSupport(false);
  69. screenBlend = CheckShaderAndCreateMaterial(screenBlendShader, screenBlend);
  70. lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader, lensFlareMaterial);
  71. vignetteMaterial = CheckShaderAndCreateMaterial(vignetteShader, vignetteMaterial);
  72. separableBlurMaterial = CheckShaderAndCreateMaterial(separableBlurShader, separableBlurMaterial);
  73. addBrightStuffBlendOneOneMaterial = CheckShaderAndCreateMaterial(addBrightStuffOneOneShader, addBrightStuffBlendOneOneMaterial);
  74. hollywoodFlaresMaterial = CheckShaderAndCreateMaterial(hollywoodFlaresShader, hollywoodFlaresMaterial);
  75. brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
  76. if (!isSupported)
  77. ReportAutoDisable();
  78. return isSupported;
  79. }
  80. void OnRenderImage(RenderTexture source, RenderTexture destination)
  81. {
  82. if (CheckResources() == false)
  83. {
  84. Graphics.Blit(source, destination);
  85. return;
  86. }
  87. // screen blend is not supported when HDR is enabled (will cap values)
  88. doHdr = false;
  89. if (hdr == HDRBloomMode.Auto)
  90. doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().allowHDR;
  91. else
  92. {
  93. doHdr = hdr == HDRBloomMode.On;
  94. }
  95. doHdr = doHdr && supportHDRTextures;
  96. BloomScreenBlendMode realBlendMode = screenBlendMode;
  97. if (doHdr)
  98. realBlendMode = BloomScreenBlendMode.Add;
  99. var rtFormat = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
  100. RenderTexture halfRezColor = RenderTexture.GetTemporary(source.width / 2, source.height / 2, 0, rtFormat);
  101. RenderTexture quarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
  102. RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
  103. RenderTexture thirdQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
  104. float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
  105. float oneOverBaseSize = 1.0f / 512.0f;
  106. // downsample
  107. Graphics.Blit(source, halfRezColor, screenBlend, 2); // <- 2 is stable downsample
  108. Graphics.Blit(halfRezColor, quarterRezColor, screenBlend, 2); // <- 2 is stable downsample
  109. RenderTexture.ReleaseTemporary(halfRezColor);
  110. // cut colors (thresholding)
  111. BrightFilter(bloomThreshold, useSrcAlphaAsMask, quarterRezColor, secondQuarterRezColor);
  112. quarterRezColor.DiscardContents();
  113. // blurring
  114. if (bloomBlurIterations < 1) bloomBlurIterations = 1;
  115. for (int iter = 0; iter < bloomBlurIterations; iter++)
  116. {
  117. float spreadForPass = (1.0f + (iter * 0.5f)) * sepBlurSpread;
  118. separableBlurMaterial.SetVector("offsets", new Vector4(0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
  119. RenderTexture src = iter == 0 ? secondQuarterRezColor : quarterRezColor;
  120. Graphics.Blit(src, thirdQuarterRezColor, separableBlurMaterial);
  121. src.DiscardContents();
  122. separableBlurMaterial.SetVector("offsets", new Vector4((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
  123. Graphics.Blit(thirdQuarterRezColor, quarterRezColor, separableBlurMaterial);
  124. thirdQuarterRezColor.DiscardContents();
  125. }
  126. // lens flares: ghosting, anamorphic or a combination
  127. if (lensflares)
  128. {
  129. if (lensflareMode == 0)
  130. {
  131. BrightFilter(lensflareThreshold, 0.0f, quarterRezColor, thirdQuarterRezColor);
  132. quarterRezColor.DiscardContents();
  133. // smooth a little, this needs to be resolution dependent
  134. /*
  135. separableBlurMaterial.SetVector ("offsets", Vector4 (0.0ff, (2.0ff) / (1.0ff * quarterRezColor.height), 0.0ff, 0.0ff));
  136. Graphics.Blit (thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
  137. separableBlurMaterial.SetVector ("offsets", Vector4 ((2.0ff) / (1.0ff * quarterRezColor.width), 0.0ff, 0.0ff, 0.0ff));
  138. Graphics.Blit (secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
  139. */
  140. // no ugly edges!
  141. Vignette(0.975f, thirdQuarterRezColor, secondQuarterRezColor);
  142. thirdQuarterRezColor.DiscardContents();
  143. BlendFlares(secondQuarterRezColor, quarterRezColor);
  144. secondQuarterRezColor.DiscardContents();
  145. }
  146. // (b) hollywood/anamorphic flares?
  147. else
  148. {
  149. // thirdQuarter has the brightcut unblurred colors
  150. // quarterRezColor is the blurred, brightcut buffer that will end up as bloom
  151. hollywoodFlaresMaterial.SetVector("_threshold", new Vector4(lensflareThreshold, 1.0f / (1.0f - lensflareThreshold), 0.0f, 0.0f));
  152. hollywoodFlaresMaterial.SetVector("tintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
  153. Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 2);
  154. thirdQuarterRezColor.DiscardContents();
  155. Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 3);
  156. secondQuarterRezColor.DiscardContents();
  157. hollywoodFlaresMaterial.SetVector("offsets", new Vector4((sepBlurSpread * 1.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
  158. hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth);
  159. Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
  160. thirdQuarterRezColor.DiscardContents();
  161. hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 2.0f);
  162. Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 1);
  163. secondQuarterRezColor.DiscardContents();
  164. hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 4.0f);
  165. Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
  166. thirdQuarterRezColor.DiscardContents();
  167. if (lensflareMode == (LensflareStyle34)1)
  168. {
  169. for (int itera = 0; itera < hollywoodFlareBlurIterations; itera++)
  170. {
  171. separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
  172. Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
  173. secondQuarterRezColor.DiscardContents();
  174. separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
  175. Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
  176. thirdQuarterRezColor.DiscardContents();
  177. }
  178. AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
  179. secondQuarterRezColor.DiscardContents();
  180. }
  181. else
  182. {
  183. // (c) combined
  184. for (int ix = 0; ix < hollywoodFlareBlurIterations; ix++)
  185. {
  186. separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
  187. Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
  188. secondQuarterRezColor.DiscardContents();
  189. separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
  190. Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
  191. thirdQuarterRezColor.DiscardContents();
  192. }
  193. Vignette(1.0f, secondQuarterRezColor, thirdQuarterRezColor);
  194. secondQuarterRezColor.DiscardContents();
  195. BlendFlares(thirdQuarterRezColor, secondQuarterRezColor);
  196. thirdQuarterRezColor.DiscardContents();
  197. AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
  198. secondQuarterRezColor.DiscardContents();
  199. }
  200. }
  201. }
  202. // screen blend bloom results to color buffer
  203. screenBlend.SetFloat("_Intensity", bloomIntensity);
  204. screenBlend.SetTexture("_ColorBuffer", source);
  205. Graphics.Blit(quarterRezColor, destination, screenBlend, (int)realBlendMode);
  206. RenderTexture.ReleaseTemporary(quarterRezColor);
  207. RenderTexture.ReleaseTemporary(secondQuarterRezColor);
  208. RenderTexture.ReleaseTemporary(thirdQuarterRezColor);
  209. }
  210. private void AddTo(float intensity_, RenderTexture from, RenderTexture to)
  211. {
  212. addBrightStuffBlendOneOneMaterial.SetFloat("_Intensity", intensity_);
  213. Graphics.Blit(from, to, addBrightStuffBlendOneOneMaterial);
  214. }
  215. private void BlendFlares(RenderTexture from, RenderTexture to)
  216. {
  217. lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
  218. lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
  219. lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
  220. lensFlareMaterial.SetVector("colorD", new Vector4(flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
  221. Graphics.Blit(from, to, lensFlareMaterial);
  222. }
  223. private void BrightFilter(float thresh, float useAlphaAsMask, RenderTexture from, RenderTexture to)
  224. {
  225. if (doHdr)
  226. brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f, 0.0f, 0.0f));
  227. else
  228. brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f / (1.0f - thresh), 0.0f, 0.0f));
  229. brightPassFilterMaterial.SetFloat("useSrcAlphaAsMask", useAlphaAsMask);
  230. Graphics.Blit(from, to, brightPassFilterMaterial);
  231. }
  232. private void Vignette(float amount, RenderTexture from, RenderTexture to)
  233. {
  234. if (lensFlareVignetteMask)
  235. {
  236. screenBlend.SetTexture("_ColorBuffer", lensFlareVignetteMask);
  237. Graphics.Blit(from, to, screenBlend, 3);
  238. }
  239. else
  240. {
  241. vignetteMaterial.SetFloat("vignetteIntensity", amount);
  242. Graphics.Blit(from, to, vignetteMaterial);
  243. }
  244. }
  245. }
  246. }