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,首先他会将FurthestHZBTexture和ClosestHZBTexture的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的流数据。