diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md index 1e00e20..f645b36 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md @@ -218,7 +218,174 @@ void FSceneRenderer::InitDynamicShadows(FRHICommandListImmediate& RHICmdList, FG - **FProjectedShadowInfo::RenderTranslucencyDepths** ## RenderDepth -FShadowParallelCommandListSet +MeshDrawProcessor为***FShadowDepthPassMeshProcessor***。渲染的Shader为ShadowDepthPixelShader.usf +```c++ +void FProjectedShadowInfo::RenderDepth( + FRDGBuilder& GraphBuilder, + const FSceneRenderer* SceneRenderer, + FRDGTextureRef ShadowDepthTexture, + bool bDoParallelDispatch, + bool bDoCrossGPUCopy) +{ +#if WANTS_DRAW_MESH_EVENTS + FString EventName; + + if (GetEmitDrawEvents()) + { + GetShadowTypeNameForDrawEvent(EventName); + EventName += FString(TEXT(" ")) + FString::FromInt(ResolutionX) + TEXT("x") + FString::FromInt(ResolutionY); + } + + RDG_EVENT_SCOPE(GraphBuilder, "%s", *EventName); +#endif + + CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_RenderWholeSceneShadowDepthsTime, bWholeSceneShadow); + CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_RenderPerObjectShadowDepthsTime, !bWholeSceneShadow); + QUICK_SCOPE_CYCLE_COUNTER(STAT_RenderShadowDepth); + + FScene* Scene = SceneRenderer->Scene; + const ERHIFeatureLevel::Type FeatureLevel = ShadowDepthView->FeatureLevel; + BeginRenderView(GraphBuilder, Scene); + + FShadowDepthPassParameters* PassParameters = GraphBuilder.AllocParameters(); + PassParameters->View = ShadowDepthView->ViewUniformBuffer; + PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding( + ShadowDepthTexture, + ERenderTargetLoadAction::ELoad, + ERenderTargetLoadAction::ENoAction, + FExclusiveDepthStencil::DepthWrite_StencilNop); + + if (CacheMode == SDCM_MovablePrimitivesOnly || CacheMode == SDCM_CSMScrolling) + { + // Copy in depths of static primitives before we render movable primitives. + FMeshPassProcessorRenderState DrawRenderState; + SetStateForShadowDepth(bOnePassPointLightShadow, bDirectionalLight, DrawRenderState, MeshPassTargetType); + CopyCachedShadowMap(GraphBuilder, *ShadowDepthView, SceneRenderer, PassParameters->RenderTargets, DrawRenderState); + } + + PassParameters->VirtualShadowMap = SceneRenderer->VirtualShadowMapArray.GetUniformBuffer(); + + switch (FSceneInterface::GetShadingPath(FeatureLevel)) + { + case EShadingPath::Deferred: + { + auto* ShadowDepthPassParameters = GraphBuilder.AllocParameters(); + SetupShadowDepthPassUniformBuffer(this, GraphBuilder, *ShadowDepthView, *ShadowDepthPassParameters);//设置矩阵、Shader等相关ShadowDepthPassParameters参数 + PassParameters->DeferredPassUniformBuffer = GraphBuilder.CreateUniformBuffer(ShadowDepthPassParameters); + } + break; + case EShadingPath::Mobile: + { + auto* ShadowDepthPassParameters = GraphBuilder.AllocParameters(); + SetupShadowDepthPassUniformBuffer(this, GraphBuilder, *ShadowDepthView, *ShadowDepthPassParameters);//设置矩阵、Shader等相关ShadowDepthPassParameters参数 + PassParameters->MobilePassUniformBuffer = GraphBuilder.CreateUniformBuffer(ShadowDepthPassParameters); + } + break; + default: + checkNoEntry(); + } + + ShadowDepthPass.BuildRenderingCommands(GraphBuilder, Scene->GPUScene, PassParameters->InstanceCullingDrawParams); + +#if WITH_MGPU + // Need to fetch GPU mask outside "AddPass", as it's not updated during pass execution + FRHIGPUMask GPUMask = GraphBuilder.RHICmdList.GetGPUMask(); +#endif + + if (bDoParallelDispatch) + { + RDG_WAIT_FOR_TASKS_CONDITIONAL(GraphBuilder, IsShadowDepthPassWaitForTasksEnabled()); + + GraphBuilder.AddPass( + RDG_EVENT_NAME("ShadowDepthPassParallel"), + PassParameters, + ERDGPassFlags::Raster | ERDGPassFlags::SkipRenderPass, + [this, PassParameters +#if WITH_MGPU + , ShadowDepthTexture, GPUMask, bDoCrossGPUCopy +#endif + ](const FRDGPass* InPass, FRHICommandListImmediate& RHICmdList) + { + FShadowParallelCommandListSet ParallelCommandListSet(InPass, RHICmdList, *ShadowDepthView, *this, FParallelCommandListBindings(PassParameters)); + ShadowDepthPass.DispatchDraw(&ParallelCommandListSet, RHICmdList, &PassParameters->InstanceCullingDrawParams); + +#if WITH_MGPU + if (bDoCrossGPUCopy) + { + CopyCachedShadowMapCrossGPU(RHICmdList, ShadowDepthTexture->GetRHI(), GPUMask); + } +#endif + }); + } + else + { + GraphBuilder.AddPass( + RDG_EVENT_NAME("ShadowDepthPass"), + PassParameters, + ERDGPassFlags::Raster, + [this, PassParameters +#if WITH_MGPU + , ShadowDepthTexture, GPUMask, bDoCrossGPUCopy +#endif + ](FRHICommandList& RHICmdList) + { + SetStateForView(RHICmdList); + ShadowDepthPass.DispatchDraw(nullptr, RHICmdList, &PassParameters->InstanceCullingDrawParams); + +#if WITH_MGPU + if (bDoCrossGPUCopy) + { + CopyCachedShadowMapCrossGPU(RHICmdList, ShadowDepthTexture->GetRHI(), GPUMask); + } +#endif + }); + } +} +``` + +```c++ +void SetupShadowDepthPassUniformBuffer( + const FProjectedShadowInfo* ShadowInfo, + FRDGBuilder& GraphBuilder, + const FViewInfo& View, + FShadowDepthPassUniformParameters& ShadowDepthPassParameters) +{ + static const auto CSMCachingCVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Shadow.CSMCaching")); + const bool bCSMCachingEnabled = CSMCachingCVar && CSMCachingCVar->GetValueOnAnyThread() != 0; + + SetupSceneTextureUniformParameters(GraphBuilder, View.GetSceneTexturesChecked(), View.FeatureLevel, ESceneTextureSetupMode::None, ShadowDepthPassParameters.SceneTextures);//设置对应的RT与Texture + + ShadowDepthPassParameters.ProjectionMatrix = FTranslationMatrix44f(FVector3f(ShadowInfo->PreShadowTranslation - View.ViewMatrices.GetPreViewTranslation())) * ShadowInfo->TranslatedWorldToClipOuterMatrix; // LWC_TDOO: Precision loss? + ShadowDepthPassParameters.ViewMatrix = FMatrix44f(ShadowInfo->TranslatedWorldToView); // LWC_TODO: Precision loss + + // Disable the SlopeDepthBias because we couldn't reconstruct the depth offset if it is not 0.0f when scrolling the cached shadow map. + ShadowDepthPassParameters.ShadowParams = FVector4f(ShadowInfo->GetShaderDepthBias(), bCSMCachingEnabled ? 0.0f : ShadowInfo->GetShaderSlopeDepthBias(), ShadowInfo->GetShaderMaxSlopeDepthBias(), ShadowInfo->bOnePassPointLightShadow ? 1 : ShadowInfo->InvMaxSubjectDepth); + ShadowDepthPassParameters.bClampToNearPlane = ShadowInfo->ShouldClampToNearPlane() ? 1.0f : 0.0f; + + if (ShadowInfo->bOnePassPointLightShadow) + { + check(ShadowInfo->BorderSize == 0); + + // offset from translated world space to (pre translated) shadow space + const FMatrix Translation = FTranslationMatrix(ShadowInfo->PreShadowTranslation - View.ViewMatrices.GetPreViewTranslation()); + + for (int32 FaceIndex = 0; FaceIndex < 6; FaceIndex++) + { + ShadowDepthPassParameters.ShadowViewProjectionMatrices[FaceIndex] = FMatrix44f(Translation * ShadowInfo->OnePassShadowViewProjectionMatrices[FaceIndex]); // LWC_TODO: Precision loss? + ShadowDepthPassParameters.ShadowViewMatrices[FaceIndex] = FMatrix44f(Translation * ShadowInfo->OnePassShadowViewMatrices[FaceIndex]); + } + } + + ShadowDepthPassParameters.bRenderToVirtualShadowMap = false; + ShadowDepthPassParameters.VirtualSmPageTable = GraphBuilder.CreateSRV(GSystemTextures.GetDefaultStructuredBuffer(GraphBuilder, sizeof(uint32))); + ShadowDepthPassParameters.PackedNaniteViews = GraphBuilder.CreateSRV(GSystemTextures.GetDefaultStructuredBuffer(GraphBuilder, sizeof(Nanite::FPackedView))); + ShadowDepthPassParameters.PageRectBounds = GraphBuilder.CreateSRV(GSystemTextures.GetDefaultStructuredBuffer(GraphBuilder, sizeof(FIntVector4))); + + FRDGTextureRef DepthBufferArray = GraphBuilder.CreateTexture( FRDGTextureDesc::Create2DArray( FIntPoint(4,4), PF_R32_UINT, FClearValueBinding::None, TexCreate_ShaderResource | TexCreate_UAV, 1 ), TEXT("Dummy-OutDepthBuffer") ); + + ShadowDepthPassParameters.OutDepthBufferArray = GraphBuilder.CreateUAV( DepthBufferArray ); +} +``` # Lights ### Shader