Unity HDRP下VRTK传送、穿墙 时画面淡入淡出、视觉遮挡无法正确显示问题解决

Unity HDRP下VRTK传送、穿墙 时画面淡入淡出、视觉遮挡无法正确显示问题解决

Unity HDRP的渲染方式和普通Unity有所不同,而SteamVR插件中负责VR画面淡入、淡出的脚本“SteamVR_Fade”是通过在相机渲染一帧后执行的方法OnPostRender调用GL.QUADS去执行绘制一个片,然后使用Shader控制这个片的颜色、渐变等来实现画面淡入、淡出遮当视线的功能;
SteamVR控制画面淡入、淡出的脚本
然而在HDRP中在OnPostRender下的GL绘制不会正常显示,要把“SteamVR_Fade”脚本原来普通方式放在 OnRenderObject 方法中调用GL来绘制的部分放到
UnityEngine.Rendering.RenderPipelineManager.endFrameRendering 这个方法回调中。


	protected void OnCameraRender(ScriptableRenderContext context, Camera[] cameraList)
	{
		foreach (var camera in cameraList)
		{
			
				DrawLines();
		}
	}

	void DrawLines()
	{
		
		if (currentColor != targetColor)
		{
			
			if (Mathf.Abs(currentColor.a - targetColor.a) < Mathf.Abs(deltaColor.a) * Time.deltaTime)
			{
				currentColor = targetColor;
				deltaColor = new Color(0, 0, 0, 0);
			}
			else
			{
				currentColor += deltaColor * Time.deltaTime;
			}

			if (fadeOverlay)
			{
				var overlay = SteamVR_Overlay.instance;
				if (overlay != null)
				{
					overlay.alpha = 1.0f - currentColor.a;
				}
			}
		}

		if (currentColor.a > 0 && fadeMaterial)
		{
			
			fadeMaterial.SetColor(fadeMaterialColorID, currentColor);
			fadeMaterial.SetPass(0);
			GL.Begin(GL.QUADS);

			GL.Vertex3(-1, -1, 0);
			GL.Vertex3( 1, -1, 0);
			GL.Vertex3(1, 1, 0);
			GL.Vertex3(-1, 1, 0);
			GL.End();
		}
	}
}

至此Game视窗中已经可以实现画面淡入、淡出和遮挡了,但VR头盔内画面依然没有变化
我们还需要调用OpenVR中的Compositor.FadeToColor方法对VR头盔内的画面进行操作;

最终代码

//#define TEST_FADE_VIEW
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
//
// Purpose:	CameraFade script adapted to work with SteamVR.
//
// Usage:	Add to your top level SteamVR_Camera (the one with ApplyDistoration
//			checked) and drag a reference to this component into SteamVR_Camera
//			RenderComponents list.  Then call the static helper function
//			SteamVR_Fade.Start with the desired color and duration.
//			Use a duration of zero to set the start color.
//
// Example:	Fade down from black over one second.
//			SteamVR_Fade.Start(Color.black, 0);
//			SteamVR_Fade.Start(Color.clear, 1);
//
// Note:	This component is provided to fade out a single camera layer's
//			scene view.  If instead you want to fade the entire view, use:
//			SteamVR_Fade.View(Color.black, 1);
//			(Does not affect the game view, however.)
//
//=============================================================================

using UnityEngine;
using UnityEngine.Rendering;
using Valve.VR;

public class SteamVR_Fade : MonoBehaviour
{
	private Color currentColor = new Color(0, 0, 0, 0);	// default starting color: black and fully transparent
	private Color targetColor = new Color(0, 0, 0, 0);	// default target color: black and fully transparent
	private Color deltaColor = new Color(0, 0, 0, 0);	// the delta-color is basically the "speed / second" at which the current color should change
	private bool fadeOverlay = false;

	static public void Start(Color newColor, float duration, bool fadeOverlay = false)
	{
		SteamVR_Events.Fade.Send(newColor, duration, fadeOverlay);
	}

	static public void View(Color newColor, float duration)
	{
		var compositor = OpenVR.Compositor;
		if (compositor != null)
			compositor.FadeToColor(duration, newColor.r, newColor.g, newColor.b, newColor.a, false);
	}

#if TEST_FADE_VIEW
	void Update()
	{
		if (Input.GetKeyDown(KeyCode.Space))
		{
			SteamVR_Fade.View(Color.black, 0);
			SteamVR_Fade.View(Color.clear, 1);
		}
	}
#endif

	public void OnStartFade(Color newColor, float duration, bool fadeOverlay)
	{
		if (duration > 0.0f)
		{
			targetColor = newColor;
			deltaColor = (targetColor - currentColor) / duration;
		}
		else
		{
			currentColor = newColor;
		}
	}

	static Material fadeMaterial = null;
	static int fadeMaterialColorID = -1;

