Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VRTK_ScreenFade does not work with scriptable render pipelines #481

Closed
krzys-h opened this issue Mar 26, 2019 · 11 comments
Closed

VRTK_ScreenFade does not work with scriptable render pipelines #481

krzys-h opened this issue Mar 26, 2019 · 11 comments
Labels
Projects

Comments

@krzys-h
Copy link

krzys-h commented Mar 26, 2019

Environment

  • Source of VRTK: GitHub
  • Version of VRTK: 3.3.0 bf584452ff8df5f5fd71ae148b642131b5820fb7
  • Version of Unity3D: 2018.3.5f1
  • Hardware used: VR Simulator
  • SDK used: VR Simulator, but everything except for SteamVR seems to use the same code path

Steps to reproduce

Set up a project using experimental LWRP for VR in Unity. Import VRTK into it. Do the following:

VRTK_HeadsetFade fade = gameObject.AddComponent<VRTK_HeadsetFade>();
fade.Fade(Color.black, 5.0f);

Expected behavior

The screen should fade.

Current behavior

The screen does not fade. OnPostRender in the VRTK_ScreenFade script is not called when scriptable render pipelines are used.

@krzys-h
Copy link
Author

krzys-h commented Mar 26, 2019

Also see https://forum.unity.com/threads/feedback-wanted-scriptable-render-pipelines.470095/page-8#post-3408481 for explanation why OnPostRender was removed

@krzys-h
Copy link
Author

krzys-h commented Apr 2, 2019

I tested on SteamVR now as well - it doesn't work either, the SteamVR_Fade script has exactly the same problem.

Here is the solution I ended up with for now, it took a while to figure out since there aren't many resources about the scriptable pipelines yet but it works:

using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.LightweightPipeline;
using UnityEngine.Rendering;
using VRTK;

public class VRTK_ScreenFade_LWRP : VRTK_ScreenFade, IAfterRender
{
    private FadeRenderPass fadeRenderPass;

    public ScriptableRenderPass GetPassToEnqueue()
    {
        return fadeRenderPass ?? (fadeRenderPass = new FadeRenderPass(this));
    }

    private class FadeRenderPass : ScriptableRenderPass
    {
        private VRTK_ScreenFade_LWRP screenFade;
        private Mesh quad;

        public FadeRenderPass(VRTK_ScreenFade_LWRP screenFade)
        {
            this.screenFade = screenFade;

            quad = new Mesh();

            Vector3[] newVertices = new Vector3[4];
            newVertices[0] = new Vector3(0f, 0f, 0.9999f);
            newVertices[1] = new Vector3(0f, 1f, 0.9999f);
            newVertices[2] = new Vector3(1f, 0f, 0.9999f);
            newVertices[3] = new Vector3(1f, 1f, 0.9999f);
            quad.vertices = newVertices;

            Vector2[] newUVs = new Vector2[newVertices.Length];
            newUVs[0] = new Vector2(0, 0);
            newUVs[1] = new Vector2(0, 1);
            newUVs[2] = new Vector2(1, 0);
            newUVs[3] = new Vector2(1, 1);
            quad.uv = newUVs;

            int[] newTriangles = new int[] { 0, 1, 2, 3, 2, 1 };
            quad.triangles = newTriangles;

            Vector3[] newNormals = new Vector3[newVertices.Length];
            for (int i = 0; i < newNormals.Length; i++)
                newNormals[i] = Vector3.forward;
            quad.normals = newNormals;
        }

        public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData)
        {
            // interpolation code copy-pasted from current OnPostRender implementation
            if (screenFade.currentColor != screenFade.targetColor)
            {
                if (Mathf.Abs(screenFade.currentColor.a - screenFade.targetColor.a) < Mathf.Abs(screenFade.deltaColor.a) * Time.deltaTime)
                {
                    screenFade.currentColor = screenFade.targetColor;
                    screenFade.deltaColor = new Color(0, 0, 0, 0);
                }
                else
                {
                    screenFade.currentColor += screenFade.deltaColor * Time.deltaTime;
                }
            }
            
            if (screenFade.currentColor.a > 0 && screenFade.fadeMaterial)
            {
                screenFade.currentColor.a = (screenFade.targetColor.a > screenFade.currentColor.a && screenFade.currentColor.a > 0.98f ? 1f : screenFade.currentColor.a);
                
                screenFade.fadeMaterial.color = screenFade.currentColor;
                screenFade.fadeMaterial.SetPass(0);

                CommandBuffer cmd = CommandBufferPool.Get("ScreenFade");
                cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.Ortho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 100.0f));
                cmd.DrawMesh(quad, Matrix4x4.identity, screenFade.fadeMaterial);
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            }
        }
    }
}
diff --git a/Assets/VRTK/Source/SDK/SteamVR/SDK_SteamVRHeadset.cs b/Assets/VRTK/Source/SDK/SteamVR/SDK_SteamVRHeadset.csindex d54988d..3e59f49 100644
--- a/Assets/VRTK/Source/SDK/SteamVR/SDK_SteamVRHeadset.cs
+++ b/Assets/VRTK/Source/SDK/SteamVR/SDK_SteamVRHeadset.cs
@@ -133,7 +133,9 @@ namespace VRTK
         /// <param name="fadeOverlay">Determines whether to use an overlay on the fade.</param>
         public override void HeadsetFade(Color color, float duration, bool fadeOverlay = false)
         {
-            SteamVR_Fade.Start(color, duration, fadeOverlay);
+            // PATCH: SteamVR_Fade is also broken in LWRP ~krzys_h
+            //SteamVR_Fade.Start(color, duration, fadeOverlay);
+            VRTK_ScreenFade.Start(color, duration);
         }

         /// <summary>
