Camera Dithering is one of the most basic requirements of a dynamic gameplay camera. In fact some AAA video games choose to solve all of their camera collision issues heavily using dithering all over the place. Dithering allows you to hide anything that is between the camera and the player, so that the line of sight is never broken, or objects/foliage overlapping the Camera itself and consequently covering the entire screen.
Here are examples from AAA video games.
Source - Ghost of Tsushima
Source - Assassin’s Creed: Origins
Source - Uncharted: Lost Legacy
Setting up Dithering
First of all, there are two types of collision checks performed for the dithering:
Line of Sight: This is a box overlap from the camera location to the spring arm origin location where we check for anything that is between both.
Overlap: This is a sphere overlap at the position of the camera. This is useful to dither the player, or whatever foliage starts covering your screen.
While playing in editor, you can open the console (usually with the ` key) and enter TraceTag CameraDithering to show the collision checks that are done for the dithering.
Next, if you are using UGC Camera Data Assets, then open your data asset and expand the DitheringSettings section, otherwise open the UGC_CameraDitheringModifier_BP class.
Here you can you set the Collision Channel for each of Line of Sight tests and the Overlap tests
You can set the Channels to Camera or you can create a new one if you want to. Whatever you do, the important thing is that if you want an object to be detected by the Dithering Modifier, they need to overlap the chosen collision channel
The final thing to do is to edit the Material of your object so that the CollisionModifier can hide the object.
If you are using your own Dithering material function, make sure to update the MaterialOpacityParameterName in the settings.
Open your master material, click on the output and make sure that the blend mode is set to Masked.
Now right-click in the editor and look for MF_CameraDithering_Whole. If you can’t find it, then in the content browser, go to AuroraDevs_UGC\Blueprints\Misc\Dithering where you will find the material function, then drag-and-drop it inside your material editor.
Now that you have the function, plug it into the OpacityMask
If you already had something plugged into Opacity Mask, plug it into the input of the MF_CameraDithering_Whole function.
You can also use MF_CameraDithering_Circle which uses a circular dithering style
⚠️ If you use the circular dithering, you will need to enabled UpdateMaterialPlayerPosition
Dithering Modifier Settings
There are a number of settings you can tweak for the dithering modifier.
General
DitheringMPC: The material parameter collection where we set the player position.
MaterialOpacityParameterName: The name of the scalar material parameter to blend in/out. If you are using our MF_CameraDithering_Whole and MF_CameraDithering_Circle material functions then leave this as it is.
bUpdateMaterialPlayerPosition: Whether the material has a vector parameter which should be updated to the player location.
MaterialPlayerPositionParameterName: The name of the vector parameter inside the Dithering Material Parameter Collection to set to the player position.
MaterialDitherMinimum: The minimum value of the material's Opacity when dithered.
DitherInSpeed: Controls the speed of the blend when starting to dither an object.
DitherOutSpeed: Controls the speed of the blend when finishing to dither an object.
IgnoreDitheringTag: Actors with this tag will not be dithered even if they overlap DitherLOSChannel and DitherOverlapChannel.
Line Of Sight
bDitherLineOfSight: Whether we should dither objects that block the LINE OF SIGHT of the camera.
DitherLOSChannel: The collision channel to use when checking for what the LINE OF SIGHT of the camera is colliding with. The other objects have to Overlap this channel in order to be dithered!
LOSProbeSize: The width of the probe when testing if any object is blocking the LINE OF SIGHT from the player to the camera. The other objects have to Overlap this channel in order to be dithered!
CollisionTimeThreshold: The minimum amount of time the camera LINE OF SIGHT has to collide with an object for it to be dithered.
Overlaps
bDitherOverlaps: Whether we should dither objects that OVERLAP the actual camera component.
bDitherOwner: Whether we should dither the owner character when the actual camera overlaps with them.
DitherOverlapChannel: The collision channel to use when checking for what the actual camera is overlapping with. The other objects have to Overlap this channel in order to be dithered!
SphereCollisionRadius: The radius around the camera where we check for collisions.
Dithering Modifier Functions
You can do this either by calling SetCameraDitheringSettings on the BP_UGCCameraManager
Or you can set them through the UGCCameraDataAssets, and then calling SetCameraData on BP_UGCCameraManager (see