Why has Bokeh been removed and Gaussian been made mobile only in 4.23?

As my designers seem to feel, this impacts our game heavily, and is a terrible move by Epic.

is anyone else affected by this decision in 4.23?

What are your opinions on this?

Is there anyway to get around this and achieve similar effects using the stripped back DOF?

I was JUST working on a gimmick with bokeh and then I upgraded to 4.23 and this happened. Stuff failed to compile.

I can’t get to get any of the CineCamera stuff to work. It shows the layers properly when visualizing DOF Layers in the “show” options, but I can’t see any effect in the viewport.
Am I just bad at setting the camera properly? Did I miss anything? The layers also seem to move around when moving the mobile depth of field stuff, which is supposed to not be used. So is that still tied to legacy behavior?

Unreal have removed Bokeh and made Gaussian mobile only.

in 4.22 these are now marked as deprecated, and projects in 4.23 that rely upon Bokeh will have it disabled.

CircleDoF is actually really amazing once you get a handle on it. See my post here for some tips

The biggest issue is that the new Circle DOF does not function with TAAUpsampling enabled, meaning games that use Resolution Scaling effectively no longer have access to any DOF effects.

I previously reported this as a bug with a full demonstration project, and it was swiftly marked as a Non-Issue.

Prior to 4.23, users could fall back to legacy Circle DOF methods when TAAUpsampling was in use, which allowed at least an inferior method for DOF. However, 4.23 also removed the legacy Circle DOF algorithm.

So now you simply cannot have DOF effects if you use a Resolution Scale <100% and want to have TAAUpsampling for a clear image.

Note that ALL previous methods for DOF functioned perfectly with TAAUpsampling and Resolution Scale <100%.

Unless something has changed very recently, it *partially *works with temporal upsampling – the “slight out of focus” component doesn’t doesn’t work at all, but the downsampled portion does, so there’s a terrible-looking hard edge between the heavily-blurred area of the image and the rest that is fully sharp.

It’s possible to work around this to some extent using a post-process material to do the “slight out of focus” portion, using the DepthOfFieldFunction node (with value set to TDOF Circle of Confusion Radius) and some kind of blur function of your own (this custom node is a possible example):


//this is actually just the SpiralBlur node slightly adjusted to make a disc kernel

#include "/Engine/Private/SceneTexturesCommon.ush"

float3 CurColor;
float2 NewUV = BaseUV;
float StepSize = Distance / (int) DistanceSteps;
float CurDistance=0;
float2 CurOffset;
float TwoPi = 6.283185;
float Substep;
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;


int i=0;
int TotalRadialSteps = 0;

if (DistanceSteps<1)
{
    return DecodeSceneColorForMaterialNode(NewUV);
}
else
{

    while ( i < (int) DistanceSteps)
    {
        //decrease the number of radial steps near center so that samples are distributed more uniformly
        int RadialStepsDistributed = ((float)RadialSteps)*(((float)i)/((float)DistanceSteps));

        for (int j = 0; j < (int) RadialStepsDistributed; j++)
        {
            CurOffset.x = cos(TwoPi*((TempAARotation+Substep) / RadialStepsDistributed));
            CurOffset.y = sin(TwoPi*((TempAARotation+Substep) / RadialStepsDistributed));
            CurOffset *=DistanceMask;
            NewUV.x = BaseUV.x + (CurOffset.x * (CurDistance+(RandomSamp*TempAADistance)));
            NewUV.y = BaseUV.y + (CurOffset.y * (CurDistance+(RandomSamp*TempAADistance)));
            CurColor += SceneTextureLookup(NewUV, 14, false);
            Substep++;
            TotalRadialSteps++;
        }
        CurDistance+=StepSize;
        Substep+=RadialOffset;
        i++;
    }
    CurColor = CurColor / ((int)TotalRadialSteps);
    return CurColor;
}

There are, of course, a few problems with doing it this way:

-Performing this blur in the “Before Tonemapping” location breaks the temporal reconstruction used for upsampling pretty badly, so you need to do your custom blur in “After Tonemapping” instead. You can perform your own gamma correction to compensate to some extent, but it still won’t be correct.

-You should avoid blurring the areas that are already handled by the diaphragm DOF so that they’re not double-blurred, but it’s impossible to determine exactly where the diaphragm DOF kicks in. Making your custom blur fade out or start to decrease in radius as the CoC reaches some threshold can at least hide the seam.

-It’s kind of slow, although the number of samples doesn’t need to be very high since we’re only blurring slightly.

-Directly using the DepthOfFieldFunction as the custom blur radius causes sharp edge artifacts, so you may want to perform a pre-blur on the CoC as well in the same material (which makes this even slower).

EDIT: I just noticed that I was setting the “BaseUV” to a value that’s not corrected for screen percentage, so you need to pass that in as a parameter as well.

Wow, thanks @amoser for sharing. That’s a really smart way to solve it! I’ll give it a try as soon as I can come back to this. I had not noticed what you are mentioning about the slight out of focus vs. fully out of focus components. My experience was either no blur or full screen blur, depending on camera focus. But focus distance seemed totally broken as well. So I definitely missed something.

Long term, my hope would be that either a)Epic chooses to solve this problem themselves, or b)They simply give us back the legacy Circle DOF mode as an option. I’m guessing that will probably happen before a major studio releases an Xbox One game with 4.23 or higher LOL :smiley: