Looking-Glass/Assets/playerstuff/glass shader/WorkingPortal.cs

119 lines
4.9 KiB
C#
Raw Permalink Normal View History

2024-02-02 12:54:47 +01:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
2024-03-10 23:31:45 +01:00
// This class manages the rendering effects of portals.
2024-02-07 20:26:35 +01:00
2024-03-10 23:31:45 +01:00
// !!! Caution: Modifying this code without proper understanding may lead to unintended consequences. !!!
2024-02-07 20:26:35 +01:00
2024-02-02 12:54:47 +01:00
public class WorkingPortal : MonoBehaviour {
2024-02-07 20:26:35 +01:00
2024-03-10 23:31:45 +01:00
// The portal that this portal is linked to; the one whose view is seen when looking through this portal.
2024-02-02 12:54:47 +01:00
public WorkingPortal linkedWorkingPortal;
2024-02-07 20:26:35 +01:00
2024-03-10 23:31:45 +01:00
// The mesh renderer that renders the portal.
2024-02-02 12:54:47 +01:00
public MeshRenderer screen;
2024-03-10 23:31:45 +01:00
// Determines if the portal is visible from the camera.
2024-02-07 20:26:35 +01:00
public bool visibleFromCamera = true;
2024-02-02 12:54:47 +01:00
public GameObject myGameObject;
2024-03-10 23:31:45 +01:00
// The render texture that this portal's camera renders to, providing the view when looking through the linked portal.
2024-02-02 12:54:47 +01:00
public RenderTexture viewTexture;
2024-03-10 23:31:45 +01:00
// The camera used for rendering this portal.
public Camera WorkingPortalCam;
2024-02-07 20:26:35 +01:00
2024-03-10 23:31:45 +01:00
// Offset values for adjusting the near clipping plane.
2024-02-07 20:26:35 +01:00
float nearClipOffset = 0.05f;
float nearClipLimit = 0.2f;
2024-03-10 23:31:45 +01:00
// Reference to the player's camera.
2024-02-02 12:54:47 +01:00
Camera playerCam;
2024-03-10 23:31:45 +01:00
// Mesh filter of the portal's screen.
2024-02-02 12:54:47 +01:00
MeshFilter screenMeshFilter;
void Awake () {
2024-03-10 23:31:45 +01:00
// Set reference to this GameObject.
2024-02-02 12:54:47 +01:00
myGameObject = gameObject;
2024-03-10 23:31:45 +01:00
// Disable camera rendering by default; rendering is triggered manually via the Render() function.
2024-02-02 12:54:47 +01:00
WorkingPortalCam.enabled = false;
2024-03-10 23:31:45 +01:00
// Retrieve the mesh filter component of the portal screen.
2024-02-02 12:54:47 +01:00
screenMeshFilter = screen.GetComponent<MeshFilter> ();
2024-03-10 23:31:45 +01:00
// Set the display mask to render solid color instead of the camera view.
2024-02-02 12:54:47 +01:00
screen.material.SetInt ("displayMask", 1);
}
2024-03-10 23:31:45 +01:00
// Renders the view through this portal.
2024-02-02 12:54:47 +01:00
public void Render (Camera newplayerCam) {
if (!visibleFromCamera) {
return;
}
2024-02-07 20:26:35 +01:00
playerCam = newplayerCam;
2024-02-02 12:54:47 +01:00
CreateViewTexture ();
2024-03-10 23:31:45 +01:00
// This section aligns the portal camera with the player's view and renders only the portion visible through the portal.
2024-02-07 20:26:35 +01:00
2024-02-02 12:54:47 +01:00
var localToWorldMatrix = playerCam.transform.localToWorldMatrix;
2024-02-07 20:26:35 +01:00
var renderPosition = new Vector3();
var renderRotation = new Quaternion();
2024-02-02 12:54:47 +01:00
WorkingPortalCam.projectionMatrix = playerCam.projectionMatrix;
2024-02-07 20:26:35 +01:00
localToWorldMatrix = transform.localToWorldMatrix * linkedWorkingPortal.transform.worldToLocalMatrix * localToWorldMatrix;
renderPosition = localToWorldMatrix.GetColumn (3);
renderRotation = localToWorldMatrix.rotation;
2024-02-02 12:54:47 +01:00
2024-03-10 23:31:45 +01:00
// Hide the portal screen to allow camera to see through it.
2024-02-02 12:54:47 +01:00
screen.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
2024-02-07 20:26:35 +01:00
linkedWorkingPortal.screen.material.SetInt ("displayMask", 1);
2024-02-02 12:54:47 +01:00
2024-02-07 20:26:35 +01:00
WorkingPortalCam.transform.SetPositionAndRotation (renderPosition, renderRotation);
SetNearClipPlane ();
WorkingPortalCam.Render ();
2024-02-02 12:54:47 +01:00
2024-03-10 23:31:45 +01:00
// Revert hiding objects that were hidden at the start of rendering.
2024-02-02 12:54:47 +01:00
screen.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
void CreateViewTexture () {
if (viewTexture == null || viewTexture.width != Screen.width || viewTexture.height != Screen.height) {
if (viewTexture != null) {
viewTexture.Release ();
}
viewTexture = new RenderTexture (Screen.width, Screen.height, 0);
2024-03-10 23:31:45 +01:00
// Render the view from the portal camera to the view texture.
2024-02-02 12:54:47 +01:00
WorkingPortalCam.targetTexture = viewTexture;
2024-03-10 23:31:45 +01:00
// Display the view texture on the screen of the linked portal.
2024-02-02 12:54:47 +01:00
linkedWorkingPortal.screen.material.SetTexture ("_MainTex", viewTexture);
}
}
2024-03-10 23:31:45 +01:00
// Adjusts the near clipping plane to align with the surface of the portal.
2024-02-02 12:54:47 +01:00
void SetNearClipPlane () {
Transform clipPlane = transform;
int dot = System.Math.Sign (Vector3.Dot (clipPlane.forward, transform.position - WorkingPortalCam.transform.position));
Vector3 camSpacePos = WorkingPortalCam.worldToCameraMatrix.MultiplyPoint (clipPlane.position);
Vector3 camSpaceNormal = WorkingPortalCam.worldToCameraMatrix.MultiplyVector (clipPlane.forward) * dot;
float camSpaceDst = -Vector3.Dot (camSpacePos, camSpaceNormal) + nearClipOffset;
2024-03-10 23:31:45 +01:00
// Don't use oblique clip plane if very close to the portal as it may cause visual artifacts.
2024-02-02 12:54:47 +01:00
if (Mathf.Abs (camSpaceDst) > nearClipLimit) {
Vector4 clipPlaneCameraSpace = new Vector4 (camSpaceNormal.x, camSpaceNormal.y, camSpaceNormal.z, camSpaceDst);
2024-03-10 23:31:45 +01:00
// Update projection based on the new clip plane.
// Calculate matrix with player cam to use its settings (e.g., fov).
2024-02-02 12:54:47 +01:00
WorkingPortalCam.projectionMatrix = playerCam.CalculateObliqueMatrix (clipPlaneCameraSpace);
} else {
2024-03-10 23:31:45 +01:00
// Use default projection matrix if very close to the portal.
2024-02-02 12:54:47 +01:00
WorkingPortalCam.projectionMatrix = playerCam.projectionMatrix;
}
}
2024-03-10 23:31:45 +01:00
}