源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
6.8 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using LuaInterface;
  4. using UnityEngine;
  5. [ExecuteInEditMode]
  6. [RequireComponent(typeof(Camera))]
  7. public class ScreenEffect : MonoBehaviour {
  8. private RenderTexture final_renderTexture; // 最终渲染出来的画面RT缓存
  9. #region 高速模糊相关参数
  10. private const int BLUR_PASS_HOR = 0; // 水平模糊pass
  11. private const int BLUR_PASS_VER = 1; // 垂直模糊pass
  12. public Material blurMaterial; // 高速模糊材质
  13. [HideInInspector]
  14. public bool render_blur_effect = false; // 高斯模糊关键参数,设置为true时会开始渲染高斯模糊纹理
  15. public bool get_screen_shot = false; // 与上面的功能区分,只截图,并不会改变原先的渲染
  16. // 高斯模糊缓存纹理(不要在渲染时动态创建,会消耗很多内存,这里先生成引用)
  17. private RenderTexture buffer_temp; // 临时材质
  18. public float blurSpread = 0.4f; // 模糊散值
  19. public float blur_amount = 1f; // 模糊插值,0:初始效果,1:完全模糊效果
  20. private int recurveNum = 1; // 当前迭代的渲染次数
  21. public int recurveMaxNum = 1; // 最大迭代渲染次数
  22. public int downSample = 4; // 降低采样率比率(降低采样率可以提高性能,但肯定会让效果变差)
  23. LuaFunction screenshot_callback; // 模糊截图回调
  24. #endregion
  25. #region 双面模糊相关参数
  26. const int DOWN_SAMPLE_PASS = 0; // 降采样pass
  27. const int UP_SAMPLE_PASS = 1; // 升采样pass
  28. public bool use_dual_blur = false; // 使用双面模糊
  29. public Material dual_blur_mat; // 双面模糊材质球
  30. RenderTextureFormat format;
  31. #endregion
  32. private bool isSupported; // 设备支持变量
  33. private void Start()
  34. {
  35. isSupported = CheckSupport();
  36. this.enabled = false;
  37. }
  38. // 检测当前平台是否支持屏幕特效
  39. private bool CheckSupport()
  40. {
  41. if (SystemInfo.supportsImageEffects == false)
  42. {
  43. Debug.LogWarning("当前平台不支持!");
  44. return false;
  45. }
  46. return true;
  47. }
  48. // 获取设备支持
  49. public bool GetSupported()
  50. {
  51. return isSupported;
  52. }
  53. void OnRenderImage(RenderTexture src, RenderTexture dest)
  54. {
  55. format = src.format;
  56. //1.迭代渲染画面,加强模糊效果
  57. //当设置为了true时,获取当前的画面内容
  58. if (blurMaterial != null && dual_blur_mat != null && (render_blur_effect || get_screen_shot))
  59. {
  60. // 使用双面模糊算法
  61. if(use_dual_blur){
  62. int width = src.width;
  63. int height = src.height;
  64. recurveNum = 1; // 初始化迭代
  65. while(recurveNum <= recurveMaxNum)
  66. {
  67. width /= downSample;
  68. height /= downSample;
  69. dual_blur_mat.SetFloat("_Offset", (1.0f + recurveNum * blurSpread) * blur_amount); // 设置模糊扩散uv偏移
  70. buffer_temp = RenderTexture.GetTemporary(width, height, 0, format);
  71. // 降采样渲染
  72. if(recurveNum == 1)
  73. {
  74. Graphics.Blit(src, buffer_temp, dual_blur_mat, DOWN_SAMPLE_PASS);
  75. }
  76. else{
  77. Graphics.Blit(final_renderTexture, buffer_temp, dual_blur_mat, DOWN_SAMPLE_PASS);
  78. }
  79. // 升采样渲染
  80. width *= downSample;
  81. height *= downSample;
  82. ReleaseTargetRenderTexture(final_renderTexture);
  83. final_renderTexture = RenderTexture.GetTemporary(width, height, 0, format);
  84. Graphics.Blit(buffer_temp, final_renderTexture, dual_blur_mat, UP_SAMPLE_PASS);
  85. RenderTexture.ReleaseTemporary(buffer_temp); // 释放临时RT
  86. recurveNum ++;
  87. }
  88. }else
  89. {
  90. recurveNum = 1;
  91. //缩小要模糊的图片,减少处理压力
  92. int width = src.width / downSample;
  93. int height = src.height / downSample;
  94. final_renderTexture = RenderTexture.GetTemporary(width, height, 0);
  95. final_renderTexture.filterMode = FilterMode.Bilinear;
  96. Graphics.Blit(src, final_renderTexture);
  97. while(recurveNum <= recurveMaxNum){
  98. recurveNum ++;
  99. blurMaterial.SetFloat("_BlurSize", (1.0f + recurveNum * blurSpread) * blur_amount);
  100. buffer_temp = RenderTexture.GetTemporary(width, height, 0);
  101. Graphics.Blit(final_renderTexture, buffer_temp, blurMaterial, BLUR_PASS_HOR);
  102. Graphics.Blit(buffer_temp, final_renderTexture, blurMaterial, BLUR_PASS_VER);
  103. RenderTexture.ReleaseTemporary(buffer_temp);
  104. }
  105. }
  106. if(get_screen_shot && !render_blur_effect){
  107. GetBlurScreenShot();
  108. Graphics.Blit(src, dest);
  109. get_screen_shot = false; // 截图生成之后就停止运作
  110. this.enabled = false;
  111. }
  112. else{
  113. Graphics.Blit(final_renderTexture, dest);
  114. RenderTexture.ReleaseTemporary(final_renderTexture);
  115. }
  116. }
  117. else
  118. {
  119. Graphics.Blit(src, dest);
  120. }
  121. }
  122. // 设置开始处理模糊效果的截图
  123. public void RenderBlurScreenShot(float blur_amount, int downSample, LuaFunction func)
  124. {
  125. get_screen_shot = true;
  126. this.blur_amount = blur_amount;
  127. this.downSample = downSample;
  128. screenshot_callback = func;
  129. }
  130. void GetBlurScreenShot()
  131. {
  132. RenderTexture temp_screen_shot = RenderTexture.GetTemporary(final_renderTexture.width, final_renderTexture.height, 0);
  133. Graphics.Blit(final_renderTexture, temp_screen_shot);
  134. if (screenshot_callback != null)
  135. {
  136. List<UnityEngine.Object> list = new List<UnityEngine.Object>();
  137. list.Add(temp_screen_shot);
  138. object[] args = new object[] { list.ToArray() };
  139. screenshot_callback.Call(args);
  140. screenshot_callback.Dispose();
  141. screenshot_callback = null;
  142. }
  143. ReleaseRenderTexCache();
  144. }
  145. // 销毁渲染纹理缓存
  146. public void ReleaseRenderTexCache()
  147. {
  148. if (!render_blur_effect) {
  149. RenderTexture.ReleaseTemporary(final_renderTexture);
  150. }
  151. }
  152. public void ReleaseTargetRenderTexture(RenderTexture rt)
  153. {
  154. if (rt!= null)
  155. {
  156. RenderTexture.ReleaseTemporary(rt);
  157. rt = null;
  158. }
  159. }
  160. }