Unity 2019.4.30
URP 7.7.1
刚把测试项目升级到URP,本想看官方的Demo工程学习写一个简单后效,快速GettingStart
结果官方示例已经是 Unity 2020 URP 10.8.1 内容变化很多
最后还是结合Unity教程,终于把简单的后效跑起来了
Forward Renderer Data
创建Pipeline Asset之后,有一个同名的Forward Renderer Data
创建Forward Render Data,我命名的是DistortForwardData,扭曲的效果,测试的话默认ImageEffect就行。
添加到 PipelineAsset RenderList
回到DistortForwardData
Add Renderer Feature 可以添加Renderer Feature,但是此时只能添加Renderer Objects,还是实验性的
后效需要构建自己的Renderer Feature
Renderer Feature
创建DistortFeature类,继承ScriptableRendererFeature
再加两个类,逻辑比较简单直接作为内部类就行。
CustomPass类,继承ScriptableRenderPass,核心的渲染逻辑写在这里。
DistortSettings类,主要是用于传参,会出现在Renderer Feature的面板上,可以把材质参数放这里。
这时候在DistortForwardData就可以看到我们写的Feature啦
大致的代码结构如下:
Create()
可以在这里做初始化操作。
比如把Setting的参数赋值给CustomPass,我们会在CustomPass对材质参数进行设置。
public override void Create()
{
customPass = new CustomPass();
customPass.renderPassEvent = Settings.renderPassEvent;
customPass.Material = Settings.Material;
customPass.Distortion = Settings.Distortion;
customPass.Scale = Settings.Scale;
}
AddRenderPasses()
在这里将CustomPass加入队列
我们的CustomPass还需要相机的输出,就来自ScriptableRenderer.cameraColorTarget,
给CustomPass增加Setup方法,在加入队列之前,由Setup传给CustomPass
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
customPass.Setup(renderer.cameraColorTarget);
renderer.EnqueuePass(customPass);
}
Renderer Pass
核心方法就是Execute,我们在这里创建CommandBuffer,由ScriptableRenderContext执行。
CustomPass的父类ScriptableRenderPass属性renderPassEvent指定执行的阶段。
public class DistortFeature : ScriptableRendererFeature
{
[System.Serializable]
public class DistortSettings
{
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
public Material Material = null;
[Range(0.001f, 10)] public float Distortion;
[Range(0.001f, 10)] public float Scale;
}
public class CustomPass : ScriptableRenderPass
{
static readonly string renderTag = "My Distort Effect";
public Material Material = null;
public float Distortion;
public float Scale;
RenderTargetIdentifier currentTarget;
int TempTargetId = Shader.PropertyToID("_TempTarget");
public void Setup(in RenderTargetIdentifier target)
{
currentTarget = target;
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (Material == null) return;
var source = currentTarget;
var destination = TempTargetId;
Material.SetFloat("_distortion", Distortion);
Material.SetFloat("_scale", Scale);
CommandBuffer cmd = CommandBufferPool.Get(renderTag);
cmd.Clear();
cmd.GetTemporaryRT(destination, Screen.width, Screen.height, 0);
cmd.Blit(source, destination, Material);
cmd.Blit(destination, source);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}
public DistortSettings Settings = new DistortSettings();
private CustomPass customPass;
public override void Create()
{
customPass = new CustomPass();
customPass.renderPassEvent = Settings.renderPassEvent;
customPass.Material = Settings.Material;
customPass.Distortion = Settings.Distortion;
customPass.Scale = Settings.Scale;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
customPass.Setup(renderer.cameraColorTarget);
renderer.EnqueuePass(customPass);
}
}
回到场景把相机设置上
然后就可以在Forward Renderer Data修改参数查看效果
参考资料:
[1] URP系列教程 | 如何使用Scriptable Renderer Feature来自定义后处理效果(https://zhuanlan.zhihu.com/p/373273390)