This section explains how the generated mesh draw commands are converted into the final RHI commands.
First, the mesh draw commands are culled. However, this step is postponed so as not to interrupt the chain of FMeshBatch
→ FMeshDrawCommand
→ RHICommand
. Hence, we will assume that the mesh draw commands are already culled.
We will talk about culling in this chapter.
<aside> ℹ️ FDeferredShadingSceneRenderer::RenderPrePass
</aside>
Next, the core part of the whole rendering system can be found in the FDeferredShadingSceneRenderer::Render
function in DeferredShadingRenderer.cpp
. This function consists of about 2000 lines of code, so we will not explain each line. Instead, let's take another look at the depth prepass.
We will revisit the rendering pipeline later. For now, let's focus on the FDeferredShadingSceneRenderer::RenderPrePass
function, which is called by FDeferredShadingSceneRenderer::Render
. Finally, it calls DispatchDraw
.
graph TD
FDeferredShadingSceneRenderer::Render --> RenderPrepass
subgraph RenderPrepass
GetDepthPassParameters --> BuildRenderingCommands --> AddPass
end
subgraph AddPass
DispatchDraw["View.ParallelMeshDrawCommandPasses[EMeshPass::DepthPass].DispatchDraw"]
end
As mentioned earlier, the Mesh Draw Command contains the necessary information to initiate one Draw Call.
However, this does not mean that one Mesh Draw Command corresponds to one RHI API call.
This is because the data required for the Draw Call, such as Vertex, Pixel Shaders, and Pipeline State, needs to be set through API calls.
In summary, when executing a Mesh Draw Command, multiple RHI API Commands are filled in the RHI Command List. However, there is usually only one Draw Call API Command for drawing, which is located at the end.
<aside> ℹ️ FParallelMeshDrawCommandPass::DispatchDraw
</aside>
Let’s take a close look of the mapping between FMeshDrawCommand
and RHICommand
, which is the content of View.ParallelMeshDrawCommandPasses[EMeshPass::DepthPass].DispatchDraw
.
graph LR
subgraph FMeshDrawCommand
direction TB
CachedPipelineId
VertexStreams
end
CachedPipelineId --> MeshPipelineState
MeshPipelineState --> SetGraphicsPipelineState
VertexStreams --> SetStreamSource
MeshPipelineState --> BoundShaderState --> SetShaderBindings
BoundShaderState --> SetShaderBindings1
subgraph RHICommands
direction TB
SetGraphicsPipelineState
SetStreamSource
SetShaderBindings
SetShaderBindings1["SetShaderBindings(PixelShader)"]
DrawIndexedPrimitive
end
subgraph SetShaderBindings["SetShaderBindings(VertexShader)"]
direction LR
SetSamplerParameter --> AllShaderParameters
SetSrvParameter-->AllShaderParameters
SetTextureParameter-->AllShaderParameters
SetLooseParameters --> AllShaderParameters
AllShaderParameters--> SetShaderParameters
AllShaderParameters(["AllShaderParameters"])
end
<aside> ℹ️ FMeshDrawCommand::SubmitDraw
</aside>
This is a simplified version, if you don’t remember the mapping to the FMeshDrawCommand
, check this part. And if you want to check the details, check this function: FMeshDrawCommand::SubmitDraw