RenderPipeline Render()
==ProcessPerCamera(迴圈)
==CullResults.Cull()
====ProcessPerPass(迴圈)
在大都數的狀況下,cameras.Length大都多是1(本來以為EditorView的Camera也會進來…)
,而要做的事,基本上都是context通溝(下CommandBuffer指令,Submit畫完之類的)。
這裡並沒有把繪圖流程包成一個Pass物件,因為相關代碼只會有一個Pass,其中DrawRendererSettings需要的第二個參數ShaderPassName相當重要,它指的是在ShaderCode裡有指定相關的Tag才畫挑出來畫,比方"LightMode" = "ForwardBase",而你的ShaderPassName也是設成"ForwardBase"時,才會被挑出來。
相關代碼如下:
private void ExecuteCommandBuffers(ref ScriptableRenderContext context, Camera targetCamera, CameraEvent evt)
{
CommandBuffer[] commandBuffers = targetCamera.GetCommandBuffers(evt);
for (int index = 0; index < commandBuffers.Length; ++index)
context.ExecuteCommandBuffer(commandBuffers[index]);
}
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
base.Render(context, cameras);
Camera targetCamera;
for (int cameraIndex = 0; cameraIndex < cameras.Length; ++cameraIndex)
{
targetCamera = cameras[cameraIndex];
//取得Camera culling參數
ScriptableCullingParameters cullingParams;
if (!CullResults.GetCullingParameters(targetCamera, out cullingParams))
continue;
//依culling參數取得culling的結果
CullResults cull = CullResults.Cull(ref cullingParams, context);
// Setup camera for rendering (sets render target, view/projection matrices and other
// per-camera built-in shader variables).
//設定矩陣相關資訊
context.SetupCameraProperties(targetCamera);
//清除深度buffer
context.ExecuteCommandBuffer(_clearCommandBuffer);
//設定Shader Pass相關資訊(指定Pass Name及Camera)
var settings = new DrawRendererSettings(targetCamera, _forwardBasePassName);
//設定畫opaque物件的相關旗標並將其畫出
settings.sorting.flags = SortFlags.CommonOpaque;
var filterSettings = new FilterRenderersSettings(true) { renderQueueRange = RenderQueueRange.opaque };
context.DrawRenderers(cull.visibleRenderers, ref settings, filterSettings);
//執行AfterForwardOpaque的CommandBuffers
ExecuteCommandBuffers(ref context, targetCamera, CameraEvent.AfterForwardOpaque);
// Draw skybox
context.DrawSkybox(targetCamera);
//執行AfterSkybox的CommandBuffers
ExecuteCommandBuffers(ref context, targetCamera, CameraEvent.AfterSkybox);
//設定畫alpha物件的相關旗標並將其畫出
settings.sorting.flags = SortFlags.CommonTransparent;
filterSettings.renderQueueRange = RenderQueueRange.transparent;
context.DrawRenderers(cull.visibleRenderers, ref settings, filterSettings);
//執行AfterForwardAlpha的CommandBuffers
ExecuteCommandBuffers(ref context, targetCamera, CameraEvent.AfterForwardAlpha);
context.Submit();
}
}
其中比較特別的是ExecuteCommandBuffers,如果之前有接觸過CommandBuffers的人就會比
較清楚,由於目前整個繪圖管線是自己實作的,當然CommandBuffers也是要自己執行,以
下是有關CommandBuffers和自訂繪圖管線執行的狀況:
- 染紅色執行的順序是AfterForwardOpaque(只染Opaque物件)
- 染綠色執行的順序是AfterSkybox(染Opaque及SkyBox物件)
- 染藍色執行的順序是AfterForwardAlpha(染Opaque,SkyBox及Alpha物件)
相關參考與原始碼:Scriptable Render Pipeline Overview
Dream continues in...
沒有留言:
張貼留言