-
Notifications
You must be signed in to change notification settings - Fork 85
URP Source
zilch edited this page Feb 25, 2021
·
2 revisions
URP的主入口为UniversalRenderPipeline.Render
,源码分析就从这里开始.
Render依次做了如下的事情:
- BeginFrameRendering
- GraphicsSettings设置
- SetupPerFrameShaderConstants
- 摄像机排序
- 遍历对每个摄像机进行渲染
- EndFrameRendering
看Render代码:
protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
{
BeginFrameRendering(renderContext, cameras);
//颜色空间设置
GraphicsSettings.lightsUseLinearIntensity = (QualitySettings.activeColorSpace == ColorSpace.Linear);
//是否开启SRP合批功能
GraphicsSettings.useScriptableRenderPipelineBatching = asset.useSRPBatcher;
//相关Shader参数设置
SetupPerFrameShaderConstants();
#if ENABLE_VR && ENABLE_XR_MODULE
SetupXRStates();
#endif
//对摄像机渲染优先级进行排序。这里排序是根据camera的depth进行的
SortCameras(cameras);
//针对每个摄像机,进行渲染
for (int i = 0; i < cameras.Length; ++i)
{
var camera = cameras[i];
#if ENABLE_VR && ENABLE_XR_MODULE
if (IsStereoEnabled(camera) && xrSkipRender)
continue;
#endif
//判定是否为GameView的摄像机. 参见CameraType
//https://docs.unity3d.com/ScriptReference/CameraType.html
//SceneView和GameView的摄像机,走的渲染流程会有些不一样
if (IsGameCamera(camera))
{
///关键代码
RenderCameraStack(renderContext, camera);
}
else
{
BeginCameraRendering(renderContext, camera);
#if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER
//It should be called before culling to prepare material. When there isn't any VisualEffect component, this method has no effect.
VFX.VFXManager.PrepareCamera(camera);
#endif
UpdateVolumeFramework(camera, null);
RenderSingleCamera(renderContext, camera);
EndCameraRendering(renderContext, camera);
}
}
EndFrameRendering(renderContext, cameras);
}
可以看出,关键代码在于RenderCameraStack
这个函数。 CameraStack是什么?参考官方文档
RenderCameraStack
函数实际渲染了一个BaseCamera和归属于它的多个OverlayCamera。内部基本逻辑为:
RenderCamera(baseCamera);
foreach(overlayCamera in baseCamera.stackCameras){
RenderCamera(overlayCamera);
}
关键代码RenderCamera
,内部基本流程为:
-
BeginCameraRendering
发送
RenderPipelineManager.beginCameraRendering
事件 -
InitializeCameraData
初始化CameraData对象
-
RenderSingleCamera
渲染单个摄像机
-
EndCameraRendering
发送
RenderPipelineManager.endFrameRendering
事件
摘取关键代码,并简化后如下:
CommandBuffer cmd = CommandBufferPool.Get(sampler.name);
renderer.Clear(cameraData.renderType);
//裁剪
renderer.SetupCullingParameters(ref cullingParameters, ref cameraData);
var cullResults = context.Cull(ref cullingParameters);
//根据裁剪信息,生成RenderingData
InitializeRenderingData(asset, ref cameraData, ref cullResults, anyPostProcessingEnabled, out var renderingData);
//初始化管线
renderer.Setup(context, ref renderingData);
//渲染
renderer.Execute(context, ref renderingData);
//执行CommandBuffer
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
//提交
context.Submit();
其中renderer
为ScriptableRenderer
对象。这是URP中定义的,URP允许为一个URPAsset配置多个ScriptableRenderer。 ScriptableRenderer负责实现裁剪和光照策略。
Class ScriptableRenderer implements a rendering strategy. It describes how culling and lighting works and the effects supported.
A renderer can be used for all cameras or be overridden on a per-camera basis. It will implement light culling and setup and describe a list of ScriptableRenderPass to execute in a frame. The renderer can be extended to support more effect with additional ScriptableRendererFeature. Resources for the renderer are serialized in ScriptableRendererData.