How can I 'pass' multiple render targets to a compute shader?

I need to access two render targets from a compute shader, because the logic I wish to put inside the shader involves subtracting the two images. Essentially, I am trying to replicate something like what’s in the picture below. How can I access multiple such render targets from my usf shader?


I haven’t used a render target as an input myself, but I have used render targets as outputs in my own compute shaders, and I imagine the process should be fairly similar for inputs.

If you’re using the old style global shader system (not render dependency graph) you probably want to get the underlying FTexture2DRHIRef from the rendertarget like the following:

UTextureRenderTarget2D* RenderTarget;
FRenderTarget* RenderTargetResource = RenderTarget->GetRenderTargetResource();
FTexture2DRHIRef RenderTargetRHI = RenderTargetResource->GetRenderTargetTexture();

From here, if you’re using a shader parameter struct like so:

        SHADER_PARAMETER_SRV(Texture2D<float4>, InputTexture1)
        SHADER_PARAMETER_SRV(Texture2D<float4>, InputTexture2)

Then you should just be able to assign the FTexture2DRHIRef directly to your shader parameter struct

FShader::FParameters PassParameters;
PassParameters.InputTexture1 = RenderTargetRHI;

Where you can then use the pass parameters in

FComputeShaderUtils::DispatchShader(RHICmdList, ComputeShader, PassParameters, GroupCount);

If you’re using RDG, then you will need to create a pooled render target and register it to the graph builder

FSceneRenderTargetItem RenderTargetItem;
RenderTargetItem.TargetableTexture = RenderTargetRHI;
RenderTargetItem.ShaderResourceTexture = RenderTargetRHI;
FPooledRenderTargetDesc RenderTargetDesc = FPooledRenderTargetDesc::Create2DDesc(RenderTargetResource->GetSizeXY(),
    RenderTargetRHI->GetFormat(), FClearValueBinding::Black, TexCreate_None, TexCreate_RenderTargetable |
    TexCreate_ShaderResource | TexCreate_UAV, false);
TRefCountPtr<IPooledRenderTarget> PooledRenderTarget;
GRenderTargetPool.CreateUntrackedElement(RenderTargetDesc, PooledRenderTarget, RenderTargetItem);

FRDGTextureRef DisplacementRenderTargetRDG = GraphBuilder.RegisterExternalTexture(PooledRenderTarget, TEXT("RenderTarget"));

Where you can then set the shader parameter the same as above, making sure to use the correct SHADER_PARAMETER_RDG in your struct definition.

Again, I haven’t tested this, as I’ve been using RDG to copy previous textures from a previous compute shader pass to my URenderTarget objects, but hopefully this should point you in the right direction.

1 Like