Search Unity

HDRP | Fade to Black in VR

Discussion in 'AR/VR (XR) Discussion' started by d1xt1r, Feb 27, 2020.

  1. d1xt1r

    d1xt1r

    Joined:
    Oct 1, 2016
    Posts:
    7
    Hi,

    does anyone know a workaround for using SteamVR_Fade script (from the SteamVR Unity Asset) in a HDRP project? The idea is when you teleport near a wall and collide with it not to see through the wall but instead fade to black
    like this:

    It works in Built-in Render Pipeline, but due to a change in the rendering flow it no longer works. There is an open issue in GitHub from last year: https://github.com/ValveSoftware/steamvr_unity_plugin/issues/388

    Thanks!
     
  2. float

    float

    Joined:
    Jul 29, 2012
    Posts:
    42
    Yesterday I've tried to implement a ScreenFader myself with the URP via Blit and a simple shader.
    From the URP examples (Post-Outline) i tried to copy all that is needed. It worked in the example project but not in my own XR enabled project. I guess something is not right as i got an out-of-bounds error when i tried to look at it via frame-debugger(somewhere in the #if XR enabled region).
    Then i tried to hijack the vignette postFX since i would never use it... but after a unity restart it was gone. Seems it gets overwritten when loading Unity.
    Finally...
    i just use the Color-Adjustments PostEffect to fade to black...
    Code (CSharp):
    1.  
    2. public Volume ppGlobalVolume; // Ref to the PostProcessing Volume
    3.  
    4. Awake()
    5. {
    6.             if(!ppGlobalVolume.profile.TryGet<ColorAdjustments>(out colorAdjustments))
    7.             {
    8.                 Debug.LogWarning("No coloradjustments found!");
    9.             }
    10.             else
    11.                 cp = colorAdjustments.colorFilter;
    12. }
    13.  
    14. public IEnumerator FadeScreen(Color from, Color to, float timing)
    15.         {
    16.             cp.value = from;
    17.             elapsedTime = 0;
    18.             while (elapsedTime < timing)
    19.             {
    20.                 cp.Interp(from, to, elapsedTime / timing);
    21.                 elapsedTime += Time.deltaTime;
    22.                 yield return wait4Frame;
    23.             }
    24.             cp.value = to;
    25.             yield return wait4Frame;
    26.         }
    27.  
    And use it like this in a coroutine:
    Code (CSharp):
    1.  
    2. yield return StartCoroutine( FadeScreen(Color.white, Color.black * -5, 2) );
    3.  
    I use Color.black * -5 to make sure it gets very dark, because if you have something emissive it would still be visible if you go to a "normal" black.

    I hope that helps you.
     
    jeromeWork likes this.
  3. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    Just wanted to say thank you. Very helpful.

    I'll contribute my own full version of the script:
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.Rendering;
    4. using UnityEngine.Rendering.Universal;
    5. //using Sirenix.OdinInspector;
    6.  
    7. public class URPScreenFade : MonoBehaviour
    8. {
    9.     public Volume ppGlobalVolume; // Ref to the PostProcessing Volume
    10.     private ColorParameter cp = null;
    11.  
    12.     private IEnumerator coroutine;
    13.  
    14.     enum FadingDirection {FadeIn, FadeOut}
    15.     void Awake()
    16.     {
    17.                 ColorAdjustments colorAdjustments = null;
    18.                 if(!ppGlobalVolume.profile.TryGet<ColorAdjustments>(out colorAdjustments))
    19.                 {
    20.                     Debug.LogWarning("No color adjustments found!");
    21.                 }
    22.                 else
    23.                     cp = colorAdjustments.colorFilter;
    24.     }
    25.     IEnumerator FadeScreen(Color from, Color to, float timing)
    26.         {
    27.             cp.value = from;
    28.             float elapsedTime = 0;
    29.             while (elapsedTime < timing)
    30.             {
    31.                 cp.Interp(from, to, elapsedTime / timing);
    32.                 elapsedTime += Time.deltaTime;
    33.                 yield return new WaitForEndOfFrame();
    34.             }
    35.             cp.value = to;
    36.             yield return new WaitForEndOfFrame();
    37.         }
    38.  
    39.         //[Button]
    40.         public void SceneFadeOut(float timeSecs = 2f){
    41.             DoFade(FadingDirection.FadeOut, timeSecs);
    42.         }
    43.         //[Button]
    44.         public void SceneFadeIn(float timeSecs = 2f){
    45.             DoFade(FadingDirection.FadeIn, timeSecs);
    46.         }
    47.  
    48.         private void DoFade(FadingDirection fadingDir, float timeSecs){
    49.  
    50.             Color fromColor = Color.white;
    51.             Color toColor = Color.black * -5; // -5 ensures full darkness
    52.  
    53.             if(fadingDir == FadingDirection.FadeIn){
    54.                 fromColor = Color.black * -5; // -5 ensures full darkness
    55.                 toColor = Color.white;
    56.             }
    57.  
    58.             // interrupt started fade and grab current value
    59.             if (coroutine != null){
    60.                 StopCoroutine(coroutine);
    61.                 fromColor = cp.value;
    62.             }
    63.             coroutine = FadeScreen(fromColor, toColor, timeSecs) ;
    64.             StartCoroutine( coroutine );
    65.         }
    66. }
    67.  
     
    andreibosco likes this.