对管线的理解
首先这里的管线,指的是图形学上的管线,渲染一帧需要的所有逻辑,要和后边说的前向渲染管线做个区分。
简单来说,分成几个部分,首先是管线的配置,也就是之前内置管线Quality Setting里的各种数值。然后是底层管线的逻辑,也就是RenderPipeline这个基类,这个类比较简单,具体逻辑都是子类实现,这里只定义了几个事件,和声明周期控制函数。核心部分就是UniversalRenderPipeline这个类了,下面会细分析这个类。
先简单看看配置
在Quality Setting里,默认分了4个,default,低中高,和内置管线位置一样的,只是细节不同。
面板上的显示,基本上和UniversalRenderPipelineAsset类是一一对应的,主要分几个部分,比较重要的是光照和阴影,细节先不说了,用到了看看就行。
需要注意的是,这里的设置是对整个管线生效的,有些设置camera可以覆盖,比如depth和opaque贴图的选项。
管线的核心,UniversalRenderPipeline
先看数据
PerFrameBuffer
- 每一帧数据都是一样的
- _GlossyEnvironmentColor和_SubtractiveShadowColor这两个运行时可能是不会改变的,但是为了shader正确使用,还是要每帧设置一次。
- 时间相关的几个值,内置管线中是可以直接取的,URP中要自己设置了。
PerCameraBuffer:每个相机需要的数据,包括矩阵,屏幕参数,相机世界坐标。
接着有一些写死的数值,不一一列举了。需要注意的是最大可见附加光数量,在这个版本StructedBuffer没开启,以后是会开的,看源码的注释是说在移动平台有性能问题,有些GPU在顶点shader不支持SSBO。
核心逻辑,Render函数
首先会发一个渲染开始的事件,然后设置线性或gamma空间,是否使用SRPBatcher,设置shader变量值,然后按深度排序相机,正式开始渲染。
对每个相机,判断是game还是scene,渲染大体相似,主要看下game的渲染。
入口,RenderCameraStack。首先读取UniversalAdditionalCameraData数据,URP中有对VR的支持,手游用不上,先忽略不看。
单个game相机渲染的完整流程,由以下5个函数组成。
- BeginCameraRendering:只是发个事件
- UpdateVolumeFramework:对volume系统的支持,核心是调用VolumeManager的Update方法,暂时不细看。
- InitializeCameraData:初始化数据,填充CameraData结构体,就是设置一系列的数值。
- RenderSingleCamera:渲染的核心逻辑,源码的注释是,执行culling,调用renderer的setup和execution方法。
- 几个主要的功能,SetupPerCameraShaderConstants,设置PerCameraBuffer类中的数值,屏幕缩放比例,相机坐标,屏幕参数,invCameraViewProj。
- 渲染逻辑分两部分,先执行一次clear指令,然后设置裁剪参数ScriptableCullingParameters结构体,再调用InitializeRenderingData函数,填充RenderingData结构体,这个结构体包含渲染相关的所有参数,裁剪信息,相机数据,光照阴影数据,后处理等很多。
- RenderingData设置好之后,传给renderer,依次调用Setup和Execute,完成渲染,具体逻辑在Renderer部分细说。
- EndCameraRendering:结束事件。
渲染相机的大体流程就是这样,URP有个cameraStack的概念,大概理解就是一个相机带有一个stack,可包含多个相机,渲染的时候将stack里最后一个激活的相机渲染到屏幕上,渲染流程和上边差不多。
还有一个类是UniversalRenderPipelineCore,这是UniversalRenderPipeline的分部类,定义数据、选项、shader关键字以及一些功能性的函数。
总结一下,管线可以理解为一个纯逻辑的管理类,驱动每个相机去渲染,渲染方式是可扩展的。实际项目中,这部分应该不会有多大修改。
最后
以上就是舒适金鱼最近收集整理的关于URP源码学习(二)管线,pipeline的全部内容,更多相关URP源码学习(二)管线内容请搜索靠谱客的其他文章。
发表评论 取消回复