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

125 lines
5.1 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RendererUtils;
using UnityEngine.Rendering.Universal;
namespace AOT.PostProcess.BlackArea
{
public class BlackAreaRPF : ScriptableRendererFeature
{
[System.Serializable]
public class Settings
{
//渲染发生的阶段,具体信息可以在枚举类RenderPassEvent中查看
public RenderPassEvent renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
public LayerMask layerMask;
}
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;
}
public override void OnCameraSetup(CommandBuffer cmd,
ref RenderingData renderingData)
{
base.OnCameraSetup(cmd, ref renderingData);
// 只对主相机Camera.main生效
if (BlackAreaManager.instance == null) return;
if (renderingData.cameraData.camera != BlackAreaManager.instance.targetCamera) return;
if (BlackAreaManager.instance.blitMat == null) return;
if (!BlackAreaManager.instance.enableBlackArea) return;
// 创建一个RenderTexture
_cachedTarget = RenderTexture.GetTemporary(renderingData.cameraData.camera.pixelWidth,
renderingData.cameraData.camera.pixelHeight, 32);
if (_blitMaterial == null)
{
_blitMaterial = new Material(BlackAreaManager.instance.blitMat);
var shader = _blitMaterial.shader;
if (shader == null || !shader.isSupported)
{
Debug.LogError("Shader not supported on platform");
return;
}
}
}
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 (BlackAreaManager.instance == null) return;
if (renderingData.cameraData.camera != BlackAreaManager.instance.targetCamera) return;
if (_blitMaterial == null) 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);
var cacheRt = RenderTexture.GetTemporary(renderingData.cameraData.camera.pixelWidth,
renderingData.cameraData.camera.pixelHeight, 32);
cmd.Blit(cameraRt, cacheRt, _blitMaterial, 0);
cmd.Blit(cacheRt, cameraRt);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
RenderTexture.ReleaseTemporary(cacheRt);
}
}
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);
}
}
}