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 ] 來設定我們自定義的管線配置。
示意圖:
image.png
那麼 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 視圖。
image.png
全黑!别擔心,這是沒問題的,因為此時我們還沒開始渲染任何東西。
到了這一步,我們主相機沒用了嗎?然而并不是!我們看接下來的代碼!
首先我們抽象一個基類:
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,這樣不管怎樣縮放,相機的參數都起作用了