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;
|
|
}
|
|
}
|
|
|
|
}
|