将后处理参数添加到 Volume 中,如果后处理不需要通过Volume 动态控制,可以不用,
参考代码以及注释:
其中MaterialParameter 是Volume 没有自带的材质类型,需要手动封装不存在的参数类型
using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class MyVolume : VolumeComponent, IPostProcessComponent
{
//需要封装参数
public MaterialParameter Material = new MaterialParameter(null, false);
//需要封装参数
public ColorParameter BlendColor = new ColorParameter(Color.white);
public bool IsActive()
{
if (Material.overrideState == false)//如果材质没有被勾选,则不激活
{
return false;
}
return true;
}
public bool IsTileCompatible()
{
return true;
}
}
[Serializable]
public sealed class MaterialParameter : VolumeParameter<Material>
{
//没有自带的Material 封装,手动封装参数
public MaterialParameter(Material value, bool overrideState = false)
: base(value, overrideState)
{
}
}
MaterialParameter 修改,不需要从Render Feature 面板获取参数,改为从VolumeManager 获取
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class MyVolumeFeature : ScriptableRendererFeature
{
public Material Material; //UniversalRenderPipelineAsset_Renderer 面板,设置材质
public Color BlendColor;
private MyVolumeFeaturePass myPass;
public override void Create()
{
myPass = new MyVolumeFeaturePass();
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(myPass);
myPass.SetValue(renderer.cameraColorTarget, Material,BlendColor); //传递给Pass 处理
}
}
public class MyVolumeFeaturePass : ScriptableRenderPass
{
private Material Material;
private RenderTargetIdentifier source;
private Color color;//接受面板颜色
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
MyVolume Volume = VolumeManager.instance.stack.GetComponent<MyVolume>();
if (!Volume.IsActive())//没激活Volume 则不后处理
{
return;
}
//执行后处理
//设置要混合的材质参数,从Volume 获取
Material = Volume.Material.value;
Material.SetColor("_Color",Volume.BlendColor.value);
CommandBuffer cmd = CommandBufferPool.Get();
//source //源图像
var dec = renderingData.cameraData.cameraTargetDescriptor; //目标图像
RenderTargetHandle tempTargetHandle=new RenderTargetHandle();
cmd.GetTemporaryRT(tempTargetHandle.id, dec);
cmd.Blit(source, tempTargetHandle.Identifier(), Material);
//核心命令CommandBuffer
cmd.Blit(tempTargetHandle.Identifier(), source); //相当于 Graphics.Blit
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public void SetValue(RenderTargetIdentifier source, Material material, Color blendColor)
{
Material = material; //接受面板材质
this.source = source;
color = blendColor;
}
}
最终效果:与自带的Volume 叠加
UI 没有被MyVolume 后处理,因为没有设置后处理时机
myPass.renderPassEvent = RenderPassEvent.AfterRenderingTransparents;