天天看點

Unity3D LWRP輕量級渲染之建構SRP管線LWRP 輕量級渲染

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 ] 來設定我們自定義的管線配置。

示意圖:

Unity3D LWRP輕量級渲染之建構SRP管線LWRP 輕量級渲染

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 視圖。

Unity3D LWRP輕量級渲染之建構SRP管線LWRP 輕量級渲染

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之類,會出現部分顔色無法清空。

異常圖一:

Unity3D LWRP輕量級渲染之建構SRP管線LWRP 輕量級渲染

圖一

我們可以看的Scene視圖是已經清空了的,但是Game視圖,scale 約趨近 1 顔色清理較為 '幹淨'。

異常圖二:

Unity3D LWRP輕量級渲染之建構SRP管線LWRP 輕量級渲染

圖二

當我們嘗試縮放螢幕就會發現問題了,這個問題解決起來也很簡單。

在管道渲染的函數中指定設定相機的屬性,若不指定,估計我們的相機也變得沒有任何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,這樣不管怎樣縮放,相機的參數都起作用了

Unity3D LWRP輕量級渲染之建構SRP管線LWRP 輕量級渲染

繼續閱讀