How do I implement focus-based dynamic DOF?

Ok, I am assuming that I should do that in Pawn blueprint, but how do I get access to the post process, applied to the pawn, from it’s blueprint? I did not find any such function to work with.

You’ll change those values in your character blueprint’s camera. Camera actors have all of the post process settings in themselves.

Yeah, I was looking there and now I understand, what’s the problem. The camera is added to the player class via C++ (I am using C++ FPS project template), and it has ReadOnly property in C++ native class. So, I can’t edit camera properties:

But, if I go back into cpp and change the properties to BlueprintReadWrite, I get this compiling error:

Do you know a way to overcome this, or a workaround?

Sorry, i know literally nothing about the C++ side of things. :\ I was assuming you’d start with a blank or BP template.

No problem, man, still u helped quite a lot and now I clearly know, what to do. Thanks :slight_smile:
I will attempt to do all the raycasting and DOF modification in the C++ tomorrow. In any case this is much faster and optimized way. I will write to this topic, upon getting any working results.

Ok, so I found a solution that works. It requires tweaking of DOF parameters and does not give instant desired result. What it does give is an instrument to change any DOF parameters on the scene according to the distance between the player and the overlapping object.
First, in Character class we add a raytracing function (you can add it somewhere else, ofc)

/*	Raytrace from a char location to the camera dir
	Utilized for dynamic DOF functionality             *///Lordink
bool AWolfdaleCharacter::TraceViewFocus(FHitResult* hitResult)
{
	FCollisionQueryParams hitTraceParams(FName(TEXT("RV_Trace")), true, this);
	FVector CameraLoc;
	FRotator CameraRot;
	GetActorEyesViewPoint(CameraLoc, CameraRot);
	
	FVector v_Start = CameraLoc;
	//The interaction distance is best set via UPROPERTY later on.
	FVector v_End = CameraLoc + (CameraRot.Vector() * 50000); // 50k is supposed to b 50m

	hitTraceParams.bTraceComplex = true; //Maybe should be set to false later on
	hitTraceParams.bTraceAsyncScene = true; //false for later on?
	hitTraceParams.bReturnPhysicalMaterial = true; //also false later on?
	hitTraceParams.TraceTag = FName("WD_CamTrace");
	
	//RayTracing:
	//bool Trace = GetWorld()->LineTraceSingle(*hitResult, v_Start, v_End, ECC_Pawn, hitTraceParams);
	bool Trace = GetWorld()->LineTraceSingle(*hitResult, v_Start, v_End, ECC_Pawn, hitTraceParams);
	
	if (!Trace){ //Prevent code from doing anything with non-traced hit results
		hitResult = NULL;
	}
	return Trace;
}

Then we can call this function anywhere where you would like to update the DOF. E.g. in ReceiveTick() funciton, which is called every tick, as far as I understand:

void AWolfdaleCharacter::ReceiveTick(float DeltaSeconds)
{
	//Call the base class func for its own functionality
	ACharacter::ReceiveTick(DeltaSeconds);

        //Raytrace and then rework the DOF
		FHitResult tracehit(ForceInit);
		bool CamTrace = TraceViewFocus(&tracehit);
		if (CamTrace){
			FVector v_Tracehitloc = tracehit.Location;
			FVector v_CamLoc;
			FRotator v_CamRot;
			GetActorEyesViewPoint(v_CamLoc, v_CamRot);
			float distance = FVector::Dist(v_CamLoc, v_Tracehitloc);
			FirstPersonCameraComponent->PostProcessSettings.DepthOfFieldScale = 0.1f;

			FirstPersonCameraComponent->PostProcessSettings.DepthOfFieldFocalDistance = distance;
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::SanitizeFloat(distance));
		}

}

This is not very optimized code, guys. I will be working on it, and you are also free to modify and enhance the code in my post.

Awesome! Glad you figured it out and thanks for sharing. :slight_smile:

I gave it a shot with BP last night and everything worked just fine until DOF. For some reason the cam’s DOF settings are bools only, couldnt edit them as a float in the blueprint. Matinee can do that but it works for level blueprint only. I’ll have to take a better look, maybe there is something i’m missing.

As I wrote earlier, for me the same problem was appearing as I was trying to modify the camera component of Cpp parent class. If u use blueprint-only template, however, u shud have full access to post proc params.
I tried it myself in other template, and I have all the settings (first dozens of them are bools, but then go actual settings):

Hah! I thought the other half had only some of the settings as floats(that crazy long pp node…) Cheers Lordink!

No problem, mate. Here is a short vid with my current results:

Cool! I’ll try to finish mine when i have the time. I can create a Wiki page for this topic together with your code when i get the result i want with only BP.

Nice idea. We can both contribute to the page. I will put there newer version of code with smooth transition like in video.
Just send me a link to the page or post it here, whenever you make it :slight_smile:

Hey mate!

Finally i gave it some time and got to a point i’m almost happy with.

I managed to get a smooth transition on the same surface by calculating the distance myself instead of using Get Distance To node, but as you can see i cant achieve a smooth transition as your solution when the trace hits different objects in different distances. So i need your help!

Here’s my blueprint setup:

What can i do to make the focus distance values interpolate smoothly?

Hey there!

I use a very simple way without any cool math, and actually I would advance it a little bit as soon as I get time.
Every tick I look at my current focus distance and compare it to the distance I get from ray tracing. Then, based on the difference, I either add or subtract some constant value with my current distance. This constant value is small enough to make each transition smooth, and, as transition happens every tick, it eventually gets to the traced value with those additions/subtractions.

One important thing is that you should not try to compare current focus distance with exact traced distance, but rather have some kind of “hysteresis” value, in which the current focus should be in order to satisfy the comparison. If you don’t get it, let me just give a quick example (or skip to next paragraph if u get): imagine your current focus distance is 500, and traced distance to object is 923. Camera does not move. Every tick you will be adding a constant of 50 to the focus distance. After some ticks it will be 900, which is too small, so it will add again and get 950 in next tick, which is too big so it will subtract, and so on, it will be jumping all the time.To solve that, we can make a hysteresis of e.g. 30, and then it will be satisfied with value of 900 and will not raise it more.

That’s my simple way. The way to improve it is to add/subtract different values every tick, depending on the difference between current dist and traced dist. The bigger the difference, the faster should be transition. This is simple to implement, and I suggest that as a superior way to just adding a constant every frame.

Hope, that helps a little :slight_smile: I can post my cpp code, if u need.

Thanks a lot for the explanation, Lordink! It helped.

Here’s the final result:

And here’s how i handled the blend:

And it also adepts the transition speed depending on how big the distance is between the last and the current hit points, so i’m pretty happy with this. Quite an achievement for a math and programming noob like me!

I’ll post the Wiki link here when i set it up so that you can post your code too.

Cheers!

Very nice. Glad I could help :slight_smile:
I would personally suggest trying out the Gaussian blur instead of Bokeh, if u will be going to put this system into the developed game. Bokeh may look a little too crazy with some focus distances :slight_smile:

Yeah, this is the bare bones of the system so i didnt care much about the looks for now. Blur type, transition speed and dof scale should be set depending on the users needs anyway. :slight_smile:

Here is the Wiki page if you want to add your code:

Cheers!

It is already there. :slight_smile: We cant embed videos on Wiki so it is a link at Final Result section.

thx. U should include the link to ur video in the Blueprint section, I guess. I would do the same for Cpp section, when will find time to write it :slight_smile: