从今天起,我将从主渲染函数入手,来整理整个UE4的渲染内容和框架,这将是一个非常漫长和艰巨的任务,因为其内容实在是太多,虚幻的更新速度也是超乎寻常的快,但是以后的版本应该不会有大的调整,毕竟新的框架直接用在UE5就可以了。

这里我们只是笼统的将Render函数那一个层级所出现的内容进行概况和整理,每一个概念的内部原理将会在之后的该系列文章中进行讲解。

虚化中目前的渲染基类为FSceneRenderer,其一共有两个派生类,一个是FDeferredShadingSceneRenderer,另一个是FMobileSceneRenderer。当然我们就算是在编辑器里选择为前向渲染,其本身还是会走FDeferredShadingSceneRendererFMobileSceneRenderer确实是移动平台才会创建的类型。我们讲讨论feature更完备的FDeferredShadingSceneRenderer

关于延迟渲染和前向渲染这种问题到底还需不需要讨论,如果有讨论的必要请在评论区留言,否则就默认大家都会的。因为实在是没办法照顾到所有人的学习阶段,是统一天坑还是我讲我的,前期很多概念没有达成共识的话,基本上很难理解剩下的内容。

在这里我将去掉与头发、光线追踪,虚拟纹理相关内容,因为他们比较凌乱,后面如果有可能会出专题。

看代码之前我们可以使用RenderDoc来抓帧unreal,只要安装了RenderDoc并且你启用了对应的插件。之后你就会看到对应的渲染列表。

这可以帮助你快速的对应代码,图形化的帮助你理解每一步的用处。

//更新需要添加到scene和需要删除的物体。
Scene->UpdateAllPrimitiveSceneInfos(RHICmdList, true);

//抗锯齿策略,分辨率大小比例,窗口大小,屏幕百分比策略
PrepareViewRectsForRendering();

//场景中是否存在天空大气的渲染需求,进行准备工作
PrepareSunLightProxy(*Scene->GetSkyAtmosphereSceneInfo(),LightIndex, *Scene->AtmosphereLights[LightIndex]);
//如果存在多GPU,计算GPUMask
ComputeViewGPUMasks(RenderTargetGPUMask);
//将RT池中的rt设置为可写入
GRenderTargetPool.TransitionTargetsWritable(RHICmdList);
//清理所有的sceneColor
SceneContext.ReleaseSceneColor();
//等待上一帧的遮挡剔除完成
WaitOcclusionTests(RHICmdList);
//初始化纯色的那些贴图
GSystemTextures.InitializeTextures(RHICmdList, FeatureLevel);
//重新分配所有的RT
SceneContext.Allocate(RHICmdList, this);
//进行物体的装配和渲染pass的组装,做剔除
bDoInitViewAftersPrepass = InitViews(RHICmdList, BasePassDepthStencilAccess, ILCTaskData, UpdateViewCustomDataEvents);

//更新GPUscene,所有的物体都在GPU里有一套,可以用来还原场景和进行数据访问
UpdateGPUScene(RHICmdList, *Scene);

//加载GPUScene 的dunamic data
UploadDynamicPrimitiveShaderDataForView(RHICmdList, *Scene, View);
//准备距离场信息
PrepareDistanceFieldScene(RHICmdList, bSplitDispatch);
//遮挡查询,当然是是跟你的硬件平台支持相关,遮挡查询是使用硬件的api特性来做的。
DoOcclusionQueries(FeatureLevel)
//提交DynamicBuffer
//预计算Dither stencil
PreRenderDitherFill(RHICmdList, SceneContext, StencilTextureUAV);
//渲染天空大气的LookUpTable
RenderSkyAtmosphereLookUpTables(RHICmdList);
//通知将要渲染特效,进行排序
GPUSortManager->OnPreRender(RHICmdList);
//等待DitherFill完成
RHICmdList.WaitComputeFence(AsyncDitherLODEndFence);

//将GPUSkin的Cache设置为Render
RunGPUSkinCacheTransition(RHICmdList, Scene, EGPUSkinCacheTransition::Renderer);

//开始渲染第一个pass Pre pass
RenderPrePass(RHICmdList, AfterTasksAreStarted);
  
//搜集场景中所有的光源,进行光源网格的计算
GatherAndSortLights(SortedLightSet);
ComputeLightGrid(RHICmdList, bComputeLightGrid, SortedLightSet);

