portal travelling

This commit is contained in:
2022-10-10 13:21:12 +02:00
parent 85e3064171
commit 6c92351658
22 changed files with 782 additions and 124 deletions

View File

@@ -10,7 +10,6 @@ namespace Escape_Room_Engine.Portal
[RequireComponent(typeof(Camera))]
public class PortalCamera : MonoBehaviour
{
private static readonly Matrix4x4 HalfRotation = Matrix4x4.Rotate(Quaternion.Euler(0, 180, 0));
private static readonly Camera.StereoscopicEye[] Eyes =
{ Camera.StereoscopicEye.Left, Camera.StereoscopicEye.Right };
private static readonly Dictionary<Camera.StereoscopicEye, int> EyeTextureNames = new()
@@ -22,15 +21,15 @@ namespace Escape_Room_Engine.Portal
/// <summary>
/// The minimum near clip plane distance to be used when calculating the oblique clip plane.
/// </summary>
public float minNearClipPlane = 0.02f;
public float minNearClipPlane = 0.0001f;
/// <summary>
/// The portal this camera renders through.
/// </summary>
[SerializeField] private Portal portal;
/// <summary>
/// The quad where the rendered texture will be drawn on.
/// The mesh where the rendered texture will be drawn on.
/// </summary>
[SerializeField] private MeshRenderer portalQuad;
[SerializeField] private MeshRenderer screen;
private PlayerCamera _playerCamera;
private Camera _camera;
@@ -56,16 +55,18 @@ namespace Escape_Room_Engine.Portal
RenderPipelineManager.beginCameraRendering -= Render;
}
private void Render(ScriptableRenderContext scriptableRenderContext, Camera camera)
private void Render(ScriptableRenderContext scriptableRenderContext, Camera _)
{
// check whether the portal plane is visible from the player camera
var frustumPlanes = GeometryUtility.CalculateFrustumPlanes(_playerCamera.camera);
if (!GeometryUtility.TestPlanesAABB(frustumPlanes, portal.other.portalCamera.portalQuad.bounds))
if (!GeometryUtility.TestPlanesAABB(frustumPlanes, portal.linkedPortal.portalCamera.screen.bounds))
// don't render this portal if it is not visible
return;
var t = portal.transform;
screen.enabled = false;
foreach (var eye in Eyes)
{
// create portal texture if it doesn't exist yet
@@ -75,15 +76,15 @@ namespace Escape_Room_Engine.Portal
{
_textures.Add(eye,
new RenderTexture(XRSettings.eyeTextureWidth, XRSettings.eyeTextureHeight, 24));
portal.other.portalCamera.portalQuad.material.SetTexture(EyeTextureNames[eye], _textures[eye]);
portal.linkedPortal.portalCamera.screen.material.SetTexture(EyeTextureNames[eye], _textures[eye]);
}
else // no texture was created so nothing should be rendered
continue;
}
// position portal camera
var m = t.localToWorldMatrix * HalfRotation * portal.other.transform.worldToLocalMatrix *
_playerCamera.getEyeTransform(eye).localToWorldMatrix;
var m = t.localToWorldMatrix * Portal.HalfRotation * portal.linkedPortal.transform.worldToLocalMatrix *
_playerCamera.GetEyeTransform(eye).localToWorldMatrix;
transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
_camera.projectionMatrix = _playerCamera.camera.GetStereoProjectionMatrix(eye);
@@ -93,7 +94,7 @@ namespace Escape_Room_Engine.Portal
var portalPlane = new Plane(n, t.position); // clip plane in world space
var clipPlane = _camera.worldToCameraMatrix.inverse.transpose *
new Vector4(n.x, n.y, n.z, portalPlane.distance); // vector format clip plane in camera space
if (Math.Abs(portalPlane.GetDistanceToPoint(transform.position)) >= minNearClipPlane)
if (-portalPlane.GetDistanceToPoint(transform.position) >= minNearClipPlane)
// only adjust the near clip plane if it doesn't intersect with the camera
_camera.projectionMatrix = _camera.CalculateObliqueMatrix(clipPlane);
@@ -101,6 +102,8 @@ namespace Escape_Room_Engine.Portal
_camera.targetTexture = _textures[eye];
UniversalRenderPipeline.RenderSingleCamera(scriptableRenderContext, _camera);
}
screen.enabled = true;
}
}
}