using System.Collections; using System.Collections.Generic; using LuaInterface; using UnityEngine; [ExecuteInEditMode] [RequireComponent(typeof(Camera))] public class ScreenEffect : MonoBehaviour { private RenderTexture final_renderTexture; // 最终渲染出来的画面RT缓存 #region 高速模糊相关参数 private const int BLUR_PASS_HOR = 0; // 水平模糊pass private const int BLUR_PASS_VER = 1; // 垂直模糊pass public Material blurMaterial; // 高速模糊材质 [HideInInspector] public bool render_blur_effect = false; // 高斯模糊关键参数,设置为true时会开始渲染高斯模糊纹理 public bool get_screen_shot = false; // 与上面的功能区分,只截图,并不会改变原先的渲染 // 高斯模糊缓存纹理(不要在渲染时动态创建,会消耗很多内存,这里先生成引用) private RenderTexture buffer_temp; // 临时材质 public float blurSpread = 0.4f; // 模糊散值 public float blur_amount = 1f; // 模糊插值,0:初始效果,1:完全模糊效果 private int recurveNum = 1; // 当前迭代的渲染次数 public int recurveMaxNum = 1; // 最大迭代渲染次数 public int downSample = 4; // 降低采样率比率(降低采样率可以提高性能,但肯定会让效果变差) LuaFunction screenshot_callback; // 模糊截图回调 #endregion #region 双面模糊相关参数 const int DOWN_SAMPLE_PASS = 0; // 降采样pass const int UP_SAMPLE_PASS = 1; // 升采样pass public bool use_dual_blur = false; // 使用双面模糊 public Material dual_blur_mat; // 双面模糊材质球 RenderTextureFormat format; #endregion private bool isSupported; // 设备支持变量 private void Start() { isSupported = CheckSupport(); this.enabled = false; } // 检测当前平台是否支持屏幕特效 private bool CheckSupport() { if (SystemInfo.supportsImageEffects == false) { Debug.LogWarning("当前平台不支持!"); return false; } return true; } // 获取设备支持 public bool GetSupported() { return isSupported; } void OnRenderImage(RenderTexture src, RenderTexture dest) { format = src.format; //1.迭代渲染画面,加强模糊效果 //当设置为了true时,获取当前的画面内容 if (blurMaterial != null && dual_blur_mat != null && (render_blur_effect || get_screen_shot)) { // 使用双面模糊算法 if(use_dual_blur){ int width = src.width; int height = src.height; recurveNum = 1; // 初始化迭代 while(recurveNum <= recurveMaxNum) { width /= downSample; height /= downSample; dual_blur_mat.SetFloat("_Offset", (1.0f + recurveNum * blurSpread) * blur_amount); // 设置模糊扩散uv偏移 buffer_temp = RenderTexture.GetTemporary(width, height, 0, format); // 降采样渲染 if(recurveNum == 1) { Graphics.Blit(src, buffer_temp, dual_blur_mat, DOWN_SAMPLE_PASS); } else{ Graphics.Blit(final_renderTexture, buffer_temp, dual_blur_mat, DOWN_SAMPLE_PASS); } // 升采样渲染 width *= downSample; height *= downSample; ReleaseTargetRenderTexture(final_renderTexture); final_renderTexture = RenderTexture.GetTemporary(width, height, 0, format); Graphics.Blit(buffer_temp, final_renderTexture, dual_blur_mat, UP_SAMPLE_PASS); RenderTexture.ReleaseTemporary(buffer_temp); // 释放临时RT recurveNum ++; } }else { recurveNum = 1; //缩小要模糊的图片,减少处理压力 int width = src.width / downSample; int height = src.height / downSample; final_renderTexture = RenderTexture.GetTemporary(width, height, 0); final_renderTexture.filterMode = FilterMode.Bilinear; Graphics.Blit(src, final_renderTexture); while(recurveNum <= recurveMaxNum){ recurveNum ++; blurMaterial.SetFloat("_BlurSize", (1.0f + recurveNum * blurSpread) * blur_amount); buffer_temp = RenderTexture.GetTemporary(width, height, 0); Graphics.Blit(final_renderTexture, buffer_temp, blurMaterial, BLUR_PASS_HOR); Graphics.Blit(buffer_temp, final_renderTexture, blurMaterial, BLUR_PASS_VER); RenderTexture.ReleaseTemporary(buffer_temp); } } if(get_screen_shot && !render_blur_effect){ GetBlurScreenShot(); Graphics.Blit(src, dest); get_screen_shot = false; // 截图生成之后就停止运作 this.enabled = false; } else{ Graphics.Blit(final_renderTexture, dest); RenderTexture.ReleaseTemporary(final_renderTexture); } } else { Graphics.Blit(src, dest); } } // 设置开始处理模糊效果的截图 public void RenderBlurScreenShot(float blur_amount, int downSample, LuaFunction func) { get_screen_shot = true; this.blur_amount = blur_amount; this.downSample = downSample; screenshot_callback = func; } void GetBlurScreenShot() { RenderTexture temp_screen_shot = RenderTexture.GetTemporary(final_renderTexture.width, final_renderTexture.height, 0); Graphics.Blit(final_renderTexture, temp_screen_shot); if (screenshot_callback != null) { List list = new List(); list.Add(temp_screen_shot); object[] args = new object[] { list.ToArray() }; screenshot_callback.Call(args); screenshot_callback.Dispose(); screenshot_callback = null; } ReleaseRenderTexCache(); } // 销毁渲染纹理缓存 public void ReleaseRenderTexCache() { if (!render_blur_effect) { RenderTexture.ReleaseTemporary(final_renderTexture); } } public void ReleaseTargetRenderTexture(RenderTexture rt) { if (rt!= null) { RenderTexture.ReleaseTemporary(rt); rt = null; } } }