源战役客户端
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.
 
 
 
 
 

167 lines
6.8 KiB

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