Download

Some issues adding a Blur to the Ambient Occlusion Pass [C++]

Hi!

A while ago I implemented a screen space blur for the SSAO pass. However since 4.11 this has been broken. I recently started working on getting it to work properly again, and I am almost there.

The only issue is… it turns everything… red?

Like this:

Imgur

So, yes. Very red.

Does anyone have any ideas as to what is even going on here?! xD

Thanks,
Aidan.

Edit: Sorry, it just occured I should probably reference some code in here:

So! Right now the Blur code looks like this:


static FRenderingCompositeOutputRef BlurSSAOBuffer(FPostprocessContext& Context, FSceneRenderTargets& SceneContext, FRenderingCompositeOutputRef AO)
{
	FRenderingCompositePass* SSAO = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessInput(SceneContext.ScreenSpaceAO));

	FRCPassPostProcessWeightedSampleSumInputBlur* PostProcessBlurX = Context.Graph.RegisterPass(new(FMemStack::Get())
		FRCPassPostProcessWeightedSampleSumInputBlur(EFS_Horiz,
			EFCM_Weighted,
			CVarAmbientOcclusionBlurRadius.GetValueOnRenderThread(),
			TEXT("SSAO Blur X")));

	PostProcessBlurX->SetInput(ePId_Input0, SSAO);
	PostProcessBlurX->AddDependency(AO);

	FRCPassPostProcessWeightedSampleSumInputBlur* PostProcessBlurY = Context.Graph.RegisterPass(new(FMemStack::Get())
		FRCPassPostProcessWeightedSampleSumInputBlur(
			EFS_Vert,
			EFCM_Weighted,
			CVarAmbientOcclusionBlurRadius.GetValueOnRenderThread(),
			TEXT("SSAO Blur Y")));

	PostProcessBlurY->SetInput(ePId_Input0, SSAO);

	PostProcessBlurY->AddDependency(PostProcessBlurX);
	return PostProcessBlurY;
}

This function is called here:


FRenderingCompositePass* AmbientOcclusionPassMip0 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessAmbientOcclusion(Context.View, FullResAOType, false));
	AmbientOcclusionPassMip0->SetInput(ePId_Input0, GBufferA);
	AmbientOcclusionPassMip0->SetInput(ePId_Input1, AmbientOcclusionInMip1);
	AmbientOcclusionPassMip0->SetInput(ePId_Input2, AmbientOcclusionPassMip1);
	AmbientOcclusionPassMip0->SetInput(ePId_Input3, HZBInput);

	// to make sure this pass is processed as well (before), needed to make process decals before computing AO
	if(AmbientOcclusionInMip1)
	{
		AmbientOcclusionInMip1->AddDependency(Context.FinalOutput);
	}
	else
	{
		AmbientOcclusionPassMip0->AddDependency(Context.FinalOutput);
	}
	
	FRenderingCompositeOutputRef BluredAO = FRenderingCompositeOutputRef(BlurSSAOBuffer(Context, SceneContext, FRenderingCompositeOutputRef(AmbientOcclusionPassMip0)));
	Context.FinalOutput = BluredAO;// FRenderingCompositeOutputRef(AmbientOcclusionPassMip0);
	

	SceneContext.bScreenSpaceAOIsValid = true;

	return BluredAO;

The “FRCPassPostProcessWeightedSampleSumInputBlur” is a slightly modified version of WeightedSampleSum. The Main difference is instead of this:

FRCPassPostProcessWeightedSampleSum:


Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());

FRCPassPostProcessWeightedSampleSumInputBlur:


Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, InputPooledElement->GetRenderTargetItem().TargetableTexture, false, FResolveParams());
	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, InputPooledElement->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams());

Update: So, I’ve found a work around, though I don’t really understand why. I’ve turned up the “Static Fraction” value to be non-zero, which has fixed the red. Really confused about this, since we aren’t using static lighting at all in our game (Custom lighting solution).

I’ve replicated all of your blur code based on your pull request and this fix posted here and I too get the red effect if I have Static Fraction set to 0 (we also use 100 percent dynamic lighting). The blur effect is great - you saved our console users from grainy AO!