OldBlueWater/BlueWater/Assets/StylizedWater2/Runtime/Underwater/UnderwaterUtilities.cs
2023-12-14 23:58:32 +09:00

114 lines
3.9 KiB
C#

//Stylized Water 2: Underwater Rendering extension
//Staggart Creations (http://staggart.xyz)
//Copyright protected under Unity Asset Store EULA
using UnityEngine;
namespace StylizedWater2.UnderwaterRendering
{
public static class UnderwaterUtilities
{
private const float VERTEX_DISTANCE = 0.02f; //50 subdivisions (100 tris)
private const int planeLengthSegments = 1;
private const float SCALE = 1f; //Unit rectangle
private static Mesh _WaterLineMesh;
public static Mesh WaterLineMesh
{
get
{
if (!_WaterLineMesh) _WaterLineMesh = CreateMaskMesh();
return _WaterLineMesh;
}
}
private static Mesh CreateMaskMesh()
{
int subdivisions = Mathf.FloorToInt(SCALE / VERTEX_DISTANCE);
int xCount = subdivisions + 1;
int yCount = planeLengthSegments + 1;
int numTriangles = subdivisions * planeLengthSegments * 6;
int numVertices = xCount * yCount;
Vector3[] vertices = new Vector3[numVertices];
int[] triangles = new int[numTriangles];
Vector2[] uvs = new Vector2[numVertices];
float scaleX = SCALE / subdivisions;
float scaleY = SCALE / planeLengthSegments;
int index = 0;
for (int z = 0; z < yCount; z++)
{
for (int x = 0; x < xCount; x++)
{
vertices[index] = new Vector3(x * scaleX - (SCALE * 0.5f), z * scaleY - (SCALE * 0.5f), 0f);
uvs[index] = new Vector2(x * scaleX, z * scaleY);
index++;
}
}
index = 0;
for (int z = 0; z < planeLengthSegments; z++)
{
for (int x = 0; x < subdivisions; x++)
{
triangles[index] = (z * xCount) + x;
triangles[index + 1] = ((z + 1) * xCount) + x;
triangles[index + 2] = (z * xCount) + x + 1;
triangles[index + 3] = ((z + 1) * xCount) + x;
triangles[index + 4] = ((z + 1) * xCount) + x + 1;
triangles[index + 5] = (z * xCount) + x + 1;
index += 6;
}
}
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
//Temp, so test mesh doesn't get culled
//mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 5000f);
#if SWS_DEV
//Debug.Log("Created waterline mesh");
#endif
return mesh;
}
private static float GetNearPlaneHeight(Camera camera)
{
return camera.projectionMatrix.inverse.m11;
}
public static Vector3 GetNearPlaneBottomPosition(Camera targetCamera, float offset = 0f)
{
return targetCamera.transform.position +
(targetCamera.transform.forward * (targetCamera.nearClipPlane + offset)) -
(targetCamera.transform.up * (targetCamera.nearClipPlane + offset) * GetNearPlaneHeight(targetCamera));
}
public static Vector3 GetNearPlaneTopPosition(Camera targetCamera, float offset = 0f)
{
return targetCamera.transform.position +
(targetCamera.transform.forward * (targetCamera.nearClipPlane + offset)) +
(targetCamera.transform.up * (targetCamera.nearClipPlane + offset) * GetNearPlaneHeight(targetCamera));
}
#if URP
public static void ToggleUnderwaterKeyword(bool value)
{
if (value) Shader.EnableKeyword(UnderwaterRenderer.Keyword);
else Shader.DisableKeyword(UnderwaterRenderer.Keyword);
}
#endif
}
}