NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/PostProcess/BlackArea/BlackAreaRPF.cs

107 lines
4.2 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RendererUtils;
using UnityEngine.Rendering.Universal;
namespace Gameplay.PostProcess.BlackArea
{
public class BlackAreaRPF : ScriptableRendererFeature
{
[System.Serializable]
public class Settings
{
//渲染发生的阶段,具体信息可以在枚举类RenderPassEvent中查看
public RenderPassEvent renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
public LayerMask layerMask;
public Material blitMaterial;
}
class CustomRenderPass : ScriptableRenderPass
{
private Settings _settings;
private RenderTexture _cachedTarget;
private readonly ShaderTagId _shaderTagId = new ShaderTagId("LightArea");
private Material _blitMaterial;
public CustomRenderPass(Settings settings)
{
_settings = settings;
_blitMaterial = Instantiate(settings.blitMaterial);
}
public override void OnCameraSetup(CommandBuffer cmd,
ref RenderingData renderingData)
{
base.OnCameraSetup(cmd, ref renderingData);
// 只对主相机Camera.main生效
if (renderingData.cameraData.camera != Camera.main) return;
if (!BlackAreaManager.instance.enableBlackArea) return;
// 创建一个RenderTexture
_cachedTarget = RenderTexture.GetTemporary(renderingData.cameraData.camera.pixelWidth,
renderingData.cameraData.camera.pixelHeight, 32);
}
public override void OnCameraCleanup(CommandBuffer cmd)
{
base.OnCameraCleanup(cmd);
if (_cachedTarget != null)
{
RenderTexture.ReleaseTemporary(_cachedTarget);
_cachedTarget = null;
}
}
public override void Execute(ScriptableRenderContext context,
ref RenderingData renderingData)
{
// 只对主相机Camera.main生效
if (renderingData.cameraData.camera != Camera.main) return;
if (!BlackAreaManager.instance.enableBlackArea) return;
var cmd = CommandBufferPool.Get("BlackArea-DrawMask");
cmd.Clear();
cmd.SetRenderTarget(_cachedTarget);
// 刷一个黑色背景
cmd.ClearRenderTarget(true, true, Color.black);
// 渲染光亮区域
var renderListDesc = new RendererListDesc(_shaderTagId,
renderingData.cullResults,
renderingData.cameraData.camera);
renderListDesc.renderQueueRange = RenderQueueRange.all;
renderListDesc.layerMask = _settings.layerMask;
var renderList = context.CreateRendererList(renderListDesc);
cmd.DrawRendererList(renderList);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
// 把这张图渲染到屏幕上
cmd = CommandBufferPool.Get("BlackArea-DrawMaskToScreen");
var cameraRt = renderingData.cameraData.renderer.cameraColorTargetHandle.nameID;
_blitMaterial.SetTexture(MaskTex, _cachedTarget);
cmd.Blit(cameraRt, cameraRt, _blitMaterial);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}
public Settings settings;
private CustomRenderPass _scriptablePass;
private static readonly int MainTex = Shader.PropertyToID("_MainTex");
private static readonly int MaskTex = Shader.PropertyToID("_MaskTex");
public override void Create()
{
_scriptablePass = new CustomRenderPass(settings);
_scriptablePass.renderPassEvent = settings.renderPassEvent;
}
public override void AddRenderPasses(ScriptableRenderer renderer,
ref RenderingData renderingData)
{
renderer.EnqueuePass(_scriptablePass);
}
}
}