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

161 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
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;
[Tooltip("模糊混合进度")]
[Range(0f, 1f)]
public float blurBlendProgress = 0.5f;
[Tooltip("叠加颜色")]
public Color overlayColor;
}
public class BlurRenderPass : ScriptableRenderPass
{
private BlurData _data;
private RenderTexture _rt0;
private RenderTexture _rt1;
private RenderTargetIdentifier _buffer0Id;
private RenderTargetIdentifier _buffer1Id;
private int _blurSizeX = Shader.PropertyToID("_BlurSizeX");
private int _blurSizeY = Shader.PropertyToID("_BlurSizeY");
private int _overlayColor = Shader.PropertyToID("_OverlayColor");
private int _blurTex = Shader.PropertyToID("_BlurTex");
private int _blurBlendProgress = Shader.PropertyToID("_BlurBlendProgress");
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);
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);
}
public override void FrameCleanup(CommandBuffer cmd)
{
RenderTexture.ReleaseTemporary(_rt0);
RenderTexture.ReleaseTemporary(_rt1);
// cmd.ReleaseTemporaryRT(_buffer0Id);
// cmd.ReleaseTemporaryRT(_buffer1Id);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
//TODO: 临时处理
#if UNITY_EDITOR
var currentSceneName = SceneManager.GetActiveScene().name;
if (currentSceneName.StartsWith("story")) return;
#endif
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看到
var cameraRt = renderingData.cameraData.renderer.cameraColorTargetHandle.nameID; //获取摄像机主纹理
// 模糊
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);
// var blurTex =
mat.SetTexture(_blurTex, _rt0);
mat.SetFloat(_blurBlendProgress, _data.blurBlendProgress);
cmd.Blit(cameraRt, cameraRt, mat);
// cmd.Blit(_buffer1Id, cameraRt); //将最终结果渲染到摄像机上
//执行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
}
}