145 lines
4.2 KiB
C#
145 lines
4.2 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace PlanarReflections3
|
|
{
|
|
[ExecuteInEditMode]
|
|
public class PlanarReflectionsCaster : MonoBehaviour
|
|
{
|
|
public PlanarReflectionsRenderer castFromRenderer;
|
|
|
|
public bool[] castDepth = new bool[0];
|
|
|
|
public bool[] castReflection = new bool[0];
|
|
|
|
[SerializeField]
|
|
protected bool SRPMode;
|
|
|
|
private Renderer rend;
|
|
|
|
private Material[] sharedMats = new Material[0];
|
|
|
|
private MaterialPropertyBlock mBlock;
|
|
|
|
public bool isSRP => SRPMode;
|
|
|
|
public void OnEnable()
|
|
{
|
|
rend = GetComponent<Renderer>();
|
|
if (castDepth.Length != GetComponent<Renderer>().sharedMaterials.Length)
|
|
{
|
|
castDepth = new bool[GetComponent<Renderer>().sharedMaterials.Length];
|
|
}
|
|
if (castReflection.Length != castDepth.Length)
|
|
{
|
|
castReflection = new bool[castDepth.Length];
|
|
}
|
|
if (GraphicsSettings.renderPipelineAsset != null)
|
|
{
|
|
SRPMode = true;
|
|
}
|
|
else
|
|
{
|
|
SRPMode = false;
|
|
}
|
|
if (SRPMode)
|
|
{
|
|
RenderPipelineManager.beginCameraRendering -= CheckSRPVisibility;
|
|
RenderPipelineManager.beginCameraRendering += CheckSRPVisibility;
|
|
base.gameObject.layer = 4;
|
|
}
|
|
else
|
|
{
|
|
Camera.onPreRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPreRender, new Camera.CameraCallback(CheckVisibility));
|
|
Camera.onPreRender = (Camera.CameraCallback)Delegate.Combine(Camera.onPreRender, new Camera.CameraCallback(CheckVisibility));
|
|
}
|
|
}
|
|
|
|
public void CheckSRPVisibility(ScriptableRenderContext context, Camera srcCamera)
|
|
{
|
|
CheckVisibility(srcCamera);
|
|
for (int i = 0; i < castReflection.Length; i++)
|
|
{
|
|
MaterialPropertyBlock block = mBlock;
|
|
GetPropertyBlock(ref block, i);
|
|
block.SetTexture("_ReflectionTex", ((bool)castFromRenderer.ReflectionTex && castReflection[i] && srcCamera.cameraType != CameraType.Reflection && !srcCamera.name.Contains("PLANAR3_")) ? ((Texture)castFromRenderer.ReflectionTex) : ((Texture)Texture2D.blackTexture));
|
|
block.SetTexture("_ReflectionDepth", ((bool)castFromRenderer.ReflectionDepth && castDepth[i] && srcCamera.cameraType != CameraType.Reflection && !srcCamera.name.Contains("PLANAR3_")) ? ((Texture)castFromRenderer.ReflectionDepth) : ((Texture)Texture2D.whiteTexture));
|
|
SetPropertyBlock(block, i);
|
|
}
|
|
}
|
|
|
|
public void CheckVisibility(Camera cam)
|
|
{
|
|
if (mBlock == null)
|
|
{
|
|
mBlock = new MaterialPropertyBlock();
|
|
}
|
|
if ((bool)castFromRenderer && rend.isVisible)
|
|
{
|
|
castFromRenderer.castersActive = true;
|
|
for (int i = 0; i < castReflection.Length; i++)
|
|
{
|
|
MaterialPropertyBlock block = mBlock;
|
|
GetPropertyBlock(ref block, i);
|
|
block.SetTexture("_ReflectionTex", ((bool)castFromRenderer.ReflectionTex && castReflection[i] && cam.cameraType != CameraType.Reflection) ? ((Texture)castFromRenderer.ReflectionTex) : ((Texture)Texture2D.blackTexture));
|
|
block.SetTexture("_ReflectionDepth", ((bool)castFromRenderer.ReflectionDepth && castDepth[i] && cam.cameraType != CameraType.Reflection) ? ((Texture)castFromRenderer.ReflectionDepth) : ((Texture)Texture2D.whiteTexture));
|
|
SetPropertyBlock(block, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnDisable()
|
|
{
|
|
if (SRPMode)
|
|
{
|
|
RenderPipelineManager.beginCameraRendering -= CheckSRPVisibility;
|
|
}
|
|
else
|
|
{
|
|
Camera.onPreRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPreRender, new Camera.CameraCallback(CheckVisibility));
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if ((bool)castFromRenderer)
|
|
{
|
|
_ = rend.isVisible;
|
|
}
|
|
}
|
|
|
|
private void GetPropertyBlock(ref MaterialPropertyBlock block, int index)
|
|
{
|
|
if (!rend)
|
|
{
|
|
rend = GetComponent<Renderer>();
|
|
}
|
|
if ((bool)rend && sharedMats.Length < 1)
|
|
{
|
|
sharedMats = rend.sharedMaterials;
|
|
}
|
|
if (block != null && index >= 0 && (bool)rend && sharedMats.Length > index)
|
|
{
|
|
rend.GetPropertyBlock(block, index);
|
|
}
|
|
}
|
|
|
|
private void SetPropertyBlock(MaterialPropertyBlock block, int index)
|
|
{
|
|
if (!rend)
|
|
{
|
|
rend = GetComponent<Renderer>();
|
|
}
|
|
if ((bool)rend && sharedMats.Length < 1)
|
|
{
|
|
sharedMats = rend.sharedMaterials;
|
|
}
|
|
if (block != null && index >= 0 && (bool)rend && sharedMats.Length > index)
|
|
{
|
|
rend.SetPropertyBlock(block, index);
|
|
}
|
|
}
|
|
}
|
|
}
|