//遮挡查询,为下一帧所使用,本帧的遮挡使用的是上一帧的数据
RenderOcclusion(RHICmdList);
bool bUseHzbOcclusion = RenderHzb(RHICmdList);
FinishOcclusion(RHICmdList);
if (bOcclusionBeforeBasePass)
{
    //如果开启选项 提早渲染阴影
    RenderShadowDepthMaps(RHICmdList);

    //计算体积雾
    ComputeVolumetricFog(RHICmdList);
}
//清理LPV
ClearLPVs(RHICmdList);


//计算Dbuffer                       
GCompositionLighting.ProcessBeforeBasePass(RHICmdList, View, bDBuffer, SSAOLevels);

//渲染CapsuleShadow
RenderIndirectCapsuleShadows(……)
if(GetCustomDepthPassLocation() == 0)
{
    //根据选项判断是否需要渲染CustomDepth
    RenderCustomDepthPassAtLocation(RHICmdList, 0);
};


//建立我们 的Gbuffer
SceneContext.BeginRenderingGBuffer(RHICmdList, ColorLoadAction, DepthLoadAction, BasePassDepthStencilAccess, 
ViewFamily.EngineShowFlags.ShaderComplexity, true, ClearColor);
//写Gbuffer
RenderBasePass()

if (!bOcclusionBeforeBasePass)
{
	RenderShadowDepthMaps(RHICmdList);
    ComputeVolumetricFog(RHICmdList);
}
if(GetCustomDepthPassLocation() == 1)
{
	RenderCustomDepthPassAtLocation(RHICmdList, 1);
}




//进行Lighting
RenderDiffuseIndirectAndAmbientOcclusion(RHICmdList);
RenderIndirectCapsuleShadows();
RenderDFAOAsIndirectShadowing(RHICmdList, SceneContext.SceneVelocity, DynamicBentNormalAO);
RenderLights(RHICmdList, SortedLightSet, HairDatas);
InjectAmbientCubemapTranslucentVolumeLighting();
FilterTranslucentVolumeLighting(RHICmdList, View, ViewIndex);
RenderDeferredReflectionsAndSkyLighting(RHICmdList, DynamicBentNormalAO, 


//渲染水体
RenderUnderWaterFog(RHICmdList, SingleLayerWaterPassData);
RenderSingleLayerWaterPass(RHICmdList, SingleLayerWaterPassData, WaterPassDepthStencilAccess, bDoParallelSingleLayerWater);
RenderSingleLayerWaterReflections(RHICmdList, SingleLayerWaterPassData);
//渲染光束
RenderLightShaftOcclusion(RHICmdList, LightShaftOutput);

//渲染大气
RenderAtmosphere(RHICmdList, LightShaftOutput);
RenderSkyAtmosphere(RHICmdList);

//渲染雾
RenderFog(RHICmdList, LightShaftOutput);
RendererModule.RenderPostOpaqueExtensions();

//通知特效系统已经渲染完了
Scene->FXSystem->PostRenderOpaque();
//GPU粒子渲染完的回调。
GPUSortManager->OnPostRenderOpaque(RHICmdList);

//渲染那些材质标识为透明的物体
RenderTranslucency(RHICmdList);

//渲染畸变
RenderDistortion(RHICmdList);
//渲染LightShaft
RenderLightShaftBloom(RHICmdList);

//渲染距离场AO
RenderDistanceFieldLighting(RHICmdList, FDistanceFieldAOParameters(OcclusionMaxDistance), SceneContext.SceneVelocity, DummyOutput, false, ViewFamily.EngineShowFlags.VisualizeDistanceFieldAO);

//执行默认的后处理,和自定义的后处理
FRDGBuilder GraphBuilder(RHICmdList);
AddDebugPostProcessingPasses(GraphBuilder, View, PostProcessingInputs);
AddPostProcessingPasses(GraphBuilder, View, PostProcessingInputs);
SceneContext.FreeSeparateTranslucency();
SceneContext.FreeSeparateTranslucencyModulate();
SceneContext.SetSceneColor(nullptr);
SceneContext.AdjustGBufferRefCount(GraphBuilder.RHICmdList, -1);
GraphBuilder.Execute();
//执行那些在默认后处理后面的自定义后处理材质
GRenderTargetPool.AddPhaseEvent(TEXT("AfterPostprocessing"));