I’ve got the solution for Opaque objects - setup is the same but custom node in SpiralBlur - SceneTexture
node should be replaced with the code below. Basically it adds depthtest check and doesn’t blur object before the blurring plane (see example below - object on right is before the plane and not blurred).
While it works fine with translucent materials since they have “Render After DOF” option in material properties, it has a problem with volumetric materials. “Render After DOF” option seems to do nothing for volumetric materials, so I guess they’re not supported for this. Maybe using a scene capture 2d with volumetric objects hidden is indeed the solution for this, unless I find some other workaround. But if there are volumetrics before the blurring plane, then the patched spiralblur node will help.
Custom hlsl:
float3 CurColor = 0;
float2 BaseUV = MaterialFloat2(ScreenAlignedPosition(Parameters.ScreenPosition).xy);
float2 NewUV = BaseUV;
float StepSize = Distance / (int) DistanceSteps;
float CurDistance = 0;
float2 CurOffset = 0;
float TwoPi = 6.283185;
float Substep = 0;
float2 ScenePixels=View.BufferSizeAndInvSize.xy*BaseUV;
ScenePixels+=View.TemporalAAParams.r;
float2 RandomSamp = ((uint)(ScenePixels.x) + 2 * (uint)(ScenePixels.y)) % 5;
RandomSamp+=Texture2DSample(Tex,TexSampler,ScenePixels);
RandomSamp/=5;
RandomSamp-=0.5;
TempAARotation*=RandomSamp;
TempAADistance*=StepSize*RandomSamp;
float pixel_depth = length(GetTranslatedWorldPosition(Parameters));
float pixel_z_buffer = CalcSceneDepth(BaseUV);
// Exit early if there's an object in Z buffer before blur plane.
if (pixel_depth >= pixel_z_buffer) {
return DecodeSceneColorForMaterialNode(BaseUV);
}
int i=0;
int actual_steps=0;
if (DistanceSteps < 1)
{
return DecodeSceneColorForMaterialNode(NewUV);
}
else
{
//CurDistance += 0.5*StepSize;
while ( i < (int) DistanceSteps)
{
//CurDistance+=StepSize;
for (int j = 0; j < (int) RadialSteps; j++)
{
CurOffset.x = cos(TwoPi*((TempAARotation+Substep) / RadialSteps));
CurOffset.y = sin(TwoPi*((TempAARotation+Substep) / RadialSteps));
CurOffset *= DistanceMask;
NewUV.x = BaseUV.x + (CurOffset.x * (CurDistance+(RandomSamp*TempAADistance)));
NewUV.y = BaseUV.y + (CurOffset.y * (CurDistance+(RandomSamp*TempAADistance)));
// Shouldn't blur the objects before the blurring plane.
if (CalcSceneDepth(NewUV) >= pixel_depth) {
CurColor += DecodeSceneColorForMaterialNode(NewUV);
actual_steps++;
}
//CurDistance+=(StepSize+(TempAADistance))/RadialSteps;
Substep++;
}
CurDistance+=StepSize;
Substep+=RadialOffset;
i++;
}
CurColor = CurColor / actual_steps;
return CurColor;
}