(and then add the VRTK_ScreenFade_LWRP on the camera manually so that VRTK doesn't automatically add the other one)

@Manuel-Meyer
Copy link

The Solution above doesn't work for me (Unity 2019).

IAfterRenderer is not part of UnityEngine.Rendering.LWRP and LightweightPipeline is not in namespace using UnityEngine.Experimental.Rendering anymore. Has anyone found a solution for this problem?

@huseyingulgen
Copy link

Does not work for me also. I just use ui image for fade now. It is not working well but you can use for now. If somebody has better a way , They can share solution here for LWRP please ? @Manuel-Meyer @krzys-h

@krzys-h
Copy link
Author

krzys-h commented Jun 7, 2019

I'm pretty sure Unity 2019 moved UnityEngine.Experimental.Rendering to just UnityEngine.Rendering.

Anyway, as it later turned out my solution didn't work on the actual headset for some reason, only on the simulator - I ended up switching to directly calling OpenVR.Compositor.FadeToColor() which worked even better for my purposes (fade between changing scenes - Unity would sometimes hang while loading and drop out to the compositor, this way the compositor keeps the screen black even if Unity stops rendering for a moment). Of course that is only valid when you are using OpenVR, but I guess other platforms must have something similar.

            try
            {
                if (OpenVR.Compositor == null)
                    throw new Exception("OpenVR not available");
                OpenVR.Compositor.FadeToColor(0.75f, 0.0f, 0.0f, 0.0f, 1.0f, false);
            }
            catch(Exception e) // throws the exception above if OpenVR is disabled or "dll not found" on platforms that don't support it at all (anything Android based like Oculus Quest or GearVR)
            {
                // TODO: add some fallback here, I'm just calling the VRTK fade for now to have it look correct when testing on the simulator
            }
            yield return new WaitForSeconds(0.75f);

            AsyncOperation asyncLoadOp = SceneManager.LoadSceneAsync(sceneToLoad, new LoadSceneParameters() { loadSceneMode = LoadSceneMode.Additive });
            yield return asyncLoadOp;
            if (previousScene.HasValue)
                yield return SceneManager.UnloadSceneAsync(previousScene.Value);
            SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneToLoad));

            try
            {
                if (OpenVR.Compositor == null)
                    throw new Exception("OpenVR not available");
                OpenVR.Compositor.FadeToColor(0.75f, 0.0f, 0.0f, 0.0f, 0.0f, false);
            }
            catch (Exception e)
            {
                // TODO: add fallback here
            }
            yield return new WaitForSeconds(0.75f);

@cocapasteque
Copy link

Any ETA for this issue ?

@bddckr
Copy link
Contributor

bddckr commented Nov 25, 2019

We'll not look at SRP support before Unity stabilizes that functionality. Additionally Unity currently does offer no way to support multiple SRPs in a single codebase/package.

You can observe changes to this issue to know about the progress on this.

@thestonefox thestonefox transferred this issue from ExtendRealityLtd/VRTK Dec 21, 2019
@thestonefox
Copy link
Member

Some further work has been done on this in the PR #477

But it's still not working on Oculus Quest so still not ready for merge.

@thestonefox
Copy link
Member

@thestonefox
Copy link
Member

PR with fix

#543

VRTK automation moved this from To do to Done Jun 10, 2021
@ExtendReality-Bot
Copy link
Member

🎉 This issue has been resolved in version 1.36.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
VRTK
  
Done
Development

No branches or pull requests

7 participants