ue 添加後處理

1. shader 類

 2.pass 類

class FPostProcessmgTestVS_ES2 : public FGlobalShader
{
    DECLARE_SHADER_TYPE(FPostProcessmgTestVS_ES2, Global);

    static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
    {
        return !IsConsolePlatform(Parameters.Platform);
    }

    /** Default constructor. */
    FPostProcessmgTestVS_ES2() {}

public:
    LAYOUT_FIELD(FPostProcessPassParameters, PostprocessParameter);

    /** Initialization constructor. */
    FPostProcessmgTestVS_ES2(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
        : FGlobalShader(Initializer)
    {
        PostprocessParameter.Bind(Initializer.ParameterMap);
    }

    void SetVS(const FRenderingCompositePassContext& Context)
    {
        FRHIVertexShader* ShaderRHI = Context.RHICmdList.GetBoundVertexShader();

        FGlobalShader::SetParameters<FViewUniformShaderParameters>(Context.RHICmdList, ShaderRHI, Context.View.ViewUniformBuffer);

        PostprocessParameter.SetVS(ShaderRHI, Context, TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI());
    }
};

IMPLEMENT_SHADER_TYPE(, FPostProcessmgTestVS_ES2, TEXT("/Engine/Private/mgTestShader.usf"), TEXT("mgTestVS"), SF_Vertex);

//////
class FPostProcessmgTestPS_ES2 : public FGlobalShader
{
public:
    DECLARE_GLOBAL_SHADER(FPostProcessmgTestPS_ES2);
    SHADER_USE_PARAMETER_STRUCT(FPostProcessmgTestPS_ES2, FGlobalShader);


    BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
        SHADER_PARAMETER_TEXTURE(Texture2D, InputTexture)
        SHADER_PARAMETER_SAMPLER(SamplerState, InputSampler)
        END_SHADER_PARAMETER_STRUCT()

        static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
    {
        return true;
    }

public:

    void SetPS(const FRenderingCompositePassContext& Context, const TShaderRef<FPostProcessmgTestPS_ES2>& Shader, FRHITexture* PostprocessInput0, FRHITexture* PostprocessInput1)
    {
        FRHIPixelShader* ShaderRHI = Context.RHICmdList.GetBoundPixelShader();

        const FPostProcessSettings& Settings = Context.View.FinalPostProcessSettings;

        FParameters ShaderParameters;
        ShaderParameters.InputTexture = PostprocessInput0;
        ShaderParameters.InputSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
        SetShaderParameters(Context.RHICmdList, Shader, ShaderRHI, ShaderParameters);
    }
};

IMPLEMENT_GLOBAL_SHADER(FPostProcessmgTestPS_ES2, "/Engine/Private/mgTestShader.usf", "mgTestPS", SF_Pixel);


void FRCPassPostProcessmgTestES2::Process(FRenderingCompositePassContext& Context)
{
    SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessMgtest);

    const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);
    FIntPoint PrePostSourceViewportSize = PrePostSourceViewportRect.Size();

    uint32 DstX = PrePostSourceViewportSize.X;//FMath::DivideAndRoundUp(PrePostSourceViewportSize.X, 4);
    uint32 DstY = PrePostSourceViewportSize.Y;// FMath::DivideAndRoundUp(PrePostSourceViewportSize.Y, 4);

    FIntRect DstRect;
    DstRect.Min.X = 0;
    DstRect.Min.Y = 0;
    DstRect.Max.X = DstX;
    DstRect.Max.Y = DstY;

    FIntPoint DstSize(DstX, DstY);

    FIntPoint SrcSize;
    FIntRect SrcRect;

    {
        // Otherwise using exact size texture.
        SrcSize = DstSize;
        SrcRect = DstRect;
    }

    const FSceneRenderTargetItem& DestRenderTarget0 = PassOutputs[0].RequestSurface(Context);
    const FSceneRenderTargetItem* DestRenderTarget1 = nullptr;
    const FSceneRenderTargetItem* DestRenderTarget2 = nullptr;



    int32 NumRenderTargets = 1;

    const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

    FRHIRenderPassInfo RPInfo(DestRenderTarget0.TargetableTexture, ERenderTargetActions::DontLoad_Store);


    RPInfo.ColorRenderTargets[0].Action = ERenderTargetActions::DontLoad_Store;


