美文网首页
Unity URP UniversalRendePipeline

Unity URP UniversalRendePipeline

作者: 暴走TA | 来源:发表于2024-02-01 18:07 被阅读0次

    简介: 感谢最近的工作需求,好好翻了一下 Unity URP UniversalRenderPipeline,继 URP 管线主要类 分析之后,来仔细看一下 UniversalRenderPipeline
    软件: unity 2022.3.14f1c1
    管线:com.unity.render-pipelines.universal@14.0.9

    背景

    由上篇文章 URP 管线主要类 分析之后 可知

    1. UniversalRenderPipeline 继承自 RenderPipeline
    2. UniversalRenderer 继承自 ScriptableRenderer
    3. UniversalRenderer 的数据类为 UniversalRendererData,用于保存 UniversalRenderer 的配置和创建 UniversalRenderer
      • UniversalRenderer 的构造函数强制需要传入 UniversalRendererData
      • UniversalRendererData 有一个 Create 函数用来创建 UniversalRenderer
    4. UniversalRenderPipelineAsset
      • 提供 UniversalRenderPipeline 的创建方法
      • 创建 UniversalRenderPipeline 时强制传入UniversalRenderPipelineAsset
      • 内部有一个 ScriptableRendererData 列表,用来保存当前管线可以用到的 RendererData , 然后还是用一个 ScriptableRenderer[] m_Renderers 来缓存生成的 scriptableRenderer
    5. URP 中的相机默认都必须有一个 UniversalAdditionalCamera 组件,这个组件保存了当前要用的 UniversalRenderer 的索引,提供一个 scriptableRenderer 属性用来获取当前相机的 Renderer。
      • scriptableRenderer 属性通过 UniversalRenderPipeline.asset 拿到管线配置文件,然后使用管线配置文件提供的 GetRenderer(int index) 方法获取对应的 scriptableRenderer。

    Pipline 渲染步骤

    除去我们不好找的引擎内部逻辑,我们就以引擎调用到 UniversalRenderPipelineRender(ScriptableRenderContext renderContext, List<Camera> cameras) 开始往后推。

    Render 方法

    1. Pipline 的 Render,接受一个渲染上下文和一个相机列表。
    2. 开始部分会做一个 ProfilingScope 标记,然后设置一些色彩空间,渲染层级,MSAA 级别等。
    3. 遍历所有的相机
      • 如果是 Game 相机则调用 RenderCameraStack(renderContext, camera) 渲染。我们主要关注这个
      • 如果不是 Game 相机则再做一个 BeginCameraRendering 标记,然后更新 Volume框架,然后调用用 RenderSingleCameraInternal(renderContext, camera) 进行渲染。然后关闭标记
    4. 关闭对应的 ProfilingScope 标记

    RenderCameraStack 方法

    渲染 UPR 中的相机Stack

    1. 起手添加一个 ProfilingScope 标记
    2. 从相机对象上获取 UniversalAdditionalCameraData 组件,
      • 通过该组件就可以获得相机上的 scriptableRenderer
      • 通过该组件就可以获得相机上的 Stack 列表
    3. 遍历 Stack 列表,对相机数据进行预处理
      • 剔除已经删除的或未激活的相机,
      • 剔除和base相机不是同一个 scriptableRenderer 类型的相机
      • 收集堆中的相机是否有开启后处理的
    4. 结束 Stack 列表的遍历后,如果有相机不生效了,则更新相机的 stack
    1. 然后引入了 XRSsytem 系统, 向baske相机添加至其中,我不做 AR VR 所以,这里对我意义不大,当然 base 相机之后也是从这里取出,这里的放入、取出,我就当其没有发生过,管线这里这样写应该也是为了兼容 AR VR
    1. InitializeCameraData 方法初始化相机数据到 baseCameraData ,具体内容下面单写
    2. InitializeAdditionalCameraData 方法初始化相机数据到 baseCameraData , 具体内容下面单写
    3. 设置 baseCameraData 的一些属性
    4. RenderSingleCamera 调用单相机渲染 basecamera
    5. 遍历 cameraStack ,每个相机调用 RenderSingleCamera 进行渲染
      • 获取 cameradata
      • 调用 InitializeAdditionalCameraData 初始化 overlayCameraData
      • 设置 overlayCameraData
      • 调用 RenderSingleCamera 逐相机渲染
    6. 一些其它 XR 的设置和调用
      上述的步骤中基本上每个相机都会一个 ProfilingScope 标记对,用来便于debug,辅助功能所以没有全部写在上述的步骤中

    InitializeCameraData

    顾名思义,初始化相机数据。这个方法会将数据返回给传入的 cameraData 对象,InitializeAdditionalCameraData 也是这个操作。

    1. 设置 cameraData 的一些属性
      • 创建 cameraData 对象
      • 调用 InitializeStackedCameraData 初始化相机堆栈数据
      • 设置 cameraData.camera
      • 设置相机的 MSAA、 XR 、HDR、cameraTargetDescriptor信息
    2. 设置相机的堆栈数据 InitializeStackedCameraData
      • 设置 cameraData.targetTexture
      • 设置 cameraData.cameraType
      • 根据相机类型设置 环境和后处理设置,主要分为,场景相机数据、UPR的baseAdditionalCameraData数据、默认相机数据
      • 设置输出设置,HDR 、size、renderScale、upscalingFilter、imageScalingMode、fsrOverrideSharpness、defaultOpaqueSortFlags、captureActions

    InitializeAdditionalCameraData

    初始化 additionalCameraData 相机数据到 cameraData ,这里的 cameraData 和 InitializeCameraData 里的是同一个对象(结构体 struct)

    1. 设置 cameraData 的各种属性对象
      • 具体的属性对象就翻一下类看吧,就是相机场景的属性
    2. 设置一些 debug 属性的 override
    3. 设置了 SetViewProjectionAndJitterMatrix

    RenderSingleCamera

    主要的渲染逻辑在这里,主要是对renderer的设置,从这里也可以看出,我们的 UniversalRender 是和相机一一对应的,这个 renderer 对象就保存为 CameraData 的 renderer 属性,即 cameraData.renderer

    1. 设置从 cameraData 获取 renderer 和 camera
    2. ScriptableRenderer.current=renderer ; 进行全局设置。ScriptableRenderer.current 是一个静态属性
    3. CommandBufferPool 里获取一个 CommandBuffer cmd
    4. ProfilingScope 标记
    5. 调用 renderer.OnPreCullRenderPasses函数
    6. 计算一次 cmd ,context.ExecuteCommandBuffer(cmd)
    7. 设置相机相关的 shader 全局变量
      • 环境色
      • 环境光 等
    8. 一些特殊相机的预处理,如 CameraType.Reflection、CameraType.Preview、SceneViewCamera
    9. cameraData 设置 MotionVector 相关
    10. cameraData 设置相机输出 Handle 的尺寸
      11.context 获取剔除结果
    11. renderer 初始化 RenderingData
    12. renderer 添加渲染Pass
    13. 判断是否使用 useRenderGraph
      • 使用 则调用RecordAndExecuteRenderGraph 和 renderer.FinishRenderGraphRendering
      • 不使用则调用 renderer.Setuprenderer.Execute* ,我们一般的渲染都在 renderer.Execute 里面执行
    14. 结束标记
    15. context.ExecuteCommandBuffer(cmd) 执行 cmd,结束

    流程完成

    基本上上面的步骤走完,就开始使用 相机的 Renderer 进行渲染了。
    在 pipeline 中主要做的就是,

    • 相机的设置
    • 根据相机的 UniversalAdditionalCameraData 组件对象、相机本身的设置,管线的设置,来生成渲染要使用的 RenderingData。所以在后面的具体渲染中我们基本上方法接受的都是 ScriptableRenderContextRenderingData,这两个对象
    • 相机的 cull 操作
    • 相机类型的区分
    • 遍历相机,逐一设置后,调用正确的渲染方法。抛去 useRenderGraph,应该调用的是 renderer.Setup 和 renderer.Execute。
    • renderer.Execute(context, ref renderingData); 接受 contex 和 renderingData

    相关文章

      网友评论

          本文标题:Unity URP UniversalRendePipeline

          本文链接:https://www.haomeiwen.com/subject/prrzodtx.html