NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/PostProcess/FullBlur/FullBlurRPF.cs

161 lines
6.1 KiB
C#
Raw Normal View History

2023-11-03 13:41:15 +08:00
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
2023-11-06 15:29:34 +08:00
2023-11-03 13:41:15 +08:00
public class FullBlurRPF : ScriptableRendererFeature
{
[Serializable] //序列化 会在ForwardRenderer下创建Blur时看到m_Data就是它
public class BlurData
{
// 模糊材质
public Material blurMat;
// 叠加材质
public Material overlayMat;
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
[Tooltip("渲染次数,次数越多越模糊,但是性能消耗也越大")]
[Range(0, 4)]
public int iterations = 3;
[Tooltip("采样间距X,值越大越模糊")]
[Range(0, 2f)]
public float blurSizeX = 0.5f;
[Tooltip("采样间距Y,值越大越模糊")]
[Range(0, 2f)]
public float blurSizeY = 0.5f;
[Tooltip("降采样,值越小越模糊,性能越好")]
[Range(0.1f, 1f)]
public float downScale = 0.5f;
2023-11-03 14:45:49 +08:00
[Tooltip("模糊混合进度")]
[Range(0f, 1f)]
public float blurBlendProgress = 0.5f;
2023-11-03 13:41:15 +08:00
[Tooltip("叠加颜色")]
public Color overlayColor;
}
public class BlurRenderPass : ScriptableRenderPass
{
private BlurData _data;
2023-11-03 14:45:49 +08:00
private RenderTexture _rt0;
private RenderTexture _rt1;
private RenderTargetIdentifier _buffer0Id;
private RenderTargetIdentifier _buffer1Id;
2023-11-03 13:41:15 +08:00
private int _blurSizeX = Shader.PropertyToID("_BlurSizeX");
private int _blurSizeY = Shader.PropertyToID("_BlurSizeY");
private int _overlayColor = Shader.PropertyToID("_OverlayColor");
2023-11-03 14:45:49 +08:00
private int _blurTex = Shader.PropertyToID("_BlurTex");
private int _blurBlendProgress = Shader.PropertyToID("_BlurBlendProgress");
2023-11-03 13:41:15 +08:00
public BlurRenderPass(BlurData data)
{
_data = data;
}
public void Setup()
{
_buffer0Id = Shader.PropertyToID("_BlurBuffer0");
_buffer1Id = Shader.PropertyToID("_BlurBuffer1");
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
var width = Mathf.FloorToInt(cameraTextureDescriptor.width * _data.downScale);
var height = Mathf.FloorToInt(cameraTextureDescriptor.height * _data.downScale);
2023-11-03 14:45:49 +08:00
var rt0 = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);
rt0.filterMode = FilterMode.Bilinear;
rt0.wrapMode = TextureWrapMode.Clamp;
_buffer0Id = rt0;
_rt0 = rt0;
var rt1 = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);
rt1.filterMode = FilterMode.Bilinear;
rt1.wrapMode = TextureWrapMode.Clamp;
_buffer1Id = rt1;
_rt1 = rt1;
// cmd.GetTemporaryRT(_buffer0Id, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
// cmd.GetTemporaryRT(_buffer1Id, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
2023-11-03 13:41:15 +08:00
}
public override void FrameCleanup(CommandBuffer cmd)
{
2023-11-03 14:45:49 +08:00
RenderTexture.ReleaseTemporary(_rt0);
RenderTexture.ReleaseTemporary(_rt1);
// cmd.ReleaseTemporaryRT(_buffer0Id);
// cmd.ReleaseTemporaryRT(_buffer1Id);
2023-11-03 13:41:15 +08:00
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
//TODO: 临时处理
#if UNITY_EDITOR
var currentSceneName = SceneManager.GetActiveScene().name;
if (currentSceneName.StartsWith("story")) return;
#endif
2023-11-03 13:41:15 +08:00
if (renderingData.cameraData.camera != Camera.main) return; //只对主摄像机进行处理
var mat = _data.blurMat;
if (mat == null) return;
//renderingData.cameraData.camera 可获取摄像机判定哪个摄像机才进行处理渲染(每个摄像机都会进一遍pass 如果摄像机有多个且都有这个Blur(ScriptableRendererFeature资源)
CommandBuffer cmd = CommandBufferPool.Get("FullBlur"); //从池获取一个cmd 命名为MyBlurCmd 能在FrameDebugger看到
2023-11-03 15:58:58 +08:00
var cameraRt = renderingData.cameraData.renderer.cameraColorTargetHandle.nameID; //获取摄像机主纹理
2023-11-03 13:41:15 +08:00
// 模糊
cmd.Blit(cameraRt, _buffer0Id);//将摄像机图渲染至buffer0
//开始iterations次渲染,每次都会进行2次Pass操作横向、纵向谁先谁后都无所谓
for (int i = 0; i < _data.iterations; i++)
{
//指定采样间距,逐级递增的形式
mat.SetFloat(_blurSizeX, 1.0f + i * _data.blurSizeX);
mat.SetFloat(_blurSizeY, 1.0f + i * _data.blurSizeY);
cmd.Blit(_buffer0Id, _buffer1Id, mat);
(_buffer0Id, _buffer1Id) = (_buffer1Id, _buffer0Id);
}
// 叠色
mat = _data.overlayMat;
if (mat == null) return;
mat.SetColor(_overlayColor, _data.overlayColor);
2023-11-03 14:45:49 +08:00
// var blurTex =
mat.SetTexture(_blurTex, _rt0);
mat.SetFloat(_blurBlendProgress, _data.blurBlendProgress);
cmd.Blit(cameraRt, cameraRt, mat);
2023-11-03 13:41:15 +08:00
2023-11-03 14:45:49 +08:00
// cmd.Blit(_buffer1Id, cameraRt); //将最终结果渲染到摄像机上
2023-11-03 13:41:15 +08:00
//执行cmd
context.ExecuteCommandBuffer(cmd);
//清空回收cmd
cmd.Clear();
CommandBufferPool.Release(cmd);
}
}
public BlurData data = new BlurData();
private BlurRenderPass _blurPass;
public override void Create()
{
_blurPass = new BlurRenderPass(data); //创建一个pass
_blurPass.renderPassEvent = data.renderPassEvent;
}
public override void AddRenderPasses(ScriptableRenderer renderer,
ref RenderingData renderingData)
{
_blurPass.Setup();
renderer.EnqueuePass(_blurPass); //入队渲染pass
}
}