A guide to setting up post processing in Unity

To implement post processing for Tilt Five using the Post Processing package provided by Unity, we will need the following:

  • A post process profile.
  • A post process volume.
  • A post process layer attached to each eye camera.

We should pay the most attention to the third point. When the TiltFiveManager is enabled at runtime, it attaches a SplitStereoCamera component to the head pose camera, which in turn creates a pair of child cameras that render the perspectives for each eye. To enable that rendering to include post processing effects, a PostProcessLayer component needs to be added to both of these eye cameras at runtime.

Note that the PostProcessLayer components for each eye should share a volume trigger. Otherwise, if one eye moves into a non-global post processing volume before the other one, the post processing effects rendered by each eye may differ, potentially causing discomfort for the user. One simple approach is to use the head pose camera as the shared volume trigger. Another might be to use the player’s avatar or the game board (just remember to update the shared volume trigger if you destroy or swap out these objects in the scene).

Additionally, be aware that to successfully add a PostProcessLayer at runtime, we must call Init() and pass in a PostProcessResources, which can be found inside the PostProcessing package.

Below is an example implementation of a component that initializes post processing for Tilt Five:

using UnityEngine;
using TiltFive;
using UnityEngine.Rendering.PostProcessing;

public class T5PostProcessing : MonoBehaviour
{

    public TiltFiveManager tiltFiveManager;
    public PostProcessResources postProcessResources;
    public Transform volumeTrigger;
    public LayerMask volumeLayer;

    // Start is called before the first frame update
    void Start()
    {
        if(tiltFiveManager == null)
        {
            Debug.LogWarning("No TiltFiveManager assigned, aborting post processing initialization.");
            return;
        }
        if (postProcessResources == null)
        {
            Debug.LogWarning("No PostProcessResources assigned, aborting post processing initialization. " + "Hint: Look inside the Post Processing package under PostProcessing>PostProcessing?");
            return;
        }

        var headPoseCameraObject = tiltFiveManager.glassesSettings.headPoseCamera.gameObject;

        if (headPoseCameraObject.TryGetComponent<SplitStereoCamera>(out var splitStereoCamera))
        {
            InitializeEyeCamera(splitStereoCamera.leftEyeCamera);
            InitializeEyeCamera(splitStereoCamera.rightEyeCamera);
        }
    }

    private void InitializeEyeCamera(Camera eyeCamera)
        {
        var postProcessLayer = eyeCamera.gameObject.AddComponent<PostProcessLayer>();
        postProcessLayer.volumeLayer = volumeLayer;
        postProcessLayer.volumeTrigger = volumeTrigger;
        postProcessLayer.Init(postProcessResources);
        }
    }
Tags: design