Files
BH3/Assets/Scripts/Assembly-CSharp/MoleMole/ReflectionBase.cs
2025-08-13 09:26:42 +08:00

223 lines
6.3 KiB
C#

using System;
using UnityEngine;
namespace MoleMole
{
[DisallowMultipleComponent]
public class ReflectionBase : MonoBehaviour
{
public enum TexResScale
{
RES_25 = 25,
RES_33 = 33,
RES_40 = 40,
RES_50 = 50,
RES_75 = 75,
RES_100 = 100
}
[Serializable]
public class ReflectRenderer
{
public Renderer renderer;
private MaterialPropertyBlock block;
public void Init()
{
block = new MaterialPropertyBlock();
}
public void SetMaterialBlock(RenderTexture reflectionTex)
{
block.SetTexture("_ReflectionTex", reflectionTex);
renderer.SetPropertyBlock(block);
}
}
public TexResScale texResScale = TexResScale.RES_33;
public RenderTextureFormat bufferFormat = RenderTextureFormat.ARGBHalf;
public LayerMask layers = -33;
[Range(-10f, 10f)]
public float reflectClipPlaneOffset;
public ReflectRenderer[] reflectRendererList;
public bool FastMode;
protected string[] reflectShaderNames = new string[5] { "miHoYo/Scene/Metal Wall", "miHoYo/Scene/Metal Floor", "miHoYo/Scene/Metal Floor (With Pow)", "miHoYo/Scene/Water", "miHoYo/Scene/Water Shore" };
public Shader hexBlurShader;
private Material _hexBlurMat;
public bool useBlur;
public float hexBlurFactor;
protected static Camera _reflectionCamera;
protected TexResScale _oldTexResScale;
protected RenderTextureWrapper _reflectionRenderTex;
protected bool _insideRendering;
protected Vector3 _reflectionPlanePosition;
private bool _oldInvertCulling;
protected virtual void Awake()
{
_insideRendering = false;
_reflectionPlanePosition = base.transform.position;
if (reflectRendererList.Length == 0)
{
Renderer component = GetComponent<Renderer>();
if (component != null)
{
reflectRendererList = new ReflectRenderer[1];
reflectRendererList[0] = new ReflectRenderer();
reflectRendererList[0].renderer = component;
}
}
SetFastMode(!GlobalVars.USE_REFLECTION);
ReflectRenderer[] array = reflectRendererList;
foreach (ReflectRenderer reflectRenderer in array)
{
reflectRenderer.Init();
}
}
public void SetFastMode(bool isFastMode)
{
FastMode = isFastMode;
string[] array = reflectShaderNames;
foreach (string text in array)
{
Shader shader = Shader.Find(text);
if ((bool)shader)
{
if (FastMode)
{
shader.maximumLOD = 100;
}
else
{
shader.maximumLOD = 600;
}
}
}
}
protected virtual void Update()
{
_reflectionPlanePosition = base.transform.position;
}
protected virtual void LateUpdate()
{
if (FastMode || reflectRendererList.Length == 0)
{
return;
}
Camera main = Camera.main;
if ((bool)main && !_insideRendering)
{
_insideRendering = true;
DrawReflectionRenderTexture(main);
if (useBlur)
{
ApplyHexBlur();
}
ReflectRenderer[] array = reflectRendererList;
foreach (ReflectRenderer reflectRenderer in array)
{
reflectRenderer.SetMaterialBlock(_reflectionRenderTex);
}
_insideRendering = false;
}
}
private void ApplyHexBlur()
{
if (_hexBlurMat == null)
{
_hexBlurMat = new Material(hexBlurShader);
}
RenderTextureWrapper renderTexture = GraphicsUtils.GetRenderTexture(_reflectionRenderTex.width, _reflectionRenderTex.height, 0, bufferFormat);
ReflectionTool.ApplyHexBlur(_hexBlurMat, _reflectionRenderTex, renderTexture, hexBlurFactor, 0f, 0.5f, 1);
ReflectionTool.ApplyHexBlur(_hexBlurMat, renderTexture, _reflectionRenderTex, hexBlurFactor, 0f, 0.5f, 1);
GraphicsUtils.ReleaseRenderTexture(renderTexture);
}
private void DrawReflectionRenderTexture(Camera cam)
{
Vector3 reflectionPlanePosition = _reflectionPlanePosition;
Vector3 up = base.transform.up;
CreateObjects(cam, ref _reflectionRenderTex, ref _reflectionCamera);
_reflectionCamera.CopyFrom(cam);
float w = 0f - Vector3.Dot(up, reflectionPlanePosition);
Matrix4x4 matrix4x = ReflectionTool.CalculateReflectionMatrix(plane: new Vector4(up.x, up.y, up.z, w), reflectionMat: Matrix4x4.zero);
Vector3 position = cam.transform.position;
Vector3 position2 = matrix4x.MultiplyPoint(position);
_reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * matrix4x;
Vector4 clipPlane = ReflectionTool.CameraSpacePlane(_reflectionCamera, reflectionPlanePosition, up, 1f, reflectClipPlaneOffset);
Matrix4x4 projectionMatrix = cam.projectionMatrix;
projectionMatrix = ReflectionTool.CalculateObliqueMatrix(projectionMatrix, clipPlane, -1f);
_reflectionCamera.projectionMatrix = projectionMatrix;
_reflectionCamera.cullingMask = -17 & layers.value;
_reflectionCamera.targetTexture = _reflectionRenderTex;
_oldInvertCulling = GL.invertCulling;
GL.invertCulling = true;
_reflectionCamera.transform.position = position2;
Vector3 eulerAngles = cam.transform.eulerAngles;
_reflectionCamera.transform.eulerAngles = new Vector3(0f, eulerAngles.y, eulerAngles.z);
_reflectionCamera.Render();
_reflectionCamera.transform.position = position;
GL.invertCulling = _oldInvertCulling;
}
protected virtual void OnDisable()
{
if (_reflectionRenderTex != null)
{
GraphicsUtils.ReleaseRenderTexture(_reflectionRenderTex);
_reflectionRenderTex = null;
}
if ((bool)_reflectionCamera)
{
UnityEngine.Object.DestroyImmediate(_reflectionCamera.gameObject);
_reflectionCamera = null;
}
}
protected virtual void CreateObjects(Camera srcCam, ref RenderTextureWrapper renderTex, ref Camera destCam)
{
if (renderTex == null || _oldTexResScale != texResScale)
{
if (renderTex != null)
{
GraphicsUtils.ReleaseRenderTexture(renderTex);
}
renderTex = GraphicsUtils.GetRenderTexture(srcCam.pixelWidth * (int)texResScale / 100, srcCam.pixelHeight * (int)texResScale / 100, 16, bufferFormat);
renderTex.content.name = "__RefRenderTexture" + renderTex.content.GetInstanceID();
renderTex.content.hideFlags = HideFlags.DontSave;
_oldTexResScale = texResScale;
}
if (!destCam)
{
GameObject gameObject = new GameObject("__RefCamera for " + srcCam.GetInstanceID(), typeof(Camera));
destCam = gameObject.GetComponent<Camera>();
destCam.enabled = false;
destCam.transform.position = base.transform.position;
destCam.transform.rotation = base.transform.rotation;
gameObject.hideFlags = HideFlags.HideAndDontSave;
}
}
}
}