Skip to content
zilch edited this page Mar 8, 2021 · 2 revisions

写在前面

这个系列是从0开始,使用Unity的SRP(Scriptable Render Pipeline)来实现各种渲染功能。某些地方可能会在一开始有理解不到位的地方,后面如果发现了就会返回过来修改。

作为开篇,先定一个小目标,使用SRP绘制一个Cube。

1. 创建自定义渲染管线

SRP中实现自定义RP,需要按以下步骤来:

  • 继承RenderPipelineAsset,实现自己的RPAsset
  • 继承RenderPipeline,实现自己的RP
  • RPAssetCreatePipeline函数中返回自己实现的RP

用c#代码来实现,非常简单:

[CreateAssetMenu(menuName = "SRPLearn/XRendererPipelineAsset")]
public class XRendererPipelineAsset : RenderPipelineAsset
{
    protected override RenderPipeline CreatePipeline()
    {
        return new XRenderPipeline();
    }
}


public class XRenderPipeline : RenderPipeline
{
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
    }
}

然后右键->Create->SRPLearn->XRendererPipelineAsset,创建一个XRendererPipelineAsset资源文件,配置到Edit/ProjectSetting/Graphic

这样我们就完成了项目中自定义渲染管线的配置。但目前这条渲染管线什么都没做,所以场景中是一片漆黑,即使创建了Cube,也是看不到的。

2. 绘制对象

渲染管线的绘制入口为RenderPipeline.Render函数,Render函数有两个参数,分别是ScriptableRenderContextCamera[]数组。Camera数组包含了GameView中玩家创建的所有摄像机,以及SceneView中的编辑器摄像机。 我们需要对每个摄像机,做单独的渲染操作。这里暂不区分SceneView与GameView

protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
    //遍历摄像机,进行渲染
    foreach(var camera in cameras){
        RenderPerCamera(context,camera);
    }
    //提交渲染命令
    context.Submit();
}

RenderPerCamera实现:

private void RenderPerCamera(ScriptableRenderContext context,Camera camera){
    //将camera相关参数,设置到渲染管线中
    context.SetupCameraProperties(camera);
    //对场景进行裁剪
    camera.TryGetCullingParameters( out var cullingParams);
    var cullingResults = context.Cull(ref cullingParams);

    //相关参数,用来计算物体渲染时的排序
    var sortingSetting = new SortingSettings(camera);
    var drawSetting = new DrawingSettings(_shaderTag,sortingSetting);
    //相关参数,用来过滤需要渲染的物体
    var filterSetting = new FilteringSettings(RenderQueueRange.all);
    //绘制物体
    context.DrawRenderers(cullingResults,ref drawSetting,ref filterSetting);
}

其中_shaderTag定义如下:

private ShaderTagId _shaderTag = new ShaderTagId("ForwardBase");

这表示,我们只会绘制Shader的LightModeForwardBase的物体。(因为目前创建的Cube,默认使用Builtin的Standard材质,其LightMode为ForwardBase)

这样,场景中就能正常显示创建的Cube了。

但是你会发现Directional Light无论如何调整,都不起效果。 那是因为我们还没在渲染管线中加入灯光控制。

Clone this wiki locally