Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/LuxWater/LuxWater_ProjectorRenderer.cs
2026-03-04 10:03:45 +08:00

266 lines
7.9 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.XR;
namespace LuxWater
{
[RequireComponent(typeof(Camera))]
[ExecuteInEditMode]
public class LuxWater_ProjectorRenderer : MonoBehaviour
{
public enum BufferResolution
{
Full = 1,
Half = 2,
Quarter = 4,
Eighth = 8
}
[Space(8f)]
public BufferResolution FoamBufferResolution = BufferResolution.Full;
public BufferResolution NormalBufferResolution = BufferResolution.Full;
[Space(2f)]
[Header("Debug")]
[Space(4f)]
public bool DebugFoamBuffer;
public bool DebugNormalBuffer;
public bool DebugStats;
private int drawnFoamProjectors;
private int drawnNormalProjectors;
private static CommandBuffer cb_Foam;
private static CommandBuffer cb_Normals;
private Camera cam;
private Transform camTransform;
private RenderTexture ProjectedFoam;
private RenderTexture ProjectedNormals;
private Texture2D defaultBump;
private Bounds tempBounds;
private int _LuxWater_FoamOverlayPID;
private int _LuxWater_NormalOverlayPID;
private Plane[] frustumPlanes = new Plane[6];
private Material DebugMat;
private Material DebugNormalMat;
private void OnEnable()
{
_LuxWater_FoamOverlayPID = Shader.PropertyToID("_LuxWater_FoamOverlay");
_LuxWater_NormalOverlayPID = Shader.PropertyToID("_LuxWater_NormalOverlay");
cb_Foam = new CommandBuffer();
cb_Foam.name = "Lux Water: Foam Overlay Buffer";
cb_Normals = new CommandBuffer();
cb_Normals.name = "Lux Water: Normal Overlay Buffer";
cam = GetComponent<Camera>();
cam.AddCommandBuffer(CameraEvent.BeforeSkybox, cb_Foam);
cam.AddCommandBuffer(CameraEvent.BeforeSkybox, cb_Normals);
}
private void OnDisable()
{
if (ProjectedFoam != null)
{
Object.DestroyImmediate(ProjectedFoam);
}
if (ProjectedNormals != null)
{
Object.DestroyImmediate(ProjectedNormals);
}
if (defaultBump != null)
{
Object.DestroyImmediate(defaultBump);
}
if (DebugMat != null)
{
Object.DestroyImmediate(DebugMat);
}
if (cb_Foam != null && cb_Foam.sizeInBytes > 0)
{
cb_Foam.Clear();
cb_Foam.Dispose();
}
if (cb_Normals != null && cb_Normals.sizeInBytes > 0)
{
cb_Normals.Clear();
cb_Normals.Dispose();
}
Shader.DisableKeyword("USINGWATERPROJECTORS");
}
private void OnPreCull()
{
cam = GetComponent<Camera>();
int count = LuxWater_Projector.FoamProjectors.Count;
int count2 = LuxWater_Projector.NormalProjectors.Count;
if (count + count2 == 0)
{
if (cb_Foam != null)
{
cb_Foam.Clear();
}
if (cb_Normals != null)
{
cb_Normals.Clear();
}
Shader.DisableKeyword("USINGWATERPROJECTORS");
return;
}
Shader.EnableKeyword("USINGWATERPROJECTORS");
Matrix4x4 projectionMatrix = cam.projectionMatrix;
Matrix4x4 worldToCameraMatrix = cam.worldToCameraMatrix;
Matrix4x4 worldToProjectMatrix = projectionMatrix * worldToCameraMatrix;
int pixelWidth = cam.pixelWidth;
int pixelHeight = cam.pixelHeight;
GeomUtil.CalculateFrustumPlanes(frustumPlanes, worldToProjectMatrix);
int num = Mathf.FloorToInt(pixelWidth / (int)FoamBufferResolution);
int height = Mathf.FloorToInt(pixelHeight / (int)FoamBufferResolution);
bool flag = false;
TextureDimension dimension = TextureDimension.Tex2D;
if (cam.stereoEnabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced)
{
flag = true;
dimension = TextureDimension.Tex2DArray;
}
if (!ProjectedFoam)
{
ProjectedFoam = new RenderTexture(num, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
ProjectedFoam.dimension = dimension;
if (flag)
{
ProjectedFoam.volumeDepth = 2;
}
}
else if (ProjectedFoam.width != num)
{
Object.DestroyImmediate(ProjectedFoam);
ProjectedFoam = new RenderTexture(num, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
ProjectedFoam.dimension = dimension;
if (flag)
{
ProjectedFoam.volumeDepth = 2;
}
}
RenderTargetIdentifier renderTarget = ((!flag) ? new RenderTargetIdentifier(ProjectedFoam) : new RenderTargetIdentifier(ProjectedFoam, 0, CubemapFace.Unknown, -1));
cb_Foam.Clear();
cb_Foam.SetRenderTarget(renderTarget);
cb_Foam.ClearRenderTarget(clearDepth: true, clearColor: true, new Color(0f, 0f, 0f, 0f), 1f);
drawnFoamProjectors = 0;
for (int i = 0; i < count; i++)
{
LuxWater_Projector luxWater_Projector = LuxWater_Projector.FoamProjectors[i];
tempBounds = luxWater_Projector.m_Rend.bounds;
if (GeometryUtility.TestPlanesAABB(frustumPlanes, tempBounds))
{
cb_Foam.DrawRenderer(luxWater_Projector.m_Rend, luxWater_Projector.m_Mat);
drawnFoamProjectors++;
}
}
Shader.SetGlobalTexture(_LuxWater_FoamOverlayPID, ProjectedFoam);
num = Mathf.FloorToInt(pixelWidth / (int)NormalBufferResolution);
height = Mathf.FloorToInt(pixelHeight / (int)NormalBufferResolution);
if (!ProjectedNormals)
{
ProjectedNormals = new RenderTexture(num, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
ProjectedNormals.name = "ProjectedNormals";
ProjectedNormals.dimension = dimension;
if (flag)
{
ProjectedNormals.volumeDepth = 2;
}
}
else if (ProjectedNormals.width != num)
{
Object.DestroyImmediate(ProjectedNormals);
ProjectedNormals = new RenderTexture(num, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
ProjectedNormals.name = "ProjectedNormals";
ProjectedNormals.dimension = dimension;
if (flag)
{
ProjectedNormals.volumeDepth = 2;
}
}
RenderTargetIdentifier renderTarget2 = ((!flag) ? new RenderTargetIdentifier(ProjectedNormals) : new RenderTargetIdentifier(ProjectedNormals, 0, CubemapFace.Unknown, -1));
cb_Normals.Clear();
cb_Normals.SetRenderTarget(renderTarget2);
cb_Normals.ClearRenderTarget(clearDepth: true, clearColor: true, new Color(0f, 0f, 0f, 0f), 1f);
drawnNormalProjectors = 0;
for (int j = 0; j < count2; j++)
{
LuxWater_Projector luxWater_Projector2 = LuxWater_Projector.NormalProjectors[j];
tempBounds = luxWater_Projector2.m_Rend.bounds;
if (GeometryUtility.TestPlanesAABB(frustumPlanes, tempBounds))
{
cb_Normals.DrawRenderer(luxWater_Projector2.m_Rend, luxWater_Projector2.m_Mat);
drawnNormalProjectors++;
}
}
Shader.SetGlobalTexture(_LuxWater_NormalOverlayPID, ProjectedNormals);
}
private void OnDrawGizmos()
{
Camera component = GetComponent<Camera>();
int num = 0;
int num2 = (int)(component.aspect * 128f);
if (DebugMat == null)
{
DebugMat = new Material(Shader.Find("Hidden/LuxWater_Debug"));
}
if (DebugNormalMat == null)
{
DebugNormalMat = new Material(Shader.Find("Hidden/LuxWater_DebugNormals"));
}
if (DebugFoamBuffer)
{
if (ProjectedFoam == null)
{
return;
}
GL.PushMatrix();
GL.LoadPixelMatrix(0f, Screen.width, Screen.height, 0f);
Graphics.DrawTexture(new Rect(num, 0f, num2, 128f), ProjectedFoam, DebugMat);
GL.PopMatrix();
num = num2;
}
if (DebugNormalBuffer && !(ProjectedNormals == null))
{
GL.PushMatrix();
GL.LoadPixelMatrix(0f, Screen.width, Screen.height, 0f);
Graphics.DrawTexture(new Rect(num, 0f, num2, 128f), ProjectedNormals, DebugNormalMat);
GL.PopMatrix();
}
}
private void OnGUI()
{
if (DebugStats)
{
int count = LuxWater_Projector.FoamProjectors.Count;
int count2 = LuxWater_Projector.NormalProjectors.Count;
TextAnchor alignment = GUI.skin.label.alignment;
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUI.Label(new Rect(10f, 0f, 300f, 40f), "Foam Projectors [Registered] " + count + " [Drawn] " + drawnFoamProjectors);
GUI.Label(new Rect(10f, 18f, 300f, 40f), "Normal Projectors [Registered] " + count2 + " [Drawn] " + drawnNormalProjectors);
GUI.skin.label.alignment = alignment;
}
}
}
}