您当前的位置: 首页 > 

VT LI

暂无认证

  • 6浏览

    0关注

    126博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

ue5-lumen的场景数据更新与写入UpdateLumenScene

VT LI 发布时间:2022-02-28 21:15:04 ,浏览量:6

lumen在渲染的时候会走几个步骤:

第一是BeginUpdateLumenSceneTasks对场景的距离场体素重建

第二是UpdateLumenScene更新lumen的场景以及包括用nanite提出并且上传lumen的card

第三是RenderLumenSceneLighting获取lumen光照的直接光与间接光

第四是RenderLumenSceneVisualization可视化探针的获取与设置,体素步进与辐射度设置。

第五是RenderDiffuseIndirectAndAmbientOcclusion中对lumen的探针执行计算获取探针的光照来叠加。

通过Lumen::SetupViewUniformBufferParameters来设置uniform的数据。

数据拷贝到内存中

对lumen的card的渲染

对CardsToRender中的所有FCardRenderData对象都执行SubmitMeshDrawCommandsRange,提交到渲染指令中。这里的CardsToRender是经过BeginUpdateLumenSceneTasks过滤后的。其中的参数带有4张rt,包括lumen算出来的albedoatlas,normalatlas,emissiveatlas以及depthstencilatlas。

Nanite剔除

后面就用nanite来剔除,首先通过Nanite::InitRasterContext获取光栅化的上下文信息,以及通过Nanite::InitCullingContext获取剔除的上下文信息。

对视角或单视角剔除

然后根据是否是GLumenSceneNaniteMultiViewCapture来指定是多个view处理的还是单个view处理的。

然后组织成NaniteView来对所有CardsToRender进入Nanite::CullRasterize。如果是单view则对所有CardsToRender执行PackedView的Nanite::CullRasterize。

其中Nanite::CullRasterize中的NaniteInstanceDraws就是用nanite来渲染的对象。执行剔除。Nanite::CullRasterize,包括HZB,vsm剔除。

距离场剔除

紧接着会执行距离场的剔除,其中的参数Lumen::GetDistanceSceneNaniteLODScaleFactor()是2的

幂次。然后执行Nanite::CullRasterize对单独的PackedView做剔除。

CullRasterize相当的处理

这里的Nanite::CullRasterize需要的参数是场景,视野对象,剔除上下文,光栅化上下文,然后是光栅化状态(比如近裁剪面以及剔除方式是正面背面等)。

具体到CullRasterize中,如果视锥数量大于MAX_VIEWS_PER_CULL_RASTERIZE_PASS则要拆开另一个pass来剔除。

然后用FInitArgs_CS初始化cluster的剔除

用AddPass_InstanceHierarchyAndClusterCull来加入一个层级剔除和簇剔除。

Nanite关于lumen的渲染:

然后用Nanite::DrawLumenMeshCapturePass来渲染,执行到NaniteRender.cpp的DrawLumenMeshCapturePass。

首先设置参数FNaniteMarkStencilRectsParameters,然后执行到FPixelShaderUtils::AddRasterizeToRectsPass,在里面执行RHICmdList.DrawPrimitive,标记所有通过深度测试的像素的模板。

接着设置参数FNaniteEmitMaterialIdRectsParameters,然后执行FPixelShaderUtils::AddRasterizeToRectsPass,用RHICmdList.DrawPrimitive绘制信息,这里是用深度信息获取材质信息。

然后设置参数到FNaniteEmitGBufferParameters,包括簇信息,albedo,normal,emissive,并设置uniform数据到FNaniteUniformParameters,利用const_cast(Scene).UniformBuffers.NaniteUniformBuffer.UpdateUniformBufferImmediate,也就是nanite的uniform数据设置。

两种模式提交渲染

然后有两种模式,一个是有距离场的模式,一个是执行列表模式。

距离场模式:

有距离场的模式通过BuildNaniteMaterialPassCommands获取到NaniteMaterialPassCommands关于nanite的材质的pass。对每个pass进行提交SubmitNaniteMaterialPassCommand。这里的

这里的SubmitNaniteMaterialPassCommand是执行到NaniteRender的SubmitNaniteMaterialPassCommand,也是通过FMeshDrawCommand::SubmitDrawBegin和FMeshDrawCommand::SubmitDrawEnd去执行到具体平台的draw指令。

nanite执行列表模式

如果不是距离场的模式,则遍历CardRenderData.NaniteCommandInfos然后拿到里面的id,通过Scene.NaniteDrawCommands[ENaniteMeshPass::LumenCardCapture]获取到FMeshDrawCommand,然后用SubmitNaniteMaterialPassCommand来执行MeshDrawCommand的draw。

再次获取深度信息:

最后他还再执行一次深度值的获取,这里主要是如果有修改能第一时间写入。

上传lumen的buffer

然后用FLumenCardIdUpload上传lumen的card。这里是对几个IBuffer的上传,包括有CardsToRenderIndexBuffer,CardsToRenderHashMapBuffer,VisibleCardsIndexBuffer。

这里的上传的核心是地址拷贝,FPlatformMemory::Memcpy(DestCardIdPtr, CardIdPtr, CardIdBytes);这里的目标地址是是RHI的一个buffer。

过滤lumen的深度:

然后执行完上传后还会过滤一遍深度。PrefilterLumenSceneDepth。这里是执行到FDeferredShadingSceneRenderer::PrefilterLumenSceneDepth。

首先初始化CardScatterContext的变量。

然后执行FLumenCardScatterContext::CullCardsToShape,主要是执行FCullCardsToShapeCS这个computeshader,也就执行LumenSceneLighting.usf的CullCardsToShapeCS。主要过滤的方式是card是否可见,card是否受到灯光范围影响以及card是否在可视范围内。

然后就是BuildScatterIndirectArgs,也就是跟RenderLumenSceneLighting的BuildScatterIndirectArgs的间接光参数初始化一样。

然后FLumenCardCopyDepth执行lumencard的深度拷贝。主要是执行LumenSceneLighting.usf的LumenCardPrefilterLightingPS通过mrt执行三个颜色的赋值,OutLighting,OutColor1,OutColor2。分别是父级光照信息,直接辐照度颜色,间接辐照度颜色。

关注
打赏
1649603425
查看更多评论
立即登录/注册

微信扫码登录

3.5383s