145 lines
6.5 KiB
C#
Raw Permalink Normal View History

2025-06-07 17:43:34 +08:00
using UnityEngine;
//设置在编辑模式下也执行该脚本
//[ExecuteInEditMode]
//添加选项到菜单中
[AddComponentMenu("RapidBlurEffect")]
public class RapidBlurEffectUtlis : MonoBehaviour
{
static class Uniforms
{
internal static readonly int _DownSampleValue = Shader.PropertyToID("_DownSampleValue");
}
//-------------------变量声明部分-------------------
#region Variables
//指定Shader名称
private string ShaderName = "Learning Unity Shader/Lecture 15/RapidBlurEffect";
public Shader CurShader;
//着色器和材质实例
private Material CurMaterial;
//降采样次数
[Range(0, 6), Tooltip("[降采样次数],,,")]
public int DownSampleNum = 2;
//模糊扩散度
[Range(0.0f, 20.0f), Tooltip("[模糊扩散度]")]
public float BlurSpreadSize = 2.0f;
//迭代次数
[Range(0, 8), Tooltip("[迭代次数],")]
public int BlurIterations = 2;
#endregion
public void SetShader(Shader s)
{
CurShader = s;
}
Material material
{
get
{
if (CurMaterial == null && CurShader != null)
{
CurMaterial = new Material(CurShader);
CurMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return CurMaterial;
}
}
#region Functions
//-----------------------------------------【Start()函数】---------------------------------------------
// 说明此函数仅在Update函数第一次被调用前被调用
//--------------------------------------------------------------------------------------------------------
void Start()
{
//判断当前设备是否支持屏幕特效
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
}
//-------------------------------------【OnRenderImage()函数】------------------------------------
// 说明:此函数在当完成所有渲染图片后被调用,用来渲染图片后期效果
//--------------------------------------------------------------------------------------------------------
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
//着色器实例不为空,就进行参数设置
if (material != null)
{
//【0】参数准备
//根据向下采样的次数确定宽度系数。用于控制降采样后相邻像素的间隔
float widthMod = 1.0f / (1.0f * (1 << DownSampleNum));
//Shader的降采样参数赋值
//material.SetFloat("_DownSampleValue", BlurSpreadSize * widthMod);
material.SetFloat(Uniforms._DownSampleValue, BlurSpreadSize * widthMod);
//设置渲染模式:双线性
sourceTexture.filterMode = FilterMode.Bilinear;
//通过右移,准备长、宽参数值
int renderWidth = sourceTexture.width >> DownSampleNum;
int renderHeight = sourceTexture.height >> DownSampleNum;
// 【1】处理Shader的通道0用于降采样 ||Pass 0,for down sample
//准备一个缓存renderBuffer用于准备存放最终数据
RenderTexture renderBuffer = RenderTexture.GetTemporary(renderWidth, renderHeight, 0, sourceTexture.format);
//设置渲染模式:双线性
renderBuffer.filterMode = FilterMode.Bilinear;
//拷贝sourceTexture中的渲染数据到renderBuffer,并仅绘制指定的pass0的纹理数据
Graphics.Blit(sourceTexture, renderBuffer, material, 0);
//【2】根据BlurIterations迭代次数来进行指定次数的迭代操作
for (int i = 0; i < BlurIterations; i++)
{
//【2.1】Shader参数赋值
//迭代偏移量参数
float iterationOffs = (i * 1.0f);
//Shader的降采样参数赋值
//material.SetFloat("_DownSampleValue", BlurSpreadSize * widthMod + iterationOffs);
material.SetFloat(Uniforms._DownSampleValue, BlurSpreadSize * widthMod + iterationOffs);
// 【2.2】处理Shader的通道1垂直方向模糊处理 || Pass1,for vertical blur
// 定义一个临时渲染的缓存tempBuffer
RenderTexture tempBuffer = RenderTexture.GetTemporary(renderWidth, renderHeight, 0, sourceTexture.format);
// 拷贝renderBuffer中的渲染数据到tempBuffer,并仅绘制指定的pass1的纹理数据
Graphics.Blit(renderBuffer, tempBuffer, material, 1);
// 清空renderBuffer
RenderTexture.ReleaseTemporary(renderBuffer);
// 将tempBuffer赋给renderBuffer此时renderBuffer里面pass0和pass1的数据已经准备好
renderBuffer = tempBuffer;
// 【2.3】处理Shader的通道2竖直方向模糊处理 || Pass2,for horizontal blur
// 获取临时渲染纹理
tempBuffer = RenderTexture.GetTemporary(renderWidth, renderHeight, 0, sourceTexture.format);
// 拷贝renderBuffer中的渲染数据到tempBuffer,并仅绘制指定的pass2的纹理数据
Graphics.Blit(renderBuffer, tempBuffer, material, 2);
//【2.4】得到pass0、pass1和pass2的数据都已经准备好的renderBuffer
// 再次清空renderBuffer
RenderTexture.ReleaseTemporary(renderBuffer);
// 再次将tempBuffer赋给renderBuffer此时renderBuffer里面pass0、pass1和pass2的数据都已经准备好
renderBuffer = tempBuffer;
}
//拷贝最终的renderBuffer到目标纹理并绘制所有通道的纹理到屏幕
Graphics.Blit(renderBuffer, destTexture);
//清空renderBuffer
RenderTexture.ReleaseTemporary(renderBuffer);
}
//着色器实例为空,直接拷贝屏幕上的效果。此情况下是没有实现屏幕特效的
else
{
//直接拷贝源纹理到目标渲染纹理
Graphics.Blit(sourceTexture, destTexture);
}
}
#endregion
}