|
|
- 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<UnityEngine.Object> list = new List<UnityEngine.Object>();
- 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;
- }
- }
-
- }
|