diff --git a/01-Diary/周小结/2024.12.md b/01-Diary/周小结/2024.12.md index 0f9b3fe..8ff4311 100644 --- a/01-Diary/周小结/2024.12.md +++ b/01-Diary/周小结/2024.12.md @@ -23,4 +23,5 @@ # 12.16~12.20 - [x] 帮助朱雨辰解决: - [x] 4周年角色不能完全变黑问题。 - - [x] 渲片时的天空球问题切换天空盒问题。 \ No newline at end of file + - [x] 渲片时的天空球问题切换天空盒问题。 +- [ ] \ No newline at end of file diff --git a/03-UnrealEngine/Rendering/RenderingPipeline/Materials&MeshDraw/MeshDraw.md b/03-UnrealEngine/Rendering/RenderingPipeline/Materials&MeshDraw/MeshDraw.md index c207db8..9f3fd78 100644 --- a/03-UnrealEngine/Rendering/RenderingPipeline/Materials&MeshDraw/MeshDraw.md +++ b/03-UnrealEngine/Rendering/RenderingPipeline/Materials&MeshDraw/MeshDraw.md @@ -21,11 +21,6 @@ Shader推荐: - DepthOnlyVertexShader.usf - DepthOnlyPixelShader.usf -# NaniteMeshDraw -`Engine\Source\Runtime\Renderer\Private\Nanite\`NaniteMaterials.h & NaniteMaterials.cpp - -PS.使用的Shader必须是`FNaniteGlobalShader`的子类。 - ## BasePass ### DrawBasePass() 该函数在FDeferredShadingSceneRenderer::RenderBasePassInternal()中调用。 @@ -255,4 +250,147 @@ FViewInfo& ViewInfo - DECLARE_GPU_STAT_NAMED_EXTERN(NaniteBasePass, TEXT("Nanite BasePass")); - GET_STATID(STAT_CLP_BasePass) - FRDGParallelCommandListSet ParallelCommandListSet(InPass, RHICmdList, GET_STATID(STAT_CLP_BasePass), View, FParallelCommandListBindings(PassParameters)); - - DECLARE_CYCLE_STAT(TEXT("BasePass"), STAT_CLP_BasePass, STATGROUP_ParallelCommandListMarkers); \ No newline at end of file + - DECLARE_CYCLE_STAT(TEXT("BasePass"), STAT_CLP_BasePass, STATGROUP_ParallelCommandListMarkers); + +# NaniteMeshDraw +`Engine\Source\Runtime\Renderer\Private\Nanite\`NaniteMaterials.h & NaniteMaterials.cpp + +PS.使用的Shader必须是`FNaniteGlobalShader`的子类。 + +以下是Nanite物体的CustomDepth绘制过程: +```c++ +bool FSceneRenderer::RenderCustomDepthPass( + FRDGBuilder& GraphBuilder, + FCustomDepthTextures& CustomDepthTextures, + const FSceneTextureShaderParameters& SceneTextures, + TConstArrayView PrimaryNaniteRasterResults, + TConstArrayView PrimaryNaniteViews) +{ + if (!CustomDepthTextures.IsValid()) + { + return false; + } + + // Determine if any of the views have custom depth and if any of them have Nanite that is rendering custom depth + bool bAnyCustomDepth = false; + TArray NaniteDrawLists; + NaniteDrawLists.AddDefaulted(Views.Num()); + uint32 TotalNaniteInstances = 0; + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex) + { + FViewInfo& View = Views[ViewIndex]; + if (View.ShouldRenderView() && View.bHasCustomDepthPrimitives) + { + if (PrimaryNaniteRasterResults.IsValidIndex(ViewIndex)) + { + const FNaniteVisibilityResults& VisibilityResults = PrimaryNaniteRasterResults[ViewIndex].VisibilityResults; + + // Get the Nanite instance draw list for this view. (NOTE: Always use view index 0 for now because we're not doing + // multi-view yet). + NaniteDrawLists[ViewIndex] = BuildNaniteCustomDepthDrawList(View, 0u, VisibilityResults); + + TotalNaniteInstances += NaniteDrawLists[ViewIndex].Num(); + } + bAnyCustomDepth = true; + } + } + + SET_DWORD_STAT(STAT_NaniteCustomDepthInstances, TotalNaniteInstances); +.. + if (TotalNaniteInstances > 0) + { + RDG_EVENT_SCOPE(GraphBuilder, "Nanite CustomDepth"); + + const FIntPoint RasterTextureSize = CustomDepthTextures.Depth->Desc.Extent; + FIntRect RasterTextureRect(0, 0, RasterTextureSize.X, RasterTextureSize.Y); + if (Views.Num() == 1) + { + const FViewInfo& View = Views[0]; + if (View.ViewRect.Min.X == 0 && View.ViewRect.Min.Y == 0) + { + RasterTextureRect = View.ViewRect; + } + } + + const bool bWriteCustomStencil = IsCustomDepthPassWritingStencil(); + + Nanite::FSharedContext SharedContext{}; + SharedContext.FeatureLevel = Scene->GetFeatureLevel(); + SharedContext.ShaderMap = GetGlobalShaderMap(SharedContext.FeatureLevel); + SharedContext.Pipeline = Nanite::EPipeline::Primary; + + // TODO: If !bWriteCustomStencil, we could copy off the depth and rasterize depth-only (probable optimization) + Nanite::FRasterContext RasterContext = Nanite::InitRasterContext( + GraphBuilder, + SharedContext, + ViewFamily, + RasterTextureSize, + RasterTextureRect, + false, // bVisualize + Nanite::EOutputBufferMode::VisBuffer, + true, // bClearTarget + nullptr, // RectMinMaxBufferSRV + 0, // NumRects + nullptr, // ExternalDepthBuffer + true // bCustomPass + ); + + Nanite::FCustomDepthContext CustomDepthContext = Nanite::InitCustomDepthStencilContext( + GraphBuilder, + CustomDepthTextures, + bWriteCustomStencil); + + Nanite::FConfiguration CullingConfig = { 0 }; + CullingConfig.bUpdateStreaming = true; + + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex) + { + RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, Views.Num() > 1, "View%d", ViewIndex); + + FViewInfo& View = Views[ViewIndex]; + + if (!View.ShouldRenderView() || NaniteDrawLists[ViewIndex].Num() == 0) + { + continue; + } + + auto NaniteRenderer = Nanite::IRenderer::Create( + GraphBuilder, + *Scene, + View, + GetSceneUniforms(), + SharedContext, + RasterContext, + CullingConfig, + View.ViewRect, + /* PrevHZB = */ nullptr + ); + + NaniteRenderer->DrawGeometry( + Scene->NaniteRasterPipelines[ENaniteMeshPass::BasePass], + PrimaryNaniteRasterResults[ViewIndex].VisibilityResults, + *Nanite::FPackedViewArray::Create(GraphBuilder, PrimaryNaniteViews[ViewIndex]), + NaniteDrawLists[ViewIndex] + ); + + Nanite::FRasterResults RasterResults; + NaniteRenderer->ExtractResults( RasterResults ); + + // Emit depth + Nanite::EmitCustomDepthStencilTargets( + GraphBuilder, + *Scene, + View, + RasterResults.PageConstants, + RasterResults.VisibleClustersSWHW, + RasterResults.ViewsBuffer, + RasterContext.VisBuffer64, + CustomDepthContext + ); + } + + Nanite::FinalizeCustomDepthStencil(GraphBuilder, CustomDepthContext, CustomDepthTextures); + } +... +} +```