|
抓手
本文将会具体阐述,如何扩展Unity URP的Volume。
之前写过一篇叫《Unity的URP的自定义后处理效果》的文章,传送门:
琅琅:Unity的URP的自定义后处理效果实现,但是并不完全是我想要的效果。
因为最终我是希望像Unity 的Volume一样去添加自定义的后处理效果,可以随时添加、关闭和打开。
最近参考了一些文章,终于知道怎么做了。以下是具体做法。
具体实现:
一共五个大步骤。
步骤一:
创建VolumeComponent类。
在com.unity.render-pipelines.universal@7.4.3\Runtime\Overrides源码里,有URP自带的后处理的类。
参考它们的bloom.cs,在URP的命名空间下定义自己的VolumeComponent类,这里我的类名叫HologramBlock。
using System;
namespace UnityEngine.Rendering.Universal
{
//定义类
}
接着,在定义类的上面加上以下代码,就是把我们的类加入到Volume的组件里。
[System.Serializable, VolumeComponentMenu("HL/HologramBlock")]
整个文件的代码如下:
using System;
namespace UnityEngine.Rendering.Universal
{
[System.Serializable, VolumeComponentMenu("HL/HologramBlock")]
public sealed class HologramBlock : VolumeComponent, IPostProcessComponent
{
[Tooltip("是否开启效果")]
public BoolParameter enableEffect = new BoolParameter(true);
public bool IsActive() => enableEffect==true;
public bool IsTileCompatible() => false;
}
}
然后就可以在Volume下面找到我们的Volume组件啦!
但是目前还没有任何效果哈,下面的步骤就是给我们的Volume添加实际的效果。
步骤二:
创建自定义的ScriptableRendererFeature和ScriptableRenderPass
因为Unity暂时在URP自定义扩展Volume并没有太多接口和相关文档说明,也有可能是我没找到。
所以目前的方法还是通过ScriptableRendererFeature和ScriptableRenderPass去做。
如果对部分理论有不理解的可以参考我之前的文章,传送门:琅琅:Unity的URP的自定义后处理效果实现
首先定义我们的ScriptableRendererFeature:
using UnityEngine.Rendering.Universal;
public class HologramBlockRenderFeature : ScriptableRendererFeature
{
HologramBlockRenderPass m_ScriptablePass;
public override void Create()
{
m_ScriptablePass = new HologramBlockRenderPass();
m_ScriptablePass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
m_renderTargetHandle.Init("_ScreenTexture2");
}
RenderTargetHandle m_renderTargetHandle;
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
var dest = RenderTargetHandle.CameraTarget;
m_ScriptablePass.Setup(renderer.cameraColorTarget, dest);
renderer.EnqueuePass(m_ScriptablePass);
}
}
接着定义我们的ScriptableRenderPass,在Override的Execute方法里做我们的具体的后处理:
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (holoMat == null)
{
UnityEngine.Debug.LogError("材质没找到!");
return;
}
if (!renderingData.cameraData.postProcessEnabled) return;
//通过队列来找到HologramBlock组件,然后
var stack = VolumeManager.instance.stack;
hologramBlock = stack.GetComponent<HologramBlock>();
if (hologramBlock == null){return;}
if (!hologramBlock.IsActive())return;
var cmd = CommandBufferPool.Get(k_RenderTag);
Render(cmd, ref renderingData);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
上面使用了VolumeManager.instance.stack的GetComponent方法来获得我们的自定义Volume类的实例。
并获取里面的属性变量来做具体的后处理。
可以调用我们的HologramBlock组件的IsActive方法来判断是否执行该后处理。
诚然,这个IsActive返回的值,是你自己在继承的VolumeComponent类里定义的,
并非是VolumeComponent组件的启用和禁用决定的。
步骤三:
写后处理所需的shader。
写我们后处理的shader,该shader是一个视频错误效果。
我在ScriptableRenderPass的构造函数中用该shader创建了一个Material。
public HologramBlockRenderPass()
{
var shader = Shader.Find(&#34;Hidden/HL/HologramBlockPE&#34;);
holoMat = CoreUtils.CreateEngineMaterial(shader);
m_temporaryColorTexture.Init(&#34;temporaryColorTexture&#34;);
}
shader文件内容在源码下载中可见,文件名是HologramBlockPE.shader。
步骤四:
配置我们的东西到Unity里。
在ForwardRendererData里Add Renderer Feature。
在Camera中勾选Post Processing
同时,在Camera的Environment的Volume Mask中选择相应的volume的gameObject的Layer。
步骤五:
最后,把HologramBlock添加到Volume里,就可以生效了。我使用了
这里我在代码里添加了Enable Effect来控制是否生效。
因为RenderFeature一旦加入到ForwardRendererData里,
它就一直会执行ScriptableRenderPass的Execute方法。这个我感觉挺不喜欢的。
最终效果:
该方法存在的问题:
RenderFeature一旦加入到ForwardRendererData里,它就一直会执行ScriptableRenderPass的Execute方法。
所以我只能通过外部的代码来控制Execute方法里的东西是否执行。勾线掉该组件,并非能让它不生效。
也可能是我没找到相应的接口吧。如果有问题,请朋友们指出。
为了解决这个问题,比如我可以写一个PostEffectCtrl的类,如果我不需要该后处理,
我就会将PostEffectCtrl的静态变量Close的值设为false,然后
使用PostEffectCtrl.Close来判断是否执行ScriptableRenderPass的Execute的内容,
不需要就return。
另外,可以给VolumeComponent类配对一个VolumeComponentEditor
如果你对界面显示有要求的话,可以写一个VolumeComponentEditor哈。
代码也比较简单,只需继承VolumeComponentEditor类,并且
在定义类的上面添加[VolumeComponentEditor(typeof(你的VolumeComponent类名))],大体如下:
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(HologramBlock))]
sealed class HologramBlockEditor : VolumeComponentEditor
{
}
}
具体可以看我提供的工程里的源码哈,文件名为HologramBlockEditor.cs
源码下载:
链接:https://pan.baidu.com/s/1_9lkdanrnnZAFZAeIvbtEQ
提取码:amqx
参考文章:
感谢这位日本朋友的文章,还有知乎的会编程的猫的文章。感谢他们前人栽树后人乘凉。
https://qiita.com/t-matsunaga/items/09343ae7c683269374c4
https://zhuanlan.zhihu.com/p/161658349
HDRP如何自定义扩展Volume可以参考Keijiro Takahashi大神的工程:
https://gitee.com/langlang1988/KinoEight
以上,最后,希望这篇文章能给在使用URP的朋友们带来帮助。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|