--- title: 未命名 date: 2024-05-10 16:30:16 excerpt: tags: rating: ⭐ --- PostProcesss ```c++ void AddPostProcessingPasses( FRDGBuilder& GraphBuilder, const FViewInfo& View, int32 ViewIndex, FSceneUniformBuffer& SceneUniformBuffer, bool bAnyLumenActive, bool bLumenGIEnabled, EReflectionsMethod ReflectionsMethod, const FPostProcessingInputs& Inputs, const Nanite::FRasterResults* NaniteRasterResults, FInstanceCullingManager& InstanceCullingManager, FVirtualShadowMapArray* VirtualShadowMapArray, FLumenSceneFrameTemporaries& LumenFrameTemporaries, const FSceneWithoutWaterTextures& SceneWithoutWaterTextures, FScreenPassTexture TSRMoireInput) { RDG_CSV_STAT_EXCLUSIVE_SCOPE(GraphBuilder, RenderPostProcessing); QUICK_SCOPE_CYCLE_COUNTER(STAT_PostProcessing_Process); check(IsInRenderingThread()); check(View.VerifyMembersChecks()); Inputs.Validate(); FScene* Scene = View.Family->Scene->GetRenderScene(); const FIntRect PrimaryViewRect = View.ViewRect; const FSceneTextureParameters SceneTextureParameters = GetSceneTextureParameters(GraphBuilder, Inputs.SceneTextures); const FScreenPassRenderTarget ViewFamilyOutput = FScreenPassRenderTarget::CreateViewFamilyOutput(Inputs.ViewFamilyTexture, View); const FScreenPassTexture SceneDepth(SceneTextureParameters.SceneDepthTexture, PrimaryViewRect); const FScreenPassTexture CustomDepth(Inputs.CustomDepthTexture, PrimaryViewRect); const FScreenPassTexture Velocity(SceneTextureParameters.GBufferVelocityTexture, PrimaryViewRect); const FScreenPassTexture BlackDummy(GSystemTextures.GetBlackDummy(GraphBuilder)); const FTranslucencyPassResources& PostDOFTranslucencyResources = Inputs.TranslucencyViewResourcesMap.Get(ETranslucencyPass::TPT_TranslucencyAfterDOF); const FTranslucencyPassResources& PostMotionBlurTranslucencyResources = Inputs.TranslucencyViewResourcesMap.Get(ETranslucencyPass::TPT_TranslucencyAfterMotionBlur); ``` # BasePass ```c++ #if WITH_EDITOR if (ViewFamily.EngineShowFlags.Wireframe) { checkf(ExclusiveDepthStencil.IsDepthWrite(), TEXT("Wireframe base pass requires depth-write, but it is set to read-only.")); BasePassTextureCount = 1; BasePassTextures[0] = SceneTextures.EditorPrimitiveColor; BasePassTexturesView = MakeArrayView(BasePassTextures.GetData(), BasePassTextureCount); BasePassDepthTexture = SceneTextures.EditorPrimitiveDepth; auto* PassParameters = GraphBuilder.AllocParameters(); PassParameters->RenderTargets = GetRenderTargetBindings(ERenderTargetLoadAction::EClear, BasePassTexturesView); PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(BasePassDepthTexture, ERenderTargetLoadAction::EClear, ERenderTargetLoadAction::EClear, ExclusiveDepthStencil); GraphBuilder.AddPass(RDG_EVENT_NAME("WireframeClear"), PassParameters, ERDGPassFlags::Raster, [](FRHICommandList&) {}); } #endif // Render targets bindings should remain constant at this point. FRenderTargetBindingSlots BasePassRenderTargets = GetRenderTargetBindings(ERenderTargetLoadAction::ELoad, BasePassTexturesView); BasePassRenderTargets.DepthStencil = FDepthStencilBinding(BasePassDepthTexture, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, ExclusiveDepthStencil); FForwardBasePassTextures ForwardBasePassTextures{}; if (bForwardShadingEnabled) { ForwardBasePassTextures.SceneDepthIfResolved = SceneTextures.Depth.IsSeparate() ? SceneTextures.Depth.Resolve : nullptr; ForwardBasePassTextures.ScreenSpaceAO = SceneTextures.ScreenSpaceAO; ForwardBasePassTextures.ScreenSpaceShadowMask = ForwardShadowMaskTexture; } else if (!ExclusiveDepthStencil.IsDepthWrite()) { // If depth write is not enabled, we can bound the depth texture as read only ForwardBasePassTextures.SceneDepthIfResolved = SceneTextures.Depth.Resolve; } ForwardBasePassTextures.bIs24BitUnormDepthStencil = ForwardBasePassTextures.SceneDepthIfResolved ? GPixelFormats[ForwardBasePassTextures.SceneDepthIfResolved->Desc.Format].bIs24BitUnormDepthStencil : 1; GraphBuilder.SetCommandListStat(GET_STATID(STAT_CLM_BasePass)); RenderBasePassInternal(GraphBuilder, SceneTextures, BasePassRenderTargets, BasePassDepthStencilAccess, ForwardBasePassTextures, DBufferTextures, bDoParallelBasePass, bRenderLightmapDensity, InstanceCullingManager, bNaniteEnabled, NaniteRasterResults); GraphBuilder.SetCommandListStat(GET_STATID(STAT_CLM_AfterBasePass)); FRenderTargetBindingSlots BasePassRenderTargets = GetRenderTargetBindings(ERenderTargetLoadAction::ELoad, BasePassTexturesView); BasePassRenderTargets.DepthStencil = FDepthStencilBinding(BasePassDepthTexture, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, ExclusiveDepthStencil); RenderBasePassInternal(GraphBuilder, SceneTextures, BasePassRenderTargets, BasePassDepthStencilAccess, ForwardBasePassTextures, DBufferTextures, bDoParallelBasePass, bRenderLightmapDensity, InstanceCullingManager, bNaniteEnabled, NaniteRasterResults); ``` ## 读取GBufferTexture 位于SceneRendering.h ```c++ FORCEINLINE FSceneTextures& GetActiveSceneTextures() { return ViewFamily.GetSceneTextures(); } ``` 考虑使用形参 - const FSceneTextures* SceneTextures - const FSceneTextures& SceneTextures - FSceneTextures& SceneTextures # UE5.4的FScreenTransform计算 参考:VisualizeMotionVectors.cpp - FScreenTransform::SvPositionToViewportUV(Output.ViewRect):**SvPosition => ViewportUV** - `FScreenTransform SvPositionToViewportUV = FScreenTransform::SvPositionToViewportUV(Output.ViewRect);` - FScreenTransform::ViewportUVToScreenPos():**ViewportUV => ScreenPos** - FScreenTransform::ChangeTextureBasisFromTo():坐标转换。比如下面的坐标是**ViewportUV => TextureUV** - ```FScreenTransform::ChangeTextureBasisFromTo(Inputs.SceneColor, FScreenTransform::ETextureBasis::ViewportUV, FScreenTransform::ETextureBasis::TextureUV);``` - **SvPosition => ScreenPos**:SvPositionToViewportUV * FScreenTransform::ViewportUVToScreenPos 这是用于重采样后2个RT大小不一样而进行的计算。 # OutlinePass ## 距离对于后处理深度描边的关系 需要针对极近距离进行处理。 - 最大深度采样值的最小值为100 | 距离 | 最小深度采样 | 最大深度采样 | | :-----: | :----: | :----: | | 100cm | 1 | 10 | | 200cm | 2 | 20 | | 500cm | 5 | 50 | | 1000cm | | 100 | | 2000cm | | | | 5000cm | | | | 10000cm | | | # 问题记录 ## 处于FarDepthValue的Outline被裁剪的问题 - SkyAtmosphere.usf中,会将天空球渲染在深度为FarDepthValue的像素上,这样会将一些Outline覆盖掉。 - HeightFogPixelShader.usf中,会通过判断**DeviceZ != 0.0** 来调整渲染结果,绘制方式PSO.BlendState = TStaticBlendState::GetRHI();