ue5-Nanite运行时数据获取

nanite的执行起始:

VisBuffer64是可视信息的纹理对象,在NaniteRender.cpp中的FRasterContext InitRasterContext,这里对RasterContext的对象初始化,其中的VisBuffer64就在这里创建的纹理。

LumenSceneRendering的nanite阶段会初始化。

除了lumen的处理,在FDeferredShadingSceneRenderer::Render在开启了nanite后也会初始化

FDeferredShadingSceneRenderer::RenderHitProxies也在开启了nanite后处理,但是是在editor下开启的

在ShadowDepthRendering.cpp中RenderShadowDepthAtlasNanite也会在开启了nanite后初始化

RenderShadowDepthAtlasNanite是在FDeferredShadingSceneRenderer::Render的bOcclusionBeforeBasePass时执行RenderShadowDepthMaps时处理的。但是他不支持开启Hierarchical Z-Buffering分层Z缓冲(HZB)

nanite剔除处理:

Nanite的FDeferredShadingSceneRenderer::Render处理流程

Nanite::CullRasterize

实例剔除:

这里执行FCompactViewsVSM_CS的computehader,/Engine/Private/Nanite/InstanceCulling.usf,执行CompactViewsVSM_CS内核,这里主要是比较所有mipmap看有哪些PageRectBounds是没被遮挡的。

这里比较的是他的宽高和xy,如果宽高大于xy则说明不能被裁剪。

初始化:

然后执行FInitArgs_CS到/Engine/Private/Nanite/NaniteClusterCulling.usf的InitArgs,初始化clusterculling的信息。

几何体剔除:

AddPass_PrimitiveFilter,执行FPrimitiveFilter_CS的computeshader,执行到"/Engine/Private/Nanite/NanitePrimitiveFilter.usf"的"PrimitiveFilter"。这里主要对隐藏的对象做过滤。

视野裁剪:

然后执行AddPass_InstanceHierarchyAndClusterCull,如果有虚拟阴影则执行FInstanceCullVSM_CS,到"/Engine/Private/Nanite/NaniteInstanceCulling.usf"的"InstanceCullVSM"。

如果没有虚拟阴影则执行FInstanceCull_CS执行到"/Engine/Private/Nanite/NaniteInstanceCulling.usf"的"InstanceCull"。主要是执行BoxCullFrustum执行到NaniteHZBCull.ush的BoxCullFrustum做裁剪。分正交与透视视角,BoxCullFrustumOrthoNoClip和BoxCullFrustumGeneral。

节点剔除与簇剔除:

然后AddPass_InstanceHierarchyAndClusterCull执行FPersistentClusterCull_CS,执行到"/Engine/Private/Nanite/NaniteClusterCulling.usf"的"PersistentClusterCull"。

首先会执行NodeCull,在nodecull里面会拿出NodeData,然后解压字节为CandidateNode,通过andidateNode.InstanceId拿到FInstanceSceneData,通过FInstanceSceneData拿到FInstanceDynamicData。然后查看可见性

如果可见则通过BoxCullFrustum和GetScreenRect来判断是否在范围内。

HZB剔除:

如果NaniteView开启了HZB也就是多Mip层级的z-buffer剔除方案并且可见则核心查看IsVisibleHZB也就是是否通过层级被剔除掉

可以在NaniteHZBCull.ush中的IsVisibleHZB看到他的实现方案。

光栅化:

AddPass_Rasterize

首先会执行FHWRasterizePS,然后如果有用meshshader则执行FHWRasterizeMS。如果不用meshshader则用FHWRasterizeVS。是关于硬件光栅化。FHWRasterizeMS和FHWRasterizeVS都是做顶点处理,然后FHWRasterizePS对渲染做插值得到颜色信息。

然后执行FMicropolyRasterizeCS是执行软件光栅化,执行/Engine/Private/Nanite/NaniteRasterizer.usf"的"MicropolyRasterize"

材质、深度、速度、模板等信息保存:

FDeferredShadingSceneRenderer::Render中执行

Nanite::EmitDepthTargets,执行到NaniteMaterials.cpp的EmitDepthTargets。如果需要计算导出深度的话则执行FDepthExportCS,执行到"/Engine/Private/Nanite/NaniteDepthExport.usf"的"DepthExport"。这里主要输出场景的速度贴图,材质信息

如果不能走深度导出的话则首先判断如果支持模板标记则执行FEmitSceneDepthStencilPS("/Engine/Private/Nanite/NaniteExportGBuffer.usf"的"EmitSceneDepthStencilPS")或输出速度,深度,材质,模板信息。

如果不支持模板标记则执行FEmitSceneDepthPS("/Engine/Private/Nanite/NaniteExportGBuffer.usf"的"EmitSceneDepthPS")输出速度,深度。然后通过FEmitSceneStencilPS("/Engine/Private/Nanite/NaniteExportGBuffer.usf"的"EmitSceneStencilPS")更改深度信息。

最后执行FEmitMaterialDepthPS("/Engine/Private/Nanite/NaniteExportGBuffer.usf"的"EmitMaterialDepthPS")输出材质,深度信息。

最近与最远的层级深度信息获取:

接下来是SceneTextureReductions.cpp的BuildHZBFurthest,然后执行BuildHZB,首先他会将FurthestHZBTextureClosestHZBTexture的HZB故意位于单独的渲染目标中,因为在大多数情况下,只能选择其中一个。将它们分开,避免在这种情况下将缓存中的大小加倍,以避免性能下降。然后执行ReduceMips,里面的话是如果能执行computeshader则执行FHZBBuildCS("/Engine/Private/HZB.usf"的"HZBBuildCS")这里面主要是对所有mipmap执行四个像素找最大和最小深度值,因为ParentTextureMip是c++中传过来的SceneDepth

如果不用computeshader则用ps来输出FHZBBuildPS("/Engine/Private/HZB.usf", "HZBBuildPS")

上面是都i当前的最近和最远深度获取。然后下面就对其他mipmap获取相同的hzb的构建信息。

组织nanite光栅化数据:

Nanite::ExtractResults,这里主要是组织结果到数据结构FRasterResults中。

Nanite::AddVisualizationPasses,这个是nanite的可视化信息显示。

Nanite::GStreamingManager.SubmitFrameStreamingRequests,这里是提交这一帧的nanite的流数据。

猜你喜欢

转载自blog.csdn.net/llsansun/article/details/124215840