SpiralBlur-SceneTexture not to blur objects before the plane with SpiralBlur

Very simple translucent shader using SpiralBlur-SceneTexture:

And very simple setup with two opaque cubes and a plane with spiral blur shader. The problem is it’s blurring not just the objects behind the plane but objects before it too. Any ideas for workarounds?

could use a scene capture 2d. with it’s own post process material.

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;
}
1 Like