FRHITexture* InputRenderTarget0 = GetInput(ePId_Input0)->GetOutput()->PooledRenderTarget->GetRenderTargetItem().ShaderResourceTexture;


    //FRHITexture* InputRenderTarget1 = GetInput(ePId_Input1)->IsValid() ? GetInput(ePId_Input1)->GetOutput()->PooledRenderTarget->GetRenderTargetItem().ShaderResourceTexture : nullptr;

    Context.RHICmdList.BeginRenderPass(RPInfo, TEXT("PostProcessBloomSetupES2"));
    {
        Context.SetViewportAndCallRHI(0, 0, 0.0f, DstX, DstY, 1.0f);

        FGraphicsPipelineStateInitializer GraphicsPSOInit;
        Context.RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
        GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
        GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
        GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();

        TShaderMapRef<FPostProcessmgTestVS_ES2> VertexShader(Context.GetShaderMap());
        //auto ShaderPermutationVector = FPostProcessBloomSetupPS_ES2::BuildPermutationVector(bUseBloom, bUseSun, bUseDof, bUseEyeAdaptation, bUseMetalMSAAHDRDecode);
        TShaderMapRef<FPostProcessmgTestPS_ES2> PixelShader(Context.GetShaderMap());

        GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI;
        GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader();
        GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader();
        GraphicsPSOInit.PrimitiveType = PT_TriangleList;

        SetGraphicsPipelineState(Context.RHICmdList, GraphicsPSOInit);

        VertexShader->SetVS(Context);
        PixelShader->SetPS(Context, PixelShader, InputRenderTarget0, nullptr);// InputRenderTarget0, InputRenderTarget1);

        DrawRectangle(
            Context.RHICmdList,
            0, 0,
            DstX, DstY,
            SrcRect.Min.X, SrcRect.Min.Y,
            SrcRect.Width(), SrcRect.Height(),
            DstSize,
            SrcSize,
            VertexShader,
            EDRF_UseTriangleOptimization);
    }
    Context.RHICmdList.EndRenderPass();


    if (DestRenderTarget0.TargetableTexture != nullptr)
    {
        Context.RHICmdList.TransitionResource(EResourceTransitionAccess::EReadable, DestRenderTarget0.TargetableTexture);
    }

}

FPooledRenderTargetDesc FRCPassPostProcessmgTestES2::ComputeOutputDesc(EPassOutputId InPassOutputId) const
{
    FPooledRenderTargetDesc Ret;
    Ret.Depth = 0;
    Ret.ArraySize = 1;
    Ret.bIsArray = false;
    Ret.NumMips = 1;
    Ret.TargetableFlags = TexCreate_RenderTargetable | TexCreate_ShaderResource;
    Ret.bForceSeparateTargetAndShaderResource = false;
    Ret.Format = PF_FloatR11G11B10;
    Ret.NumSamples = 1;
    Ret.Extent.X = FMath::Max(1, PrePostSourceViewportRect.Width());
    Ret.Extent.Y = FMath::Max(1, PrePostSourceViewportRect.Height());
    Ret.DebugName = TEXT("mgTestRTV");
    Ret.ClearValue = FClearValueBinding(FLinearColor::Red);
    return Ret;
}

 

class FRCPassPostProcessmgTestES2 : public TRenderingCompositePassBase<1, 1>
{
public:
    FRCPassPostProcessmgTestES2(FIntRect InPrePostSourceViewportRect)
        : PrePostSourceViewportRect(InPrePostSourceViewportRect)

    { }
    virtual void Process(FRenderingCompositePassContext& Context) override;
    virtual FPooledRenderTargetDesc ComputeOutputDesc(EPassOutputId InPassOutputId) const override;
    virtual void Release() override { delete this; }
private:
    FIntRect PrePostSourceViewportRect;
};

3.shader資源

#include "Common.ush"
#include "ScreenPass.ush"
SCREEN_PASS_TEXTURE_VIEWPORT(Input)
Texture2D InputTexture;

SamplerState InputSampler;

void mgTestVS(
    in float4 InPosition : ATTRIBUTE0,
    in float2 InTexCoord : ATTRIBUTE1,
    out float2 OutTexCoords : TEXCOORD0,
    out float4 OutPosition : SV_POSITION
    )
{
    DrawRectangle(InPosition, InTexCoord, OutPosition, InTexCoord);
    OutTexCoords = InTexCoord.xy;
}

void mgTestPS(
    float2 InUVs : TEXCOORD0,
    out half4 OutColor : SV_Target0
    )
{
    float4 SceneColor = Texture2DSample(InputTexture, InputSampler, InUVs);
    OutColor = half4(1,1,0,1)+ SceneColor;
}

4 加入管線

        FRenderingCompositePass* Passmg;
        Passmg = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessmgTestES2(FinalOutputViewRect));
        Passmg->SetInput(ePId_Input0, BloomOutput);
        FRenderingCompositeOutputRef mgTestOutput = FRenderingCompositeOutputRef(Passmg);
        

        static const auto VarTonemapperUpscale = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileTonemapperUpscale"));
        bool bDisableUpscaleInTonemapper = !VarTonemapperUpscale || VarTonemapperUpscale->GetValueOnRenderThread() == 0;

        bool* DoScreenPercentageInTonemapperPtr = nullptr;
        FRenderingCompositePass* TonemapperPass = nullptr;
        if (bAllowFullPostProcess)
        {
            if (bUseTonemapperFilm)
            {
                //BloomOutput
                //@todo Ronin Set to EAutoExposureMethod::AEM_Basic for PC vk crash.
                FRCPassPostProcessTonemap* PostProcessTonemap = AddTonemapper(Context, mgTestOutput, PostProcessEyeAdaptation, AutoExposureMethod, false, false, bMetalMSAAHDRDecode, bUseMobileDof);
                // remember the tonemapper pass so we can check if it's last
                TonemapperPass = PostProcessTonemap;

                PostProcessTonemap->bDoScreenPercentageInTonemapper = false;
                DoScreenPercentageInTonemapperPtr = &PostProcessTonemap->bDoScreenPercentageInTonemapper;            
            }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章