LWRP 轻量级渲染
根据官方给出的PPT以及大致的说明
LWRP 是精简并且优化过的渲染管线、主要聚焦性能、针对移动平台
所以开坑 LWRP,至于HDRP这个主要用于高性能的主机和PC上,目前不做端游,暂不考虑
- 高性能和高一致性的PBR
- 新的Shader库
- 一次渲染多个实时光
- 可插入 Scriptable Render Passes 的 API
Unity Test Version: 2019.3.0.f1
而 Scriptable Render Passes 是由C#代码来完成渲染管线的编写。在Unity 高版本中(笔者 Unity2019 3.0.f1)通过Editor -> Project Setting -> Graphices [ Scriptable Render Pipeline Settings ] 来设置我们自定义的管线配置。
示意图:
那么 Scriptable Render Pipeline Settings 需要指定什么文件?
在Unity中,官方的配置都是基于 ScriptableObject可序列化的配置,我们先尝试写下代码。
[ExecuteInEditMode]
public class BasePipelineAsset_test : RenderPipelineAsset
{
#if UNITY_EDITOR
[UnityEditor.MenuItem("RenderPipeline/Create BasePipelineAsset")]
public static void CreateBasePipelineAsset()
{
var instances = ScriptableObject.CreateInstance<BasePipelineAsset_test>();
UnityEditor.AssetDatabase.CreateAsset(instances, "Assets/Pipelines/BasePiplineAsset.asset");
}
#endif
protected override RenderPipeline CreatePipeline()
{
return null;
}
//这是一份自定义的序列化管线配置。
}
到此我们可以通过菜单 RenderPipeline => Create BasePipelineAsset创建一个管线配置,之后把创建 OK 的配置拖入 Scriptable Render Pipeline Settings 中,为此管线配置创建完成,然后看看Scene 和 Game 视图。
全黑!别担心,这是没问题的,因为此时我们还没开始渲染任何东西。
到了这一步,我们主相机没用了吗?然而并不是!我们看接下来的代码!
首先我们抽象一个基类:
public abstract class BasicRenderPipeline : RenderPipeline
{
protected CommandBuffer command;
[SerializeField] protected Color m_ClearColor;
public BasicRenderPipeline()
{
command = new CommandBuffer();
}
public BasicRenderPipeline(Color clear) : this()
{
this.m_ClearColor = clear;
}
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
foreach (Camera c in cameras)
{
this.Render(context, c);
}
}
protected abstract void Render(ScriptableRenderContext context, Camera camera);
}
然后我们通过继承来创建一个管道:
public class MainPipeline : BasicRenderPipeline
{
public MainPipeline(Color clear) : base(clear){ }
protected override void Render(ScriptableRenderContext context, Camera camera)
{
command.Clear();
command.ClearRenderTarget(true, true, this.m_ClearColor);
context.ExecuteCommandBuffer(command);
context.Submit();
}
}
这样若后续有多条管道,我们都可以通过继承的方式来完成,渲染主要写在基类抽象出来的Render函数。
最后在 BasePipelineAsset_test 类中 CreatePipeline 函数中返回我们编写的管道 MainPipeline
[ExecuteInEditMode]
public class BasePipelineAsset_test : RenderPipelineAsset
{
#if UNITY_EDITOR
[UnityEditor.MenuItem("RenderPipeline/Create BasePipelineAsset")]
public static void CreateBasePipelineAsset()
{
var instances = ScriptableObject.CreateInstance<BasePipelineAsset_test>();
UnityEditor.AssetDatabase.CreateAsset(instances, "Assets/Pipelines/BasePiplineAsset.asset");
}
#endif
protected override RenderPipeline CreatePipeline()
{
return new MainPipeline(Color.grey);
}
}
这条管道仅仅是清空了颜色(灰色做基色),返回Unity,我们就可以看的效果了,但是有个问题,就是当屏幕的分辨率不是常规像什么16:9之类,会出现部分颜色无法清空。
异常图一:
我们可以看的Scene视图是已经清空了的,但是Game视图,scale 约趋近 1 颜色清理较为 '干净'。
异常图二:
当我们尝试缩放屏幕就会发现问题了,这个问题解决起来也很简单。
在管道渲染的函数中指定设置相机的属性,若不指定,估计我们的相机也变得没有任何L用(作用应该会有,就是可以遍历我们的管道 = 。=)
修改后的代码:
public class MainPipeline : BasicRenderPipeline
{
public MainPipeline(Color clear) : base(clear){ }
protected override void Render(ScriptableRenderContext context, Camera camera)
{
command.Clear();
context.SetupCameraProperties(camera);
command.ClearRenderTarget(true, true, this.m_ClearColor);
context.ExecuteCommandBuffer(command);
context.Submit();
}
}
OK,这样不管怎样缩放,相机的参数都起作用了,上个动图(可能不会动)