We have noticed that when a scene capture component has the ‘Render in Main Renderer’ property enabled and writes to a given render target, if the same render target is read from a Niagara system then the render target will stop updating. Disabling ‘Render in Main Renderer’ will lead to the render target updating again.
If you take a PIX capture when the problem is occurring you’ll see that the draw issued to copy the rendered image to the scene capture render target, with RDG scope ‘SceneCapturePass_SceneDepth/View’, is not present.
If a debugger is attached when the problem occurs, execution will break as an ensure will trigger (“Resource NiagaraTexture2D is in external access mode and is valid for access with the following states: SRVCompute|SRVGraphicsPixel|SRVGraphicsNonPixel, but is being used in pass Scene/CustomRenderPasses/CustomRenderPass… SceneCapturePass_SceneDepth/View… with access RTV”).
We have fixed the issue (including the ensure) on our side by making the change shown below to FSceneCapturePass::OnPreRender in SceneCaptureRendering.cpp. Note that when the Niagara system mentioned above doesn’t exist, the scene capture render target is registered with the RDG builder as an external texture, with stock code keeping it in external access mode, but when Niagara registers the render target with the RDG builder it asks the external texture to use internal access mode. Given the scene capture render target is going to be written to by that draw performing the copy mentioned above, allowing RDG to manage transitions for this resource by setting the render target to internal access mode (as Niagara does) seemed appropriate.
virtual void OnPreRender(FRDGBuilder& GraphBuilder) override
{
// Resize the render resource if necessary -- render target size may have been overridden to the main view resolution, or later be changed back
// to the resource resolution. The resize call does nothing if the size already matches.
((FTextureRenderTarget2DResource*)SceneCaptureRenderTarget)->Resize(GraphBuilder.RHICmdList, RenderTargetSize.X, RenderTargetSize.Y, bAutoGenerateMips);
RenderTargetTexture = SceneCaptureRenderTarget->GetRenderTargetTexture(GraphBuilder);
// BEGIN CHANGE
GraphBuilder.UseInternalAccessMode(RenderTargetTexture);
// END CHANGE
[Attachment Removed]