Esempio n. 1
0
    private PortalRenderTexturePoolItem AllocatePortalRenderTexture(bool used = false)
    {
        RenderTexture renderTexture = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.DefaultHDR);

        renderTexture.Create();

        PortalRenderTexturePoolItem item = new PortalRenderTexturePoolItem(renderTexture, used);

        portalRenderTexturesPool.Add(item);

        return(item);
    }
Esempio n. 2
0
    /// <summary>
    /// Renders a portal, with recursions.
    /// The portal will follow the manually-defined portal visibility graph up to a certain number of recursions, depth-first.
    /// It will then render the innermost portals first, followed by outer ones, all the way until the original one is rendered.
    /// GameManager.instance.mainCamera MUST be defined before calling this function.
    /// </summary>
    /// <param name="portalToRender">Which portal are we rendering?</param>
    /// <param name="refPosition">The reference camera's position</param>
    /// <param name="refRotation">The reference camera's rotation</param>
    /// <param name="temporaryRenderTexturePoolItem">Handle to the temporay render texture pool item used to render the portal. CALLEE MUST RELEASE AFTER USE!!!</param>
    /// <param name="originalTexture">Handle to the original texture on the portal. Reset material back to this after use</param>
    /// <param name="currentRecursion">How deep are we?</param>
    /// <param name="overrideMaxRecursion">Override the global GameManager maxRecursion value</param>
    public static void RenderViewThroughRecursive(
        Portal portalToRender,
        Vector3 refPosition,
        Quaternion refRotation,
        out PortalRenderTexturePoolItem temporaryRenderTexturePoolItem,
        out Texture originalTexture,
        out int renderCount,
        int currentRecursion     = 0,
        int?overrideMaxRecursion = null)
    {
        renderCount = 1;

        // =======
        // RECURSE
        // =======

        // Override max recursions
        int maxRecursions = overrideMaxRecursion.HasValue ? overrideMaxRecursion.Value : GameManager.instance.portalMaxRecursion;

        // Calculate target view through camera position
        Vector3    targetRefPosition = TransformPositionBetweenPortals(portalToRender, portalToRender.target, refPosition);
        Quaternion targetRefRotation = TransformRotationBetweenPortals(portalToRender, portalToRender.target, refRotation);

        // Store visible portal resources to release and reset (see function description for details)
        List <VisiblePortalResources> visiblePortalResourcesList = new List <VisiblePortalResources>();

        // Recurse if not at limit
        if (currentRecursion < maxRecursions)
        {
            foreach (Portal visiblePortal in portalToRender.target.viewThroughFromVisiblePortals)
            {
                RenderViewThroughRecursive(
                    visiblePortal,
                    targetRefPosition,
                    targetRefRotation,
                    out PortalRenderTexturePoolItem visiblePortalTemporaryRenderTexturePoolItem,
                    out Texture visiblePortalOriginalTexture,
                    out int visiblePortalRenderCount,
                    currentRecursion + 1,
                    overrideMaxRecursion);

                visiblePortalResourcesList.Add(
                    new VisiblePortalResources(visiblePortal, visiblePortalTemporaryRenderTexturePoolItem, visiblePortalOriginalTexture));
                renderCount += visiblePortalRenderCount;
            }
        }

        // ======
        // RENDER
        // ======

        // Get new temporary render texture and set to portal's material
        // Will be released by CALLEE, not by this function. This is so that the callee can use the render texture
        // for their own purposes, such as a Render() or a main camera render, before releasing it.
        temporaryRenderTexturePoolItem = GameManager.instance.GetPortalRenderTexture();
        originalTexture = portalToRender.viewThroughToMaterial.GetTexture("_MainTex");
        portalToRender.viewThroughToMaterial.SetTexture("_MainTex", temporaryRenderTexturePoolItem.renderTexture);

        // Use portal camera
        Camera portalCamera = GameManager.instance.portalCamera;

        portalCamera.targetTexture = temporaryRenderTexturePoolItem.renderTexture;

        // Set target camera transform
        portalCamera.transform.SetPositionAndRotation(targetRefPosition, targetRefRotation);

        // Convert target portal's plane to camera space (relative to target camera)
        // Explanation: https://danielilett.com/2019-12-18-tut4-3-matrix-matching/
        Vector4 targetViewThroughPlaneCameraSpace =
            Matrix4x4.Transpose(Matrix4x4.Inverse(portalCamera.worldToCameraMatrix))
            * portalToRender.target.viewThroughFromPlane;

        // Set target camera projection matrix to clip walls between target portal and target camera
        // Portal camera will inherit FOV and near/clip values from main camera.
        portalCamera.projectionMatrix =
            GameManager.instance.mainCamera.CalculateObliqueMatrix(targetViewThroughPlaneCameraSpace);

        // Render portal camera to target texture
        portalCamera.Render();

        // =================
        // RELEASE AND RESET
        // =================

        foreach (VisiblePortalResources resources in visiblePortalResourcesList)
        {
            // Reset to original texture
            // So that it will remain correct if the visible portal is still expecting to be rendered
            // on another camera but has already rendered its texture. Originally the texture may be overriden by other renders.
            resources.visiblePortal.viewThroughToMaterial.SetTexture("_MainTex", resources.originalTexture);
            // Release temp render texture
            GameManager.instance.ReleasePortalRenderTexture(resources.portalRenderTexturePoolItem);
        }
    }
Esempio n. 3
0
 /// <summary>
 /// Releases the PortalRenderTexturePoolItem.
 /// </summary>
 /// <param name="item">The PortalRenderTexturePoolItem.</param>
 public void ReleasePortalRenderTexture(PortalRenderTexturePoolItem item)
 {
     item.used = false;
 }
Esempio n. 4
0
 public VisiblePortalResources(Portal visiblePortal, PortalRenderTexturePoolItem temporaryRenderTexture, Texture originalTexture)
 {
     this.visiblePortal = visiblePortal;
     this.portalRenderTexturePoolItem = temporaryRenderTexture;
     this.originalTexture             = originalTexture;
 }