render stencil portals (opaque)
This commit is contained in:
@@ -4,7 +4,6 @@ using EscapeRoomEngine.Engine.Runtime.Modules;
|
||||
using EscapeRoomEngine.Engine.Runtime.Utilities;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace EscapeRoomEngine.Portal.Runtime
|
||||
{
|
||||
@@ -23,9 +22,13 @@ namespace EscapeRoomEngine.Portal.Runtime
|
||||
/// </summary>
|
||||
public Portal linkedPortal;
|
||||
/// <summary>
|
||||
/// The camera that will draw the view for this portal.
|
||||
/// The minimum near clip plane distance to be used when calculating the oblique clip plane.
|
||||
/// </summary>
|
||||
[BoxGroup("Internal")] public PortalCamera portalCamera;
|
||||
public float minNearClipPlane = 0.0001f;
|
||||
/// <summary>
|
||||
/// The mesh where the portal will be drawn.
|
||||
/// </summary>
|
||||
[BoxGroup("Internal")] public MeshRenderer screen;
|
||||
/// <summary>
|
||||
/// The transform marking the edge of the portal plane.
|
||||
/// </summary>
|
||||
@@ -51,12 +54,10 @@ namespace EscapeRoomEngine.Portal.Runtime
|
||||
{
|
||||
case DoorEventType.Connected:
|
||||
linkedPortal = FromDoorState(Module.ConnectedDoorState);
|
||||
portalCamera.screen.gameObject.SetActive(true);
|
||||
portalCamera.enabled = true;
|
||||
screen.gameObject.SetActive(true);
|
||||
break;
|
||||
case DoorEventType.Locked:
|
||||
portalCamera.enabled = false;
|
||||
portalCamera.screen.gameObject.SetActive(false);
|
||||
screen.gameObject.SetActive(false);
|
||||
linkedPortal = null;
|
||||
break;
|
||||
}
|
||||
@@ -85,6 +86,31 @@ namespace EscapeRoomEngine.Portal.Runtime
|
||||
}
|
||||
}
|
||||
|
||||
public Camera SetUpCamera(Camera playerCamera)
|
||||
{
|
||||
// place camera
|
||||
var m = portalTransform.localToWorldMatrix * HalfRotation *
|
||||
linkedPortal.portalTransform.worldToLocalMatrix * playerCamera.transform.localToWorldMatrix;
|
||||
playerCamera.transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
|
||||
|
||||
// set camera clip plane to portal (otherwise the wall behind the portal would be rendered)
|
||||
// calculating the clip plane: https://computergraphics.stackexchange.com/a/1506
|
||||
// clip plane normal
|
||||
var n = -portalTransform.forward;
|
||||
// clip plane in world space
|
||||
var portalPlane = new Plane(n, portalTransform.position);
|
||||
if (-portalPlane.GetDistanceToPoint(playerCamera.transform.position) >= minNearClipPlane)
|
||||
{
|
||||
// vector format clip plane in camera space
|
||||
var clipPlane = playerCamera.worldToCameraMatrix.inverse.transpose *
|
||||
new Vector4(n.x, n.y, n.z, portalPlane.distance);
|
||||
// only adjust the near clip plane if it doesn't intersect with the camera
|
||||
playerCamera.projectionMatrix = playerCamera.CalculateObliqueMatrix(clipPlane);
|
||||
}
|
||||
|
||||
return playerCamera;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begin tracking a portal driver that came close to this portal and might need to be teleported.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user