Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create blur effect to all the scene except for one object (focus on that object)?

Tags:

unity3d

blur

I want to create a blur effect similar to the picture below: enter image description here

the picture is taken from this site:

https://forum.unity.com/threads/how-to-blur-specific-layers-only.555520/

I tried the post-processing profile and played around with the depth of field in the post-processing volume but it blurs all the scene.

I came across a YouTube Video that explains how to implement similar results to what I am looking for but things have changed drastically in the settings. For example, at 1:57 (minute and 57 seconds) he clicks on Add Additional Camera Data which I am struggling to find in the latest versions of LWRP.

I am using Unity version 2019.2.9f1

How can I achieve the result in the picture above? (Blurring all the scene except for one object)

Your guidance will be appreciated.

NOTE: My project is in VR using SteamVR and VRTK

like image 302
mazin Avatar asked Dec 02 '22 09:12

mazin


2 Answers

Though your question is a bit broad I took some time to show you how it can be done.


First of all you will need to import the Post Processing package via the PackageManager

Window → PackageManager

enter image description here

Make sure to be in the All Packages view, search for post, find the Post Processing package and hit Install

enter image description here


Now first of all go to the Layer settings (Layers → Edit Layers)

enter image description here

and add two additional Layers: e.g. PostProcessing and Focused

enter image description here

Now to the cameras. Afaik it makes no difference whether you are in VR or not, usually you have one MainCamera that is moved along with your headset. If there should be two of them in your project setup just repeat the same steps for the second camera.

  1. Make sure the MainCamera doesn't render the two added Layers → remove them from the Culling Mask

enter image description here

  1. Add a new Camera FocusCamera as child to the existing MainCamera. This way it is automatically moved along with the main Camera.

    RightClick on MainCamera &rightarrow Camera

    enter image description here

    It should have all the settings equal to the MainCamera except:

    • Clear Flags : Don't Clear
      If you set it to Depth Only the focused object will always be rendered on top of everything, even if it is actually behind other objects in 3D space. You decide which effect you want here ;)
    • CullingMask : only Focused
    • Depth : Anything higher than the MainCamera so this camera is rendered on top of it
    • Make sure to remove the AudioListener component.

    enter image description here enter image description here

  2. Finally add a new PostProcessingVolume to the scene. I would add it as child to the FocusCamera! Why? - Because this way it is automatically disabled together with the FocusCamera!

    RightClick on FocusCamera → 3D Object → Post Processing Volume

    enter image description here

    Set its Layer to the added PostProcessing

    enter image description here

    enable Is Global so the distance to the volume doesn't matter and add a new profile by hitting new → Unity → Depth of field

    In your case you want to overwrite the Focus Distance so check the box on the left and set a value close to the camera like e.g. 0.5

    enter image description here

Until now nothing has really changed in your scene.

Now go to the MainCamera and, a component PostProcessingLayer and set the Layer to our added layer PostProcessing

enter image description here

Now everything should be blurred in your scene!

Almost ready to go! Now Disable the FocusCamera and add this script to it

using UnityEngine;

public class FocusSwitcher : MonoBehaviour
{
    public string FocusedLayer = "Focused";

    private GameObject currentlyFocused;
    private int previousLayer;

    public void SetFocused(GameObject obj)
    {
        // enables this camera and the postProcessingVolume which is the child
        gameObject.SetActive(true);

        // if something else was focused before reset it
        if (currentlyFocused) currentlyFocused.layer = previousLayer;

        // store and focus the new object
        currentlyFocused = obj;

        if (currentlyFocused)
        {
            previousLayer = currentlyFocused.layer;
            currentlyFocused.layer = LayerMask.NameToLayer(FocusedLayer);
        }
        else
        {
            // if no object is focused disable the FocusCamera
            // and PostProcessingVolume for not wasting rendering resources
            gameObject.SetActive(false);
        }
    }

    // On disable make sure to reset the current object
    private void OnDisable()
    {
        if (currentlyFocused) currentlyFocused.layer =previousLayer;

        currentlyFocused = null;
    }
}

This will allow you to focus a certain GameObject on runtime by changing its layer to the Focused layer we added, the only one that is rendered by the FocusCamera. So this object will be rendered on top of the image without any blur effect!


For demonstration I just added this simple script to every cube object in order to enable focus on mouse enter and disable it on mouse exit:

using UnityEngine;

public class FocusMe : MonoBehaviour
{
    [SerializeField] private FocusSwitcher focus;

    private void OnMouseEnter()
    {
        focus.SetFocused(gameObject);
    }

    private void OnMouseExit()
    {
        // reset the focus
        // in the future you should maybe check first
        // if this object is actually the focused one currently
        focus.SetFocused(null);
    }
}

And here is what it looks like

enter image description here


as said I don't know exactly what your VR setup looks like. If you have to MainCameras simply add two child cameras to them. You still will need only one PostProcessingVolume and only one FocusSwitcher so you would probably move them to another object and handle the camera disabling etc differently but I hope the idea gets clear enough.

like image 78
derHugo Avatar answered Dec 03 '22 22:12

derHugo


Use a separate camera for objects you don't want to blur and set a higher depth value. Set the ClearFlags to depth only and in the CullingMask select the layer of that one object(or more objects). Obviously you would require to have a different layer for unblurred objects.

like image 30
gameDev_Unity Avatar answered Dec 03 '22 21:12

gameDev_Unity