原文链接:虚幻4渲染管线入门 - 知乎
从原文摘抄一下:
渲染框架
1,一套是传统的以RHICmdList为核心构建RenderPass,从RHICmdList.BeginRenderPass(...)开始,以RHICmdList.EndRenderPass()结束的框架。
2.一套是以新的GraphBuilder为核心来构建RenderGraph,通过GraphBuilder.AddPass(...),以回调的方式来设置每个渲染Pass的逻辑。
GraphBuilder使用的形式
RDG_GPU_MASK_SCOPE(GraphBuilder, View.GPUMask); RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, Views.Num() > 1, "View%d", ViewIndex); auto* PassParameters = GraphBuilder.AllocParameters<FDistortionPassParameters>(); PassParameters->Pass = CreateDistortionPassUniformBuffer(GraphBuilder, View); PassParameters->RenderTargets[0] = FRenderTargetBinding(DistortionTexture, LoadAction); PassParameters->RenderTargets.DepthStencil = StencilWriteBinding; GraphBuilder.AddPass( {}, PassParameters, ERDGPassFlags::Raster, [this, &View](FRHICommandListImmediate& RHICmdList) { QUICK_SCOPE_CYCLE_COUNTER(STAT_FSceneRender_RenderDistortion_Accumulate_Meshes); Scene->UniformBuffers.UpdateViewUniformBuffer(View); SetStereoViewport(RHICmdList, View); View.ParallelMeshDrawCommandPasses[EMeshPass::Distortion].DispatchDraw(nullptr, RHICmdList); });
原文链接:Unreal从0到1专栏概述 - 知乎
以下是笔记:
并行异步与渲染模块分析
一,虚幻的多线程Task系统
1,FRunable:标准多线程
2,AsyncTask:基于线程池的异步实现
它是对Runable进一步的封装,基于FQueuedThreadPool实现的异步任务系统,本质上是对IQueuedWork(任务队列)的实现
3,TaskGraph:任务图表系统
TaskGraph中工作线程是FWorkThread,它由两部分组成FRunnableThread* RunnableThread,FTaskThreadBase* TaskGraphWorker
TaskGraph通过FTaskGraphImplementation来创建和分配任务,这个类公有继承于FTaskGraphInterface【与FThreadManager类似,这才是任务分配的管理者,不过它也是个抽象类只负责提供接口,其功能具体实现是在FTaskGraphImplementation中完成的】
引擎初始化FTaskGraphImplementation会创建24个FWorkerThread,其中包括5个FNamedTaskThread:
- GameThread:游戏线程,也是虚幻引擎的主线程,向RenderThread发出CommondList
- ActualRenderingThread:渲染线程,也是本节重点关照的,向RHI发送CommondList
- RHIThread:RHI线程,向不同平台GPU发送指令
- AudioThread:AudioThread
- StatThread:StatThread
以及N个FTaskThreadAnyThread类型的Thread。其中StatThread与RenderingThread会在引擎初始化阶段执行FEngineLoop.PreInit时创建新的Runbale
TaskGraph系统要在引擎Prelnit阶段完成初始化,具体实现可以在LaunchEngineLoop.cpp中找到PreInitPreStartupScreen函数
二,UE4的多线程渲染
1,主要线程间通信
实现多线程渲染只要关注GameThread,RenderThread与RHIThread即可
游戏线程是主线程是发送命令的,渲染线程与RHI线程只是执行者
GameThread:戏线程通过某些接口向渲染线程的Queue入队回调接口,以便渲染线程稍后运行时从渲染线程的Queue获取回调,一个个地执行从而生成Command List。
RenderThread:分发执行渲染Task,向RHI线程发送commondList
RHIThread:接收渲染层的指令,发送给硬件执行