	void OnEnable()
	{
		RenderPipelineManager.endFrameRendering += OnCameraRender;
		if (fadeMaterial == null)
		{
			fadeMaterial = new Material(Shader.Find("Custom/SteamVR_Fade"));
			fadeMaterialColorID = Shader.PropertyToID("fadeColor");
		}

		SteamVR_Events.Fade.Listen(OnStartFade);
		SteamVR_Events.FadeReady.Send();
	}

	void OnDisable()
	{
		RenderPipelineManager.endFrameRendering -= OnCameraRender;
		SteamVR_Events.Fade.Remove(OnStartFade);
	}
	protected void OnCameraRender(ScriptableRenderContext context, Camera[] cameraList)
	{
		foreach (var camera in cameraList)
		{
		
				DrawLines();
		}
	}

	void DrawLines()
	{
		
		if (currentColor != targetColor)
		{
			// if the difference between the current alpha and the desired alpha is smaller than delta-alpha * deltaTime, then we're pretty much done fading:
			if (Mathf.Abs(currentColor.a - targetColor.a) < Mathf.Abs(deltaColor.a) * Time.deltaTime)
			{
				currentColor = targetColor;
				deltaColor = new Color(0, 0, 0, 0);
			}
			else
			{
				currentColor += deltaColor * Time.deltaTime;
			}

			if (fadeOverlay)
			{
				var overlay = SteamVR_Overlay.instance;
				if (overlay != null)
				{
					overlay.alpha = 1.0f - currentColor.a;
				}
			}
		}

		if (currentColor.a > 0 && fadeMaterial)
		{
			SteamVR_Fade.View(currentColor, 0);
			fadeMaterial.SetColor(fadeMaterialColorID, currentColor);
			fadeMaterial.SetPass(0);
			GL.Begin(GL.QUADS);

			GL.Vertex3(-1, -1, 0);
			GL.Vertex3( 1, -1, 0);
			GL.Vertex3(1, 1, 0);
			GL.Vertex3(-1, 1, 0);
			GL.End();
		}
	}
}


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中,可以通过使用Camera的深度值和渐变效果来实现相机的淡入淡出效果。具体步骤如下: 1. 在场景中创建一个空对象,命名为“CameraFade”。 2. 在“CameraFade”对象上添加一个新的Camera组件,并将其深度值设置为比主相机更高的值,以确保它始终在主相机之前显示。 3. 在“CameraFade”对象上添加一个新的Canvas组件,并将其渲染模式设置为“屏幕空间-覆盖”。 4. 在Canvas上添加一个新的Image组件,并将其颜色设置为黑色,并将Alpha值设置为0。 5. 创建一个新的C#脚本,命名为“CameraFadeEffect”。 6. 在“CameraFadeEffect”脚本中,使用以下代码实现淡入淡出效果: ``` using UnityEngine; using UnityEngine.UI; using System.Collections; public class CameraFadeEffect : MonoBehaviour { public Image fadeImage; public float fadeSpeed = 1.5f; private bool isFading = false; void Start() { fadeImage.color = Color.black; fadeImage.canvasRenderer.SetAlpha(0.0f); } public void FadeIn() { isFading = true; fadeImage.CrossFadeAlpha(1.0f, fadeSpeed, false); } public void FadeOut() { isFading = true; fadeImage.CrossFadeAlpha(0.0f, fadeSpeed, false); } void Update() { if (isFading && fadeImage.canvasRenderer.GetAlpha() == 1.0f) { isFading = false; } } } ``` 7. 在场景中创建一个新的空对象,命名为“GameManager”。 8. 在“GameManager”对象上添加一个新的C#脚本,命名为“GameManager”。 9. 在“GameManager”脚本中,使用以下代码实现淡入淡出效果的调用: ``` using UnityEngine; using System.Collections; public class GameManager : MonoBehaviour { public CameraFadeEffect cameraFadeEffect; void Start() { StartCoroutine(FadeIn()); } IEnumerator FadeIn() { cameraFadeEffect.FadeIn(); yield return new WaitForSeconds(cameraFadeEffect.fadeSpeed); cameraFadeEffect.gameObject.SetActive(false); } IEnumerator FadeOut() { cameraFadeEffect.gameObject.SetActive(true); cameraFadeEffect.FadeOut(); yield return new WaitForSeconds(cameraFadeEffect.fadeSpeed); } } ``` 10. 在需要淡入淡出效果的场景中,将“GameManager”对象拖放到场景中,并将其“cameraFadeEffect”字段设置为“CameraFade”对象上的“CameraFadeEffect”脚本。 11. 在需要淡入淡出效果的场景中,使用以下代码调用淡入淡出效果: ``` GameManager gameManager = FindObjectOfType<GameManager>(); StartCoroutine(gameManager.FadeOut()); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值