yukamu 发表于 2022-1-9 08:45

Unity URP渲染管线源码基础架构

ScriptableRenderer

ScriptableRenderer是一个抽象类,官方实现继承他的有ForwardRenderer和Renderer2D这两个类。
其中最重要的方法:
SetUp
/// <summary>
      /// Configures the render passes that will execute for this renderer.
      /// This method is called per-camera every frame.
      /// </summary>
      /// <param name="context">Use this render context to issue any draw commands during execution.</param>
      /// <param name="renderingData">Current render state information.</param>
      /// <seealso cref="ScriptableRenderPass"/>
      /// <seealso cref="ScriptableRendererFeature"/>
      public abstract void Setup(ScriptableRenderContext context, ref RenderingData renderingData);
这个方法主要是配置渲染时所需要的Render Passes

Excute
/// <summary>
      /// Execute the enqueued render passes. This automatically handles editor and stereo rendering.
      /// </summary>
      /// <param name="context">Use this render context to issue any draw commands during execution.</param>
      /// <param name="renderingData">Current render state information.</param>
      public void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
      {
             //......
      }该方法是依次执行队列中的render passes。
ScriptableRenderContext保存了渲染过程中渲染管线需要使用到的状态和绘制命令。
RenderingData保存的是当前渲染状态的信息

RenderPipelineAsset

主要用于管理渲染管线的资源,其变量都是一系列关于渲染管线的资源


而UniversalRenderPipelineAsset,管理URP的资源继承自此类。
通过其中的方法CreatePipeline()创建基于此资源的管线(UniversalRenderPipeline类)。

RenderPipeline

RenderPipeline类,根据官方的描述这个是定义了一系列的命令和设置,用于描述Unity如何渲染帧。
UniversalRenderPipeline继承于此类。其中包含的方法:


Render方法为管线渲染的主要入口之一
主要源码:
      protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
      {
            BeginFrameRendering(renderContext, cameras);

            GraphicsSettings.lightsUseLinearIntensity = (QualitySettings.activeColorSpace == ColorSpace.Linear);
            GraphicsSettings.useScriptableRenderPipelineBatching = asset.useSRPBatcher;
            SetupPerFrameShaderConstants();

            SortCameras(cameras);
            for (int i = 0; i < cameras.Length; ++i)
            {
                var camera = cameras;
                if (IsGameCamera(camera))
                {
                  RenderCameraStack(renderContext, camera);
                }
                else
                {
                  BeginCameraRendering(renderContext, camera);
                  RenderSingleCamera(renderContext, camera);
                  EndCameraRendering(renderContext, camera);
                }
            }

            EndFrameRendering(renderContext, cameras);
      }
其中调用的其他的静态方法BeginFrameRendering等
这个方法主要是设置好每帧需要的各种参数,然后按照Camera的深度排序相机,顺序渲染每个相机。
RenderSingleCamera为主要方法
在RenderSingleCamera中的主要逻辑为:
裁剪,设置渲染数据,render passes的设置和执行,执行cmd,submit
renderer.Clear(cameraData.renderType);
renderer.SetupCullingParameters(ref cullingParameters, ref cameraData);
var cullResults = context.Cull(ref cullingParameters);
renderer.Setup(context, ref renderingData);
renderer.Execute(context, ref renderingData);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
context.Submit();
在ExecuteCommandBuffer方法中,ScriptableRenderContext会将 commandBuffer 参数注册到自己要执行的命令内部列表中。 这些命令(包括存储在自定义 commandBuffer 中的命令)的实际执行发生在ScriptableRenderContext.Submit期间。

URP的基础架构主要为上述几个基类及他们的子类构成。
主要基础流程:

页: [1]
查看完整版本: Unity URP渲染管线源码基础架构