Created
April 17, 2020 00:56
-
-
Save limdingwen/74bc278db0a37316f83aa93e34aff503 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.Rendering; | |
/// <summary> | |
/// Starts the recursive portal rendering process, taking into account portal occlusion volumes. | |
/// </summary> | |
public class PortalRenderer : MonoBehaviour | |
{ | |
private PortalOcclusionVolume[] portalOcclusionVolumes; | |
[SerializeField] private Camera portalCamera; | |
[SerializeField] private int maxRecursions = 2; | |
[SerializeField] private LayerMask noCloneMask; | |
[SerializeField] private LayerMask renderCloneMask; | |
/// <summary> | |
/// Debug read only: Indicates the total amount of recursive renders performed by portals this frame. | |
/// </summary> | |
public int debugTotalRenderCount; | |
/// <summary> | |
/// Debug read only: Indicates how many portal renders were due to being directly visible by the player. | |
/// Use this field to debug the size of portal occlusion volumes. | |
/// </summary> | |
public int debugDirectRenderCount; | |
private void OnEnable() | |
{ | |
RenderPipelineManager.beginFrameRendering += RenderPipelineManagerOnBeginFrameRendering; | |
RenderPipelineManager.endFrameRendering += RenderPipelineManagerOnEndFrameRendering; | |
} | |
private void OnDisable() | |
{ | |
RenderPipelineManager.beginFrameRendering -= RenderPipelineManagerOnBeginFrameRendering; | |
RenderPipelineManager.endFrameRendering -= RenderPipelineManagerOnEndFrameRendering; | |
} | |
private void Start() | |
{ | |
portalOcclusionVolumes = FindObjectsOfType<PortalOcclusionVolume>(); | |
} | |
/// <summary> | |
/// Note: Does not support multiple cameras. Renders with mainCamera as reference. | |
/// Multi camera support easily possible! | |
/// </summary> | |
private void RenderPipelineManagerOnBeginFrameRendering(ScriptableRenderContext context, Camera[] cameras) | |
{ | |
// Find the current occlusion volume | |
PortalOcclusionVolume currentOcclusionVolume = null; | |
foreach (var portalOcclusionVolume in portalOcclusionVolumes) | |
{ | |
if (portalOcclusionVolume.PositionInVolume(GameManager.Instance.MainCamera.transform.position)) | |
{ | |
currentOcclusionVolume = portalOcclusionVolume; | |
} | |
} | |
// Render portals in occlusion volume | |
if (currentOcclusionVolume == null) | |
return; | |
var mainCamera = GameManager.Instance.MainCamera; | |
var mainCameraTransform = mainCamera.transform; | |
var cameraPlanes = GeometryUtility.CalculateFrustumPlanes(mainCamera); | |
debugTotalRenderCount = 0; | |
debugDirectRenderCount = 0; | |
foreach (var portal in currentOcclusionVolume.Portals) | |
{ | |
if (!portal.ShouldRender(cameraPlanes)) | |
continue; | |
portal.RenderViewthroughRecursive( | |
mainCameraTransform.position, | |
mainCameraTransform.rotation, | |
out _, | |
out _, | |
out var renderCount, | |
context, | |
portalCamera, | |
0, | |
maxRecursions, | |
currentOcclusionVolume, | |
noCloneMask, | |
renderCloneMask); | |
debugTotalRenderCount += renderCount; | |
debugDirectRenderCount++; | |
} | |
} | |
private void RenderPipelineManagerOnEndFrameRendering(ScriptableRenderContext context, Camera[] cameras) | |
{ | |
PortalRenderTexturePoolManager.Instance.ReleaseAll(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment