portals and dash. Also a bit of terrain building and level design

This commit is contained in:
2022-03-13 00:26:35 +02:00
parent 813cd0c451
commit e82799c36a
6242 changed files with 2160679 additions and 188245 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9f117c50e15c3dd46a06b1a25b9dc4a5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public interface IPMeshCreator
{
void Create(PWater water);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b2581821fa7ed184498bca0e45f6da73
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,294 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Poseidon;
namespace Pinwheel.Poseidon
{
public class PAreaMeshCreator : IPMeshCreator
{
private const int MASK_RESOLUTION = 100;
private PWater water;
private float[] mask;
private float minX;
private float maxX;
private float minY;
private float maxY;
private Vector2[,] grid;
public void Create(PWater water)
{
if (water.AreaMeshAnchors.Count < 3)
return;
this.water = water;
CalculateBoundaries();
GenerateMask();
GenerateGrid();
UpdateMesh();
}
private void GenerateMask()
{
mask = new float[MASK_RESOLUTION * MASK_RESOLUTION];
List<Vector2> segments = new List<Vector2>();
GetSegments(segments);
float lineY = 0;
List<float> intersectX = new List<float>();
for (int i = 0; i < MASK_RESOLUTION; ++i)
{
intersectX.Clear();
lineY = i * 1.0f / MASK_RESOLUTION;
FindIntersects(segments, intersectX, lineY);
FillLine(i, intersectX);
}
//DrawDebug();
}
private void CalculateBoundaries()
{
List<Vector3> anchors = water.AreaMeshAnchors;
minX = float.MaxValue;
maxX = float.MinValue;
minY = float.MaxValue;
maxY = float.MinValue;
for (int i = 0; i < anchors.Count; ++i)
{
minX = Mathf.Min(minX, anchors[i].x);
maxX = Mathf.Max(maxX, anchors[i].x);
minY = Mathf.Min(minY, anchors[i].z);
maxY = Mathf.Max(maxY, anchors[i].z);
}
}
private void GetSegments(List<Vector2> segments)
{
List<Vector3> anchors = water.AreaMeshAnchors;
for (int i = 0; i < anchors.Count; ++i)
{
segments.Add(new Vector2(
Mathf.InverseLerp(minX, maxX, anchors[i].x),
Mathf.InverseLerp(minY, maxY, anchors[i].z)));
}
segments.Add(new Vector2(
Mathf.InverseLerp(minX, maxX, anchors[0].x),
Mathf.InverseLerp(minY, maxY, anchors[0].z)));
}
private void FindIntersects(List<Vector2> segments, List<float> intersectX, float lineY)
{
for (int i = 0; i < segments.Count - 1; ++i)
{
Vector2 s0 = segments[i];
Vector2 s1 = segments[i + 1];
Vector2 inter;
if (PGeometryUtilities.IsIntersectHorizontalLine(
s0.x, s0.y,
s1.x, s1.y,
lineY,
out inter))
{
intersectX.Add(inter.x);
}
}
}
private void FillLine(int lineIndex, List<float> intersectX)
{
intersectX.Sort();
List<int> columnIndices = new List<int>();
for (int i = 0; i < intersectX.Count; ++i)
{
columnIndices.Add((int)(intersectX[i] * MASK_RESOLUTION));
}
int pairCount = columnIndices.Count / 2;
for (int p = 0; p < pairCount; ++p)
{
int c0 = columnIndices[p * 2 + 0];
int c1 = columnIndices[p * 2 + 1];
for (int c = c0; c <= c1; ++c)
{
mask[PUtilities.To1DIndex(c, lineIndex, MASK_RESOLUTION)] = 1.0f;
}
}
}
//private void DrawDebug()
//{
// water.debugTexture = new Texture2D(MASK_RESOLUTION, MASK_RESOLUTION);
// Color[] colors = new Color[MASK_RESOLUTION * MASK_RESOLUTION];
// for (int i = 0; i < mask.Length; ++i)
// {
// colors[i] = mask[i] == 1 ? Color.white : Color.black;
// }
// water.debugTexture.SetPixels(colors);
// water.debugTexture.Apply();
//}
private void GenerateGrid()
{
int resolution = water.MeshResolution;
int length = resolution + 1;
grid = new Vector2[length, length];
Vector2 p = Vector2.zero;
for (int z = 0; z < length; ++z)
{
for (int x = 0; x < length; ++x)
{
p.Set(
Mathf.InverseLerp(0, length - 1, x),
Mathf.InverseLerp(0, length - 1, z));
grid[z, x] = p;
}
}
}
private void UpdateMesh()
{
//vertices
int length = grid.GetLength(0);
int width = grid.GetLength(1);
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector4> uvs0 = new List<Vector4>(); //contain neighbor vertex position, for normal re-construction
List<Color> colors = new List<Color>(); //contain neighbor vertex position, for normal re-construction
Vector4 bl = Vector4.zero;
Vector4 tl = Vector4.zero;
Vector4 tr = Vector4.zero;
Vector4 br = Vector4.zero;
Vector4 v0 = Vector4.zero;
Vector4 v1 = Vector4.zero;
Vector4 v2 = Vector4.zero;
Vector4 hexOffset = new Vector4(-0.5f / width, 0, 0, 0);
int lastIndex = 0;
for (int z = 0; z < length - 1; ++z)
{
for (int x = 0; x < width - 1; ++x)
{
bl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z), 0);
tl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
tr.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
br.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z), 0);
if (z % 2 == 0)
{
v0 = bl;
v1 = tl + hexOffset;
v2 = tr + hexOffset;
if (!Clip(v0, v1, v2))
{
lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
}
v0 = bl;
v1 = tr + hexOffset;
v2 = br;
if (!Clip(v0, v1, v2))
{
lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
}
}
else
{
v0 = bl + hexOffset;
v1 = tl;
v2 = br + hexOffset;
if (!Clip(v0, v1, v2))
{
lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
}
v0 = tr;
v1 = br + hexOffset;
v2 = tl;
if (!Clip(v0, v1, v2))
{
lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
}
}
}
}
for (int i=0;i<vertices.Count;++i)
{
vertices[i] = Remap(vertices[i]);
uvs0[i] = Remap(uvs0[i]);
colors[i] = Remap(colors[i]);
}
Mesh m = water.Mesh;
m.Clear();
m.SetVertices(vertices);
m.SetTriangles(triangles, 0);
m.SetUVs(0, uvs0);
m.SetColors(colors);
m.RecalculateBounds();
m.RecalculateNormals();
//m.RecalculateTangents();
m.name = "Water Mesh";
Bounds bounds = m.bounds;
bounds.extents = new Vector3(bounds.extents.x, 1, bounds.extents.z);
m.bounds = bounds;
PUtilities.DoubleMeshBounds(m);
}
private bool Clip(Vector4 v0, Vector4 v1, Vector4 v2)
{
float mask0 = PUtilities.GetValueBilinear(mask, MASK_RESOLUTION, MASK_RESOLUTION, GetMaskUV(v0));
float mask1 = PUtilities.GetValueBilinear(mask, MASK_RESOLUTION, MASK_RESOLUTION, GetMaskUV(v1));
float mask2 = PUtilities.GetValueBilinear(mask, MASK_RESOLUTION, MASK_RESOLUTION, GetMaskUV(v2));
return mask0 == 0 && mask1 == 0 && mask2 == 0;
}
private Vector2 GetMaskUV(Vector4 v)
{
return new Vector2(Mathf.Clamp01(v.x), Mathf.Clamp01(v.z));
}
private Vector4 Remap(Vector4 v)
{
return new Vector4(
Mathf.Lerp(minX, maxX, v.x),
0,
Mathf.Lerp(minY, maxY, v.z),
0);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d814e0e1985404d418070b8ddaf6dfcd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,485 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine.Rendering;
using DateTime = System.DateTime;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Poseidon
{
public static class PCommon
{
public const string SUPPORT_EMAIL = "support@pinwheel.studio";
public const string BUSINESS_EMAIL = "hello@pinwheel.studio";
public const string YOUTUBE_CHANNEL = "https://www.youtube.com/channel/UCebwuk5CfIe5kolBI9nuBTg";
public const string ONLINE_MANUAL = "https://docs.google.com/document/d/1r4mJD4mcE1flYmJsLvF8N6T6AHnnF1hO0AzlC-VeyWk/edit?usp=sharing";
public const string FACEBOOK_PAGE = "https://www.facebook.com/polaris.terrain";
public const string FORUM = "https://forum.unity.com/threads/released-poseidon-low-poly-water-system-builtin-lwrp.746138/";
public const string DISCORD = "https://discord.gg/6kkDvj6";
public const int PREVIEW_TEXTURE_SIZE = 512;
public const int TEXTURE_SIZE_MIN = 1;
public const int TEXTURE_SIZE_MAX = 8192;
public static PRenderPipelineType CurrentRenderPipeline
{
get
{
RenderPipelineAsset rpAsset = GraphicsSettings.renderPipelineAsset;
if (rpAsset == null)
{
return PRenderPipelineType.Builtin;
}
else if (rpAsset.GetType().Name.Equals("UniversalRenderPipelineAsset"))
{
return PRenderPipelineType.Universal;
}
else
{
return PRenderPipelineType.Unsupported;
}
}
}
private static Vector2[] fullRectUvPoints;
public static Vector2[] FullRectUvPoints
{
get
{
if (fullRectUvPoints == null)
{
fullRectUvPoints = new Vector2[]
{
Vector2.zero,
Vector2.up,
Vector2.one,
Vector2.right
};
}
return fullRectUvPoints;
}
}
private static Mesh emptyMesh;
public static Mesh EmptyMesh
{
get
{
if (emptyMesh == null)
{
emptyMesh = new Mesh();
}
return emptyMesh;
}
}
private static Material[] emptyMaterials;
public static Material[] EmptyMaterials
{
get
{
if (emptyMaterials==null)
{
emptyMaterials = new Material[0];
}
return emptyMaterials;
}
}
public static Rect UnitRect
{
get
{
return new Rect(0, 0, 1, 1);
}
}
public static string GetUniqueID()
{
string s = GetTimeTick().ToString();
return Reverse(s);
}
public static long GetTimeTick()
{
DateTime time = DateTime.Now;
return time.Ticks;
}
public static string Reverse(string s)
{
char[] chars = s.ToCharArray();
System.Array.Reverse(chars);
return new string(chars);
}
public static void SetDirty(Object o)
{
#if UNITY_EDITOR
EditorUtility.SetDirty(o);
#endif
}
public static void AddObjectToAsset(Object objectToAdd, Object asset)
{
#if UNITY_EDITOR
AssetDatabase.AddObjectToAsset(objectToAdd, asset);
#endif
}
public static Texture2D CreateTexture(int resolution, Color fill, TextureFormat format = TextureFormat.ARGB32)
{
Texture2D t = new Texture2D(resolution, resolution, format, false);
Color[] colors = new Color[resolution * resolution];
PUtilities.Fill(colors, fill);
t.SetPixels(colors);
t.Apply();
return t;
}
public static void CopyToRT(Texture t, RenderTexture rt)
{
RenderTexture.active = rt;
Graphics.Blit(t, rt);
RenderTexture.active = null;
}
public static void CopyFromRT(Texture2D t, RenderTexture rt)
{
RenderTexture.active = rt;
t.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
t.Apply();
RenderTexture.active = null;
}
public static void CopyTexture(Texture2D src, Texture2D des)
{
RenderTexture rt = new RenderTexture(des.width, des.height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default);
CopyToRT(src, rt);
CopyFromRT(des, rt);
rt.Release();
PUtilities.DestroyObject(rt);
}
public static Texture2D CloneTexture(Texture2D t)
{
RenderTexture rt = new RenderTexture(t.width, t.height, 0, RenderTextureFormat.ARGB32);
CopyToRT(t, rt);
Texture2D result = new Texture2D(t.width, t.height, TextureFormat.ARGB32, false);
result.filterMode = t.filterMode;
result.wrapMode = t.wrapMode;
CopyFromRT(result, rt);
rt.Release();
Object.DestroyImmediate(rt);
return result;
}
public static void FillTexture(Texture2D t, Color c)
{
Color[] colors = new Color[t.width * t.height];
PUtilities.Fill(colors, c);
t.SetPixels(colors);
t.Apply();
}
public static void FillTexture(RenderTexture rt, Color c)
{
Texture2D tex = new Texture2D(1, 1, TextureFormat.ARGB32, false);
tex.SetPixel(0, 0, c);
tex.Apply();
CopyToRT(tex, rt);
PUtilities.DestroyObject(tex);
}
public static Texture2D CloneAndResizeTexture(Texture2D t, int width, int height)
{
RenderTexture rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
CopyToRT(t, rt);
Texture2D result = new Texture2D(width, height, TextureFormat.ARGB32, false);
result.filterMode = t.filterMode;
result.wrapMode = t.wrapMode;
CopyFromRT(result, rt);
rt.Release();
Object.DestroyImmediate(rt);
return result;
}
public static RenderTexture CopyToRT(Texture src, int startX, int startY, int width, int height, Color defaultColor)
{
int endX = startX + width - 1;
int endY = startY + height - 1;
Vector2 startUV = new Vector2(
PUtilities.InverseLerpUnclamped(0, src.width - 1, startX),
PUtilities.InverseLerpUnclamped(0, src.height - 1, startY));
Vector2 endUV = new Vector2(
PUtilities.InverseLerpUnclamped(0, src.width - 1, endX),
PUtilities.InverseLerpUnclamped(0, src.height - 1, endY));
Material mat = PInternalMaterials.CopyTextureMaterial;
mat.SetTexture("_MainTex", src);
mat.SetVector("_StartUV", startUV);
mat.SetVector("_EndUV", endUV);
mat.SetColor("_DefaultColor", defaultColor);
mat.SetPass(0);
RenderTexture rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
RenderTexture.active = rt;
Graphics.Blit(src, mat);
RenderTexture.active = null;
return rt;
}
public static void DrawTexture(RenderTexture rt, Texture texture, Rect uvRect, Material mat, int pass = 0)
{
if (mat == null)
mat = PInternalMaterials.UnlitTextureMaterial;
RenderTexture.active = rt;
GL.PushMatrix();
mat.SetTexture("_MainTex", texture);
mat.SetPass(pass);
GL.LoadOrtho();
GL.Begin(GL.QUADS);
GL.TexCoord(new Vector3(0, 0, 0));
GL.Vertex3(uvRect.min.x, uvRect.min.y, 0);
GL.TexCoord(new Vector3(0, 1, 0));
GL.Vertex3(uvRect.min.x, uvRect.max.y, 0);
GL.TexCoord(new Vector3(1, 1, 0));
GL.Vertex3(uvRect.max.x, uvRect.max.y, 0);
GL.TexCoord(new Vector3(1, 0, 0));
GL.Vertex3(uvRect.max.x, uvRect.min.y, 0);
GL.End();
GL.PopMatrix();
RenderTexture.active = null;
}
public static void DrawTriangle(RenderTexture rt, Vector2 v0, Vector2 v1, Vector2 v2, Color c)
{
Material mat = PInternalMaterials.SolidColorMaterial;
mat.SetColor("_Color", c);
RenderTexture.active = rt;
GL.PushMatrix();
mat.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.TRIANGLES);
GL.Vertex3(v0.x, v0.y, 0);
GL.Vertex3(v1.x, v1.y, 0);
GL.Vertex3(v2.x, v2.y, 0);
GL.End();
GL.PopMatrix();
RenderTexture.active = null;
}
public static void DrawQuad(RenderTexture rt, Vector2[] quadCorners, Material mat, int pass)
{
RenderTexture.active = rt;
GL.PushMatrix();
mat.SetPass(pass);
GL.LoadOrtho();
GL.Begin(GL.QUADS);
GL.TexCoord(new Vector3(0, 0, 0));
GL.Vertex3(quadCorners[0].x, quadCorners[0].y, 0);
GL.TexCoord(new Vector3(0, 1, 0));
GL.Vertex3(quadCorners[1].x, quadCorners[1].y, 0);
GL.TexCoord(new Vector3(1, 1, 0));
GL.Vertex3(quadCorners[2].x, quadCorners[2].y, 0);
GL.TexCoord(new Vector3(1, 0, 0));
GL.Vertex3(quadCorners[3].x, quadCorners[3].y, 0);
GL.End();
GL.PopMatrix();
RenderTexture.active = null;
}
public static List<System.Type> GetAllLoadedTypes()
{
List<System.Type> loadedTypes = new List<System.Type>();
List<string> typeName = new List<string>();
foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var t in assembly.GetTypes())
{
if (t.IsVisible && !t.IsGenericType)
{
typeName.Add(t.Name);
loadedTypes.Add(t);
}
}
}
return loadedTypes;
}
public static IEnumerable<Rect> CompareHeightMap(int gridSize, Color[] oldValues, Color[] newValues)
{
if (oldValues.LongLength != newValues.LongLength)
{
return new Rect[1] { new Rect(0, 0, 1, 1) };
}
Rect[] rects = new Rect[gridSize * gridSize];
for (int x = 0; x < gridSize; ++x)
{
for (int z = 0; z < gridSize; ++z)
{
rects[PUtilities.To1DIndex(x, z, gridSize)] = GetUvRange(gridSize, x, z);
}
}
HashSet<Rect> dirtyRects = new HashSet<Rect>();
int index = 0;
int resolution = Mathf.RoundToInt(Mathf.Sqrt(newValues.LongLength));
for (int rectIndex = 0; rectIndex < rects.Length; ++rectIndex)
{
Rect r = rects[rectIndex];
int startX = (int)Mathf.Lerp(0, resolution - 1, r.min.x);
int startY = (int)Mathf.Lerp(0, resolution - 1, r.min.y);
int endX = (int)Mathf.Lerp(0, resolution - 1, r.max.x);
int endY = (int)Mathf.Lerp(0, resolution - 1, r.max.y);
for (int x = startX; x <= endX; ++x)
{
for (int y = startY; y <= endY; ++y)
{
index = PUtilities.To1DIndex(x, y, resolution);
if (oldValues[index].r == newValues[index].r &&
oldValues[index].g == newValues[index].g &&
oldValues[index].b == newValues[index].b &&
oldValues[index].a == newValues[index].a)
continue;
dirtyRects.Add(r);
Rect hRect = new Rect();
hRect.size = new Vector2(r.width * 1.2f, r.height);
hRect.center = r.center;
dirtyRects.Add(hRect);
Rect vRect = new Rect();
vRect.size = new Vector2(r.width, r.height * 1.2f);
vRect.center = r.center;
dirtyRects.Add(vRect);
break;
}
if (dirtyRects.Contains(r))
break;
}
}
return dirtyRects;
}
public static Rect GetUvRange(int gridSize, int x, int z)
{
Vector2 position = new Vector2(x * 1.0f / gridSize, z * 1.0f / gridSize);
Vector2 size = Vector2.one / gridSize;
return new Rect(position, size);
}
public static Texture2D CreateTextureFromCurve(AnimationCurve curve, int width, int height)
{
Texture2D t = new Texture2D(width, height, TextureFormat.ARGB32, false);
t.wrapMode = TextureWrapMode.Clamp;
Color[] colors = new Color[width * height];
for (int x = 0; x < width; ++x)
{
float f = Mathf.InverseLerp(0, width - 1, x);
float value = curve.Evaluate(f);
Color c = new Color(value, value, value, value);
for (int y = 0; y < height; ++y)
{
colors[PUtilities.To1DIndex(x, y, width)] = c;
}
}
t.filterMode = FilterMode.Bilinear;
t.SetPixels(colors);
t.Apply();
return t;
}
public static Vector3[] GetBrushQuadCorners(Vector3 center, float radius, float rotation)
{
Matrix4x4 matrix = Matrix4x4.Rotate(Quaternion.Euler(0, rotation, 0));
Vector3[] corners = new Vector3[]
{
center + matrix.MultiplyPoint(new Vector3(-1,0,-1)*radius),
center + matrix.MultiplyPoint(new Vector3(-1,0,1)*radius),
center + matrix.MultiplyPoint(new Vector3(1,0,1)*radius),
center + matrix.MultiplyPoint(new Vector3(1,0,-1)*radius)
};
return corners;
}
//public static void RegisterBeginRender(Camera.CameraCallback callback)
//{
// Camera.onPreCull += callback;
//}
//public static void RegisterBeginRenderSRP(System.Action<Camera> callback)
//{
// RenderPipelineManager.beginCameraRendering += callback;
//}
//public static void UnregisterBeginRender(Camera.CameraCallback callback)
//{
// Camera.onPreCull -= callback;
//}
//public static void UnregisterBeginRenderSRP(System.Action<Camera> callback)
//{
// RenderPipeline.beginCameraRendering -= callback;
//}
//public static void RegisterEndRender(Camera.CameraCallback callback)
//{
// Camera.onPostRender += callback;
//}
public static void ClearRT(RenderTexture rt)
{
RenderTexture.active = rt;
GL.Clear(true, true, Color.clear);
RenderTexture.active = null;
}
public static void SetMaterialKeywordActive(Material mat, string keyword, bool active)
{
if (active)
{
mat.EnableKeyword(keyword);
}
else
{
mat.DisableKeyword(keyword);
}
}
public static void Editor_ProgressBar(string title, string detail, float percent)
{
#if UNITY_EDITOR
EditorUtility.DisplayProgressBar(title, detail, percent);
#endif
}
public static void Editor_CancelableProgressBar(string title, string detail, float percent)
{
#if UNITY_EDITOR
if (EditorUtility.DisplayCancelableProgressBar(title, detail, percent))
{
throw new PProgressCancelledException();
}
#endif
}
public static void Editor_ClearProgressBar()
{
#if UNITY_EDITOR
EditorUtility.ClearProgressBar();
#endif
}
public static Camera CreateCamera()
{
GameObject g = new GameObject();
Camera cam = g.AddComponent<Camera>();
return cam;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a20389aff7ce82458ed92bcd6705f3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Poseidon;
namespace Pinwheel.Poseidon
{
public class PCustomMeshBaker : IPMeshCreator
{
private PWater water;
private Vector3[] verts;
private int[] tris;
private Bounds meshBound;
public void Create(PWater profile)
{
this.water = profile;
Init();
Bake();
}
private void Init()
{
Mesh srcMesh = water.SourceMesh;
verts = srcMesh.vertices;
tris = srcMesh.triangles;
srcMesh.RecalculateBounds();
meshBound = srcMesh.bounds;
}
private void Bake()
{
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector4> uvs0 = new List<Vector4>(); //contain neighbor vertex position, for normal re-construction
List<Color> colors = new List<Color>(); //contain neighbor vertex position, for normal re-construction
List<Vector3> normals = new List<Vector3>();
Vector4 v0 = Vector4.zero;
Vector4 v1 = Vector4.zero;
Vector4 v2 = Vector4.zero;
int i0, i1, i2;
int trisCount = tris.Length / 3;
for (int i = 0; i < trisCount; ++i)
{
i0 = i * 3 + 0;
i1 = i * 3 + 1;
i2 = i * 3 + 2;
v0 = RemapVertex(ref verts[tris[i0]], ref meshBound);
v1 = RemapVertex(ref verts[tris[i1]], ref meshBound);
v2 = RemapVertex(ref verts[tris[i2]], ref meshBound);
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
triangles.Add(i0);
triangles.Add(i1);
triangles.Add(i2);
}
Mesh m = water.Mesh;
m.Clear();
m.SetVertices(vertices);
m.SetTriangles(triangles, 0);
m.SetUVs(0, uvs0);
m.SetColors(colors);
m.name = "Water Mesh";
m.RecalculateBounds();
PUtilities.DoubleMeshBounds(m);
}
private Vector3 RemapVertex(ref Vector3 v, ref Bounds bounds)
{
Vector3 n = Vector3.zero;
n.Set(
Mathf.InverseLerp(bounds.min.x, bounds.max.x, v.x) - 0.5f,
Mathf.InverseLerp(bounds.min.y, bounds.max.y, v.y) - 0.5f,
Mathf.InverseLerp(bounds.min.z, bounds.max.z, v.z) - 0.5f);
return n;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1dea4f30c3952b54394a53e39ec51367
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Poseidon;
namespace Pinwheel.Poseidon
{
public class PDiamondMeshCreator : IPMeshCreator
{
private Vector2[,] grid;
private PWater water;
public void Create(PWater water)
{
this.water = water;
Init();
GenerateGrid();
UpdateMesh();
}
private void Init()
{
int resolution = water.MeshResolution;
int length = resolution + 1;
grid = new Vector2[length, length];
}
private void GenerateGrid()
{
int length = grid.GetLength(0);
int width = grid.GetLength(1);
Vector2 p = Vector2.zero;
for (int z = 0; z < length; ++z)
{
for (int x = 0; x < width; ++x)
{
p.Set(
Mathf.InverseLerp(0, width - 1, x),
Mathf.InverseLerp(0, length - 1, z));
grid[z, x] = p;
}
}
}
private void UpdateMesh()
{
//vertices
int length = grid.GetLength(0);
int width = grid.GetLength(1);
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector4> uvs0 = new List<Vector4>(); //contain neighbor vertex position, for normal re-construction
List<Color> colors = new List<Color>(); //contain neighbor vertex position, for normal re-construction
Vector4 bl = Vector4.zero;
Vector4 tl = Vector4.zero;
Vector4 tr = Vector4.zero;
Vector4 br = Vector4.zero;
for (int z = 0; z < length - 1; ++z)
{
for (int x = 0; x < width - 1; ++x)
{
int lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
triangles.Add(lastIndex + 3);
triangles.Add(lastIndex + 4);
triangles.Add(lastIndex + 5);
bl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z), 0);
tl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
tr.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
br.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z), 0);
if ((x + z) % 2 == 0)
{
vertices.Add(bl); uvs0.Add(tl); colors.Add(tr);
vertices.Add(tl); uvs0.Add(tr); colors.Add(bl);
vertices.Add(tr); uvs0.Add(bl); colors.Add(tl);
vertices.Add(bl); uvs0.Add(tr); colors.Add(br);
vertices.Add(tr); uvs0.Add(br); colors.Add(bl);
vertices.Add(br); uvs0.Add(bl); colors.Add(tr);
}
else
{
vertices.Add(bl); uvs0.Add(tl); colors.Add(br);
vertices.Add(tl); uvs0.Add(br); colors.Add(bl);
vertices.Add(br); uvs0.Add(bl); colors.Add(tl);
vertices.Add(tr); uvs0.Add(br); colors.Add(tl);
vertices.Add(br); uvs0.Add(tl); colors.Add(tr);
vertices.Add(tl); uvs0.Add(tr); colors.Add(br);
}
}
}
Mesh m = water.Mesh;
m.Clear();
m.SetVertices(vertices);
m.SetTriangles(triangles, 0);
m.SetUVs(0, uvs0);
m.SetColors(colors);
m.RecalculateBounds();
m.RecalculateNormals();
//m.RecalculateTangents();
m.name = "Water Mesh";
Bounds bounds = m.bounds;
bounds.extents = new Vector3(bounds.extents.x, (bounds.extents.x + bounds.extents.z) * 0.5f, bounds.extents.z);
m.bounds = bounds;
PUtilities.DoubleMeshBounds(m);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5882ecbdb39c5214192b8e76416640d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,135 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Poseidon;
namespace Pinwheel.Poseidon
{
public class PHexMeshCreator : IPMeshCreator
{
private Vector2[,] grid;
private PWater water;
public void Create(PWater water)
{
this.water = water;
Init();
GenerateGrid();
UpdateMesh();
}
private void Init()
{
int resolution = water.MeshResolution;
int length = resolution + 1;
grid = new Vector2[length, length];
}
private void GenerateGrid()
{
int length = grid.GetLength(0);
int width = grid.GetLength(1);
Vector2 p = Vector2.zero;
for (int z = 0; z < length; ++z)
{
for (int x = 0; x < width; ++x)
{
p.Set(
Mathf.InverseLerp(0, width - 1, x),
Mathf.InverseLerp(0, length - 1, z));
grid[z, x] = p;
}
}
}
private void UpdateMesh()
{
//vertices
int length = grid.GetLength(0);
int width = grid.GetLength(1);
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector4> uvs0 = new List<Vector4>(); //contain neighbor vertex position, for normal re-construction
List<Color> colors = new List<Color>(); //contain neighbor vertex position, for normal re-construction
Vector4 bl = Vector4.zero;
Vector4 tl = Vector4.zero;
Vector4 tr = Vector4.zero;
Vector4 br = Vector4.zero;
Vector4 v0 = Vector4.zero;
Vector4 v1 = Vector4.zero;
Vector4 v2 = Vector4.zero;
Vector4 hexOffset = new Vector4(-0.5f / width, 0, 0, 0);
for (int z = 0; z < length - 1; ++z)
{
for (int x = 0; x < width - 1; ++x)
{
int lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
triangles.Add(lastIndex + 3);
triangles.Add(lastIndex + 4);
triangles.Add(lastIndex + 5);
bl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z), 0);
tl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
tr.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
br.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z), 0);
if (z % 2 == 0)
{
v0 = bl;
v1 = tl + hexOffset;
v2 = tr + hexOffset;
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
v0 = bl;
v1 = tr + hexOffset;
v2 = br;
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
}
else
{
v0 = bl + hexOffset;
v1 = tl;
v2 = br + hexOffset;
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
v0 = tr;
v1 = br + hexOffset;
v2 = tl;
vertices.Add(v0); uvs0.Add(v1); colors.Add(v2);
vertices.Add(v1); uvs0.Add(v2); colors.Add(v0);
vertices.Add(v2); uvs0.Add(v0); colors.Add(v1);
}
}
}
Mesh m = water.Mesh;
m.Clear();
m.SetVertices(vertices);
m.SetTriangles(triangles, 0);
m.SetUVs(0, uvs0);
m.SetColors(colors);
m.RecalculateBounds();
m.RecalculateNormals();
//m.RecalculateTangents();
m.name = "Water Mesh";
Bounds bounds = m.bounds;
bounds.extents = new Vector3(bounds.extents.x, (bounds.extents.x + bounds.extents.z) * 0.5f, bounds.extents.z);
m.bounds = bounds;
PUtilities.DoubleMeshBounds(m);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 690a8037c9d996b4a8c4725a23a917f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public enum PLightingModel
{
PhysicalBased, BlinnPhong, Lambert
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9695aa1fb9a921c44bb65757dbcc7d65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,326 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine.Rendering;
namespace Pinwheel.Poseidon
{
public static class PMat
{
public const string KW_LIGHTING_BLINN_PHONG = "LIGHTING_BLINN_PHONG";
public const string KW_LIGHTING_LAMBERT = "LIGHTING_LAMBERT";
public const string KW_FLAT_LIGHTING = "FLAT_LIGHTING";
public const int QUEUE_TRANSPARENT = 3000;
public const string COLOR = "_Color";
public const string SPEC_COLOR = "_Specular";
public const string SPEC_COLOR_BLINN_PHONG = "_SpecColor";
public const string SMOOTHNESS = "_Smoothness";
public const string KW_MESH_NOISE = "MESH_NOISE";
public const string MESH_NOISE = "_MeshNoise";
public const string KW_LIGHT_ABSORPTION = "LIGHT_ABSORPTION";
public const string DEPTH_COLOR = "_DepthColor";
public const string MAX_DEPTH = "_MaxDepth";
public const string KW_FOAM = "FOAM";
public const string KW_FOAM_HQ = "FOAM_HQ";
public const string KW_FOAM_CREST = "FOAM_CREST";
public const string KW_FOAM_SLOPE = "FOAM_SLOPE";
public const string FOAM_COLOR = "_FoamColor";
public const string FOAM_DISTANCE = "_FoamDistance";
public const string FOAM_NOISE_SCALE_HQ = "_FoamNoiseScaleHQ";
public const string FOAM_NOISE_SPEED_HQ = "_FoamNoiseSpeedHQ";
public const string SHORELINE_FOAM_STRENGTH = "_ShorelineFoamStrength";
public const string CREST_FOAM_STRENGTH = "_CrestFoamStrength";
public const string CREST_MAX_DEPTH = "_CrestMaxDepth";
public const string SLOPE_FOAM_STRENGTH = "_SlopeFoamStrength";
public const string SLOPE_FOAM_FLOW_SPEED = "_SlopeFoamFlowSpeed";
public const string SLOPE_FOAM_DISTANCE = "_SlopeFoamDistance";
public const string RIPPLE_HEIGHT = "_RippleHeight";
public const string RIPPLE_SPEED = "_RippleSpeed";
public const string RIPPLE_NOISE_SCALE = "_RippleNoiseScale";
public const string KW_WAVE = "WAVE";
public const string WAVE_DIRECTION = "_WaveDirection";
public const string WAVE_SPEED = "_WaveSpeed";
public const string WAVE_HEIGHT = "_WaveHeight";
public const string WAVE_LENGTH = "_WaveLength";
public const string WAVE_STEEPNESS = "_WaveSteepness";
public const string WAVE_DEFORM = "_WaveDeform";
public const string KW_WAVE_MASK = "WAVE_MASK";
public const string WAVE_MASK = "_WaveMask";
public const string WAVE_MASK_BOUNDS = "_WaveMaskBounds";
public const string FRESNEL_STRENGTH = "_FresnelStrength";
public const string FRESNEL_BIAS = "_FresnelBias";
public const string KW_REFLECTION = "REFLECTION";
public const string KW_REFLECTION_BLUR = "REFLECTION_BLUR";
public const string REFLECTION_TEX = "_ReflectionTex";
public const string REFLECTION_DISTORTION_STRENGTH = "_ReflectionDistortionStrength";
public const string KW_REFRACTION = "REFRACTION";
public const string REFRACTION_TEX = "_RefractionTex";
public const string REFRACTION_DISTORTION_STRENGTH = "_RefractionDistortionStrength";
public const string KW_CAUSTIC = "CAUSTIC";
public const string CAUSTIC_TEX = "_CausticTex";
public const string CAUSTIC_SIZE = "_CausticSize";
public const string CAUSTIC_STRENGTH = "_CausticStrength";
public const string CAUSTIC_DISTORTION_STRENGTH = "_CausticDistortionStrength";
public const string KW_BACK_FACE = "BACK_FACE";
public const string NOISE_TEX = "_NoiseTex";
public const string TIME = "_PoseidonTime";
public const string SINE_TIME = "_PoseidonSineTime";
public const string KW_AURA_LIGHTING = "AURA_LIGHTING";
public const string AURA_LIGHTING_FACTOR = "_AuraLightingFactor";
public const string KW_AURA_FOG = "AURA_FOG";
public const string PP_NOISE_TEX = "_NoiseTex";
public const string PP_INTENSITY = "_Intensity";
public const string PP_WATER_LEVEL = "_WaterLevel";
public const string PP_MAX_DEPTH = "_MaxDepth";
public const string PP_SURFACE_COLOR_BOOST = "_SurfaceColorBoost";
public const string PP_SHALLOW_FOG_COLOR = "_ShallowFogColor";
public const string PP_DEEP_FOG_COLOR = "_DeepFogColor";
public const string PP_VIEW_DISTANCE = "_ViewDistance";
public const string KW_PP_CAUSTIC = "CAUSTIC";
public const string PP_CAUSTIC_TEX = "_CausticTex";
public const string PP_CAUSTIC_SIZE = "_CausticSize";
public const string PP_CAUSTIC_STRENGTH = "_CausticStrength";
public const string KW_PP_DISTORTION = "DISTORTION";
public const string PP_DISTORTION_TEX = "_DistortionTex";
public const string PP_DISTORTION_STRENGTH = "_DistortionStrength";
public const string PP_WATER_FLOW_SPEED = "_WaterFlowSpeed";
public const string PP_CAMERA_VIEW_DIR = "_CameraViewDir";
public const string PP_CAMERA_FOV = "_CameraFov";
public const string PP_CAMERA_TO_WORLD_MATRIX = "_CameraToWorldMatrix";
public const string PP_WET_LENS_TEX = "_WetLensTex";
public const string PP_WET_LENS_STRENGTH = "_Strength";
private static Material activeMaterial;
public static void SetActiveMaterial(Material mat)
{
activeMaterial = mat;
}
public static void GetColor(string prop, ref Color value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
value = activeMaterial.GetColor(prop);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void GetFloat(string prop, ref float value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
value = activeMaterial.GetFloat(prop);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void GetVector(string prop, ref Vector4 value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
value = activeMaterial.GetVector(prop);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void GetTexture(string prop, ref Texture value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
value = activeMaterial.GetTexture(prop);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void GetKeywordEnabled(string kw, ref bool value)
{
try
{
value = activeMaterial.IsKeywordEnabled(kw);
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void SetColor(string prop, Color value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
activeMaterial.SetColor(prop, value);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void SetFloat(string prop, float value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
activeMaterial.SetFloat(prop, value);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void SetVector(string prop, Vector4 value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
activeMaterial.SetVector(prop, value);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void SetTexture(string prop, Texture value)
{
try
{
if (activeMaterial.HasProperty(prop))
{
activeMaterial.SetTexture(prop, value);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void SetKeywordEnable(string kw, bool enable)
{
try
{
if (enable)
{
activeMaterial.EnableKeyword(kw);
}
else
{
activeMaterial.DisableKeyword(kw);
}
}
catch (NullReferenceException nullEx)
{
Debug.LogError(nullEx.ToString());
}
catch { }
}
public static void SetOverrideTag(string tag, string value)
{
activeMaterial.SetOverrideTag(tag, value);
}
public static void SetRenderQueue(int queue)
{
activeMaterial.renderQueue = queue;
}
public static void SetRenderQueue(RenderQueue queue)
{
activeMaterial.renderQueue = (int)queue;
}
public static void SetSourceBlend(BlendMode mode)
{
activeMaterial.SetInt("_SrcBlend", (int)mode);
}
public static void SetDestBlend(BlendMode mode)
{
activeMaterial.SetInt("_DstBlend", (int)mode);
}
public static void SetZWrite(bool value)
{
activeMaterial.SetInt("ZWrite", value ? 1 : 0);
}
public static void SetBlend(bool value)
{
activeMaterial.SetInt("_Blend", value ? 1 : 0);
}
public static void SetShader(Shader shader)
{
int queue = activeMaterial.renderQueue;
activeMaterial.shader = shader;
activeMaterial.renderQueue = queue;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab270e5a2a0b3994b844711d06c59eb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public enum PPlaneMeshPattern
{
Hexagon, Diamond, Quad
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a018d04e489ea9845b0439051cc4c628
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,216 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Poseidon
{
//[CreateAssetMenu(menuName = "Poseidon/Settings")]
public class PPoseidonSettings : ScriptableObject
{
private static PPoseidonSettings instance;
public static PPoseidonSettings Instance
{
get
{
if (instance == null)
{
instance = Resources.Load<PPoseidonSettings>("PoseidonSettings");
if (instance == null)
{
instance = ScriptableObject.CreateInstance<PPoseidonSettings>();
}
}
return instance;
}
}
[SerializeField]
private PWaterProfile calmWaterProfile;
public PWaterProfile CalmWaterProfile
{
get
{
return calmWaterProfile;
}
set
{
calmWaterProfile = value;
}
}
[SerializeField]
private PWaterProfile calmWaterHQProfile;
public PWaterProfile CalmWaterHQProfile
{
get
{
return calmWaterHQProfile;
}
set
{
calmWaterHQProfile = value;
}
}
[SerializeField]
private Texture2D noiseTexture;
public Texture2D NoiseTexture
{
get
{
return noiseTexture;
}
set
{
noiseTexture = value;
}
}
[SerializeField]
private Texture2D defaultNormalMap;
public Texture2D DefaultNormalMap
{
get
{
return defaultNormalMap;
}
set
{
defaultNormalMap = value;
}
}
[SerializeField]
private Texture2D defaultUnderwaterDistortionMap;
public Texture2D DefaultUnderwaterDistortionMap
{
get
{
return defaultUnderwaterDistortionMap;
}
set
{
defaultUnderwaterDistortionMap = value;
}
}
[SerializeField]
private Texture2D defaultWetLensDistortionMap;
public Texture2D DefaultWetLensDistortionMap
{
get
{
return defaultWetLensDistortionMap;
}
set
{
defaultWetLensDistortionMap = value;
}
}
#if UNITY_POST_PROCESSING_STACK_V2
[SerializeField]
private Shader underwaterShader;
public Shader UnderwaterShader
{
get
{
if (underwaterShader == null)
{
underwaterShader = Shader.Find("Hidden/Poseidon/Underwater");
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
return underwaterShader;
}
set
{
underwaterShader = value;
}
}
[SerializeField]
private Shader wetLensShader;
public Shader WetLensShader
{
get
{
if (wetLensShader == null)
{
wetLensShader = Shader.Find("Hidden/Poseidon/WetLens");
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
return wetLensShader;
}
set
{
wetLensShader = value;
}
}
#endif
#if POSEIDON_URP
[SerializeField]
private Shader underwaterShaderURP;
public Shader UnderwaterShaderURP
{
get
{
if (underwaterShaderURP == null)
{
underwaterShaderURP = Shader.Find("Hidden/Poseidon/UnderwaterURP");
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
return underwaterShaderURP;
}
set
{
underwaterShaderURP = value;
}
}
[SerializeField]
private Shader wetLensShaderURP;
public Shader WetLensShaderURP
{
get
{
if (wetLensShaderURP == null)
{
wetLensShaderURP = Shader.Find("Hidden/Poseidon/WetLensURP");
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
return wetLensShaderURP;
}
set
{
wetLensShaderURP = value;
}
}
#endif
[SerializeField]
private PInternalShaderSettings internalShaders;
public PInternalShaderSettings InternalShaders
{
get
{
return internalShaders;
}
set
{
internalShaders = value;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e940843e5b345034cae3aa441e2c2309
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Poseidon;
namespace Pinwheel.Poseidon
{
public class PQuadMeshCreator : IPMeshCreator
{
private Vector2[,] grid;
private PWater water;
public void Create(PWater water)
{
this.water = water;
Init();
GenerateGrid();
UpdateMesh();
}
private void Init()
{
int resolution = water.MeshResolution;
int length = resolution + 1;
grid = new Vector2[length, length];
}
private void GenerateGrid()
{
int length = grid.GetLength(0);
int width = grid.GetLength(1);
Vector2 p = Vector2.zero;
for (int z = 0; z < length; ++z)
{
for (int x = 0; x < width; ++x)
{
p.Set(
Mathf.InverseLerp(0, width - 1, x),
Mathf.InverseLerp(0, length - 1, z));
grid[z, x] = p;
}
}
}
private void UpdateMesh()
{
//vertices
int length = grid.GetLength(0);
int width = grid.GetLength(1);
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector4> uvs0 = new List<Vector4>(); //contain neighbor vertex position, for normal re-construction
List<Color> colors = new List<Color>(); //contain neighbor vertex position, for normal re-construction
Vector4 bl = Vector4.zero;
Vector4 tl = Vector4.zero;
Vector4 tr = Vector4.zero;
Vector4 br = Vector4.zero;
for (int z = 0; z < length - 1; ++z)
{
for (int x = 0; x < width - 1; ++x)
{
int lastIndex = vertices.Count;
triangles.Add(lastIndex + 0);
triangles.Add(lastIndex + 1);
triangles.Add(lastIndex + 2);
triangles.Add(lastIndex + 3);
triangles.Add(lastIndex + 4);
triangles.Add(lastIndex + 5);
bl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z), 0);
tl.Set(Mathf.InverseLerp(0, width - 1, x), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
tr.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z + 1), 0);
br.Set(Mathf.InverseLerp(0, width - 1, x + 1), 0, Mathf.InverseLerp(0, length - 1, z), 0);
vertices.Add(bl); uvs0.Add(tl); colors.Add(tr);
vertices.Add(tl); uvs0.Add(tr); colors.Add(bl);
vertices.Add(tr); uvs0.Add(bl); colors.Add(tl);
vertices.Add(bl); uvs0.Add(tr); colors.Add(br);
vertices.Add(tr); uvs0.Add(br); colors.Add(bl);
vertices.Add(br); uvs0.Add(bl); colors.Add(tr);
}
}
Mesh m = water.Mesh;
m.Clear();
m.SetVertices(vertices);
m.SetTriangles(triangles, 0);
m.SetUVs(0, uvs0);
m.SetColors(colors);
m.name = "Water Mesh";
m.RecalculateBounds();
m.RecalculateNormals();
Bounds bounds = m.bounds;
bounds.extents = new Vector3(bounds.extents.x, (bounds.extents.x + bounds.extents.z) * 0.5f, bounds.extents.z);
m.bounds = bounds;
PUtilities.DoubleMeshBounds(m);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4556af04261c90445bb49f0e2bb7b537
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,285 @@
using System.Collections.Generic;
using UnityEngine;
using System;
namespace Pinwheel.Poseidon
{
[System.Serializable]
public class PSpline : IDisposable
{
[SerializeField]
private List<PSplineAnchor> anchors;
public List<PSplineAnchor> Anchors
{
get
{
if (anchors == null)
{
anchors = new List<PSplineAnchor>();
}
return anchors;
}
}
[SerializeField]
private List<PSplineSegment> segments;
public List<PSplineSegment> Segments
{
get
{
if (segments == null)
{
segments = new List<PSplineSegment>();
}
return segments;
}
}
public bool HasBranch
{
get
{
return CheckHasBranch();
}
}
public bool IsSegmentValid(int segmentIndex)
{
PSplineSegment s = Segments[segmentIndex];
if (s == null)
return false;
bool startIndexValid =
s.StartIndex >= 0 &&
s.StartIndex < Anchors.Count &&
Anchors[s.StartIndex] != null;
bool endIndexValid =
s.EndIndex >= 0 &&
s.EndIndex < Anchors.Count &&
Anchors[s.EndIndex] != null;
return startIndexValid && endIndexValid;
}
public void AddAnchor(PSplineAnchor a)
{
Anchors.Add(a);
}
public void RemoveAnchor(int index)
{
PSplineAnchor a = Anchors[index];
List<int> segmentIndices = FindSegments(index);
for (int i = 0; i < segmentIndices.Count; ++i)
{
int sIndex = segmentIndices[i];
Segments[sIndex].Dispose();
}
Segments.RemoveAll(s => s.StartIndex == index || s.EndIndex == index);
Segments.ForEach(s =>
{
if (s.StartIndex > index)
s.StartIndex -= 1;
if (s.EndIndex > index)
s.EndIndex -= 1;
});
Anchors.RemoveAt(index);
}
public PSplineSegment AddSegment(int startIndex, int endIndex)
{
PSplineSegment s = Segments.Find(s0 =>
(s0.StartIndex == startIndex && s0.EndIndex == endIndex) ||
(s0.StartIndex == endIndex && s0.EndIndex == startIndex));
if (s != null)
return s;
PSplineSegment newSegment = new PSplineSegment();
newSegment.StartIndex = startIndex;
newSegment.EndIndex = endIndex;
Segments.Add(newSegment);
PSplineAnchor startAnchor = Anchors[newSegment.StartIndex];
PSplineAnchor endAnchor = Anchors[newSegment.EndIndex];
Vector3 direction = (endAnchor.Position - startAnchor.Position).normalized;
float length = (endAnchor.Position - startAnchor.Position).magnitude / 3;
newSegment.StartTangent = startAnchor.Position + direction * length;
newSegment.EndTangent = endAnchor.Position - direction * length;
return newSegment;
}
public void RemoveSegment(int index)
{
Segments[index].Dispose();
Segments.RemoveAt(index);
}
public Vector3 EvaluatePosition(int segmentIndex, float t)
{
PSplineSegment s = Segments[segmentIndex];
PSplineAnchor startAnchor = Anchors[s.StartIndex];
PSplineAnchor endAnchor = Anchors[s.EndIndex];
Vector3 p0 = startAnchor.Position;
Vector3 p1 = s.StartTangent;
Vector3 p2 = s.EndTangent;
Vector3 p3 = endAnchor.Position;
t = Mathf.Clamp01(t);
float oneMinusT = 1 - t;
Vector3 p =
oneMinusT * oneMinusT * oneMinusT * p0 +
3 * oneMinusT * oneMinusT * t * p1 +
3 * oneMinusT * t * t * p2 +
t * t * t * p3;
return p;
}
public Quaternion EvaluateRotation(int segmentIndex, float t)
{
PSplineSegment s = Segments[segmentIndex];
PSplineAnchor startAnchor = Anchors[s.StartIndex];
PSplineAnchor endAnchor = Anchors[s.EndIndex];
return Quaternion.Lerp(startAnchor.Rotation, endAnchor.Rotation, t);
}
public Vector3 EvaluateScale(int segmentIndex, float t)
{
PSplineSegment s = Segments[segmentIndex];
PSplineAnchor startAnchor = Anchors[s.StartIndex];
PSplineAnchor endAnchor = Anchors[s.EndIndex];
return Vector3.Lerp(startAnchor.Scale, endAnchor.Scale, t);
}
public Vector3 EvaluateUpVector(int segmentIndex, float t)
{
Quaternion rotation = EvaluateRotation(segmentIndex, t);
Matrix4x4 matrix = Matrix4x4.Rotate(rotation);
return matrix.MultiplyVector(Vector3.up);
}
public Matrix4x4 TRS(int segmentIndex,float t)
{
Vector3 pos = EvaluatePosition(segmentIndex, t);
Quaternion rotation = EvaluateRotation(segmentIndex, t);
Vector3 scale = EvaluateScale(segmentIndex, t);
return Matrix4x4.TRS(pos, rotation, scale);
}
private bool CheckHasBranch()
{
int[] count = new int[Anchors.Count];
for (int i = 0; i < Segments.Count; ++i)
{
if (!IsSegmentValid(i))
continue;
PSplineSegment s = Segments[i];
count[s.StartIndex] += 1;
count[s.EndIndex] += 1;
if (count[s.StartIndex] > 2 || count[s.EndIndex] > 2)
return true;
}
return false;
}
public List<int> FindSegments(int anchorIndex)
{
List<int> indices = new List<int>();
for (int i = 0; i < Segments.Count; ++i)
{
if (Segments[i].StartIndex == anchorIndex ||
Segments[i].EndIndex == anchorIndex)
{
indices.Add(i);
}
}
return indices;
}
public void Dispose()
{
for (int i = 0; i < Segments.Count; ++i)
{
if (Segments[i] != null)
{
Segments[i].Dispose();
}
}
}
public int[] SmoothTangents(params int[] anchorIndices)
{
int[] anchorRanks = new int[Anchors.Count];
Vector3[] directions = new Vector3[Anchors.Count];
float[] segmentLengths = new float[Segments.Count];
for (int i = 0; i < Segments.Count; ++i)
{
PSplineSegment s = Segments[i];
anchorRanks[s.StartIndex] += 1;
anchorRanks[s.EndIndex] += 1;
PSplineAnchor aStart = Anchors[s.StartIndex];
PSplineAnchor aEnd = Anchors[s.EndIndex];
Vector3 startToEnd = aEnd.Position - aStart.Position;
Vector3 d = Vector3.Normalize(startToEnd);
directions[s.StartIndex] += d;
directions[s.EndIndex] += d;
segmentLengths[i] = startToEnd.magnitude;
}
for (int i = 0; i < directions.Length; ++i)
{
if (anchorRanks[i] == 0)
continue;
directions[i] = Vector3.Normalize(directions[i] / anchorRanks[i]);
}
if (anchorIndices == null || anchorIndices.Length == 0)
{
anchorIndices = PUtilities.GetIndicesArray(Anchors.Count);
}
for (int i = 0; i < anchorIndices.Length; ++i)
{
int index = anchorIndices[i];
if (anchorRanks[index] > 0)
{
Quaternion rot = Quaternion.LookRotation(directions[index], Vector3.up);
Anchors[index].Rotation = rot;
}
}
List<int> segmentIndices = new List<int>();
for (int i = 0; i < Segments.Count; ++i)
{
PSplineSegment s = Segments[i];
for (int j = 0; j < anchorIndices.Length; ++j)
{
int anchorIndex = anchorIndices[j];
if (s.StartIndex == anchorIndex || s.EndIndex == anchorIndex)
{
segmentIndices.Add(i);
}
}
}
for (int i = 0; i < segmentIndices.Count; ++i)
{
int index = segmentIndices[i];
PSplineSegment s = Segments[index];
PSplineAnchor aStart = Anchors[s.StartIndex];
PSplineAnchor aEnd = Anchors[s.EndIndex];
float sLength = segmentLengths[index];
float tangentLength = sLength * 0.33f;
Vector3 dirStart = directions[s.StartIndex];
Vector3 dirEnd = directions[s.EndIndex];
s.StartTangent = aStart.Position + dirStart * tangentLength;
s.EndTangent = aEnd.Position - dirEnd * tangentLength;
}
return segmentIndices.ToArray();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f7d04ec7ceecdf43903995dafece5df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
using UnityEngine;
namespace Pinwheel.Poseidon
{
[System.Serializable]
public class PSplineAnchor
{
[SerializeField]
private Vector3 position;
public Vector3 Position
{
get
{
return position;
}
set
{
position = value;
}
}
[SerializeField]
private Quaternion rotation;
public Quaternion Rotation
{
get
{
return rotation;
}
set
{
rotation = value;
}
}
[SerializeField]
private Vector3 scale;
public Vector3 Scale
{
get
{
return scale;
}
set
{
scale = value;
}
}
public PSplineAnchor()
{
position = Vector3.zero;
rotation = Quaternion.identity;
scale = Vector3.one;
}
public PSplineAnchor(Vector3 pos)
{
position = pos;
rotation = Quaternion.identity;
scale = Vector3.one;
}
#if GRIFFIN_2020
public static explicit operator PSplineAnchor(Pinwheel.Griffin.SplineTool.GSplineAnchor a)
{
PSplineAnchor anchor = new PSplineAnchor();
anchor.Position = a.Position;
anchor.Rotation = a.Rotation;
anchor.Scale = a.Scale;
return anchor;
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2484219c02e3a8943b0fe53c227fe824
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
using System.Collections.Generic;
using UnityEngine;
namespace Pinwheel.Poseidon
{
[System.Serializable]
[ExecuteInEditMode]
public class PSplineCreator : MonoBehaviour
{
[SerializeField]
private int groupId;
public int GroupId
{
get
{
return groupId;
}
set
{
groupId = value;
}
}
[SerializeField]
private Vector3 positionOffset;
public Vector3 PositionOffset
{
get
{
return positionOffset;
}
set
{
positionOffset = value;
}
}
[SerializeField]
private Quaternion initialRotation;
public Quaternion InitialRotation
{
get
{
return initialRotation;
}
set
{
initialRotation = value;
}
}
[SerializeField]
private Vector3 initialScale;
public Vector3 InitialScale
{
get
{
return initialScale;
}
set
{
initialScale = value;
}
}
[SerializeField]
private int smoothness;
public int Smoothness
{
get
{
return smoothness;
}
set
{
smoothness = Mathf.Max(2, value);
}
}
[SerializeField]
private float width;
public float Width
{
get
{
return width;
}
set
{
width = Mathf.Max(0, value);
}
}
[SerializeField]
private PSpline spline;
public PSpline Spline
{
get
{
if (spline == null)
{
spline = new PSpline();
}
return spline;
}
set
{
spline = value;
}
}
public void Reset()
{
PositionOffset = Vector3.zero;
InitialRotation = Quaternion.identity;
InitialScale = Vector3.one;
Smoothness = 20;
Width = 10;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1e8a058da2c0ca44ba4628ad323f26cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,146 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Poseidon;
namespace Pinwheel.Poseidon
{
public class PSplineMeshCreator : IPMeshCreator
{
private PWater water;
public void Create(PWater water)
{
List<PSplineSegment> segments = water.Spline.Segments;
for (int i = 0; i < segments.Count; ++i)
{
Create(water, i);
}
}
public void Create(PWater water, int segmentIndex)
{
this.water = water;
List<Vector3> vertices = new List<Vector3>();
List<Vector4> uvs0 = new List<Vector4>();
List<Vector4> uvs1 = new List<Vector4>();
List<Color> colors = new List<Color>();
List<int> triangles = new List<int>();
PSpline spline = water.Spline;
PSplineSegment s = water.Spline.Segments[segmentIndex];
Vector3 pos0, pos1;
Quaternion rotation0, rotation1;
Vector3 scale0, scale1;
Matrix4x4 matrix0, matrix1;
Vector4 bl, tl, tr, br;
Vector4 v0, v1, v2, v3;
Vector4 flow0, flow1;
int currentVertexCount;
float halfWidth = water.SplineWidth * 0.5f;
int resY = Mathf.RoundToInt(water.SplineResolutionY * s.ResolutionMultiplierY);
resY = Mathf.Clamp(resY, 2, 100);
if (resY % 2 == 1)
{
resY -= 1;
}
int resX = water.SplineResolutionX;
float xStep = 1.0f / resX;
float yStep = 1.0f / resY;
float x0, x1;
float y0, y1;
for (int yIndex = 0; yIndex < resY; ++yIndex)
{
y0 = yIndex * yStep;
pos0 = spline.EvaluatePosition(segmentIndex, y0);
rotation0 = spline.EvaluateRotation(segmentIndex, y0);
scale0 = spline.EvaluateScale(segmentIndex, y0);
matrix0 = Matrix4x4.TRS(pos0, rotation0, scale0);
y1 = (yIndex + 1) * yStep;
pos1 = spline.EvaluatePosition(segmentIndex, y1);
rotation1 = spline.EvaluateRotation(segmentIndex, y1);
scale1 = spline.EvaluateScale(segmentIndex, y1);
matrix1 = Matrix4x4.TRS(pos1, rotation1, scale1);
bl = matrix0.MultiplyPoint(new Vector3(-halfWidth, 0, 0));
tl = matrix1.MultiplyPoint(new Vector3(-halfWidth, 0, 0));
tr = matrix1.MultiplyPoint(new Vector3(halfWidth, 0, 0));
br = matrix0.MultiplyPoint(new Vector3(halfWidth, 0, 0));
for (int xIndex = 0; xIndex < resX; ++xIndex)
{
x0 = xIndex * xStep;
x1 = (xIndex + 1) * xStep;
v0 = Vector4.Lerp(bl, br, x0);
v1 = Vector4.Lerp(tl, tr, x0);
v2 = Vector4.Lerp(tl, tr, x1);
v3 = Vector4.Lerp(bl, br, x1);
currentVertexCount = vertices.Count;
triangles.Add(currentVertexCount + 0);
triangles.Add(currentVertexCount + 1);
triangles.Add(currentVertexCount + 2);
triangles.Add(currentVertexCount + 3);
triangles.Add(currentVertexCount + 4);
triangles.Add(currentVertexCount + 5);
flow0 = matrix0.MultiplyVector(Vector3.forward*2);
flow1 = matrix1.MultiplyVector(Vector3.forward*2);
if ((xIndex + yIndex) % 2 == 0)
{
BakeData(vertices, uvs0, colors, uvs1, v0, v1, v2, flow0, flow1, flow1);
BakeData(vertices, uvs0, colors, uvs1, v1, v2, v0, flow1, flow1, flow0);
BakeData(vertices, uvs0, colors, uvs1, v2, v0, v1, flow1, flow0, flow1);
BakeData(vertices, uvs0, colors, uvs1, v2, v3, v0, flow1, flow0, flow0);
BakeData(vertices, uvs0, colors, uvs1, v3, v0, v2, flow0, flow0, flow1);
BakeData(vertices, uvs0, colors, uvs1, v0, v2, v3, flow0, flow1, flow0);
}
else
{
BakeData(vertices, uvs0, colors, uvs1, v0, v1, v3, flow0, flow1, flow0);
BakeData(vertices, uvs0, colors, uvs1, v1, v3, v0, flow1, flow0, flow0);
BakeData(vertices, uvs0, colors, uvs1, v3, v0, v1, flow0, flow0, flow1);
BakeData(vertices, uvs0, colors, uvs1, v2, v3, v1, flow1, flow0, flow1);
BakeData(vertices, uvs0, colors, uvs1, v3, v1, v2, flow0, flow1, flow1);
BakeData(vertices, uvs0, colors, uvs1, v1, v2, v3, flow1, flow1, flow0);
}
}
}
Mesh m = s.Mesh;
m.Clear();
m.SetVertices(vertices);
m.SetUVs(0, uvs0);
m.SetUVs(1, uvs1);
m.SetColors(colors);
m.SetTriangles(triangles, 0);
m.RecalculateBounds();
PUtilities.DoubleMeshBounds(m);
}
private void BakeData(
List<Vector3> vertices, List<Vector4> uvs0, List<Color> colors, List<Vector4> uvs1,
Vector4 v0, Vector4 v1, Vector4 v2,
Vector4 flow0, Vector4 flow1, Vector4 flow2)
{
Vector3 vertex = new Vector3(v0.x, v0.y, v0.z);
Vector4 uv0 = new Vector4(v1.x, v1.y, v1.z, flow0.x);
Color color = new Color(v2.x, v2.y, v2.z, flow0.z);
Vector4 uv1 = new Vector4(flow1.x, flow1.z, flow2.x, flow2.z);
vertices.Add(vertex);
uvs0.Add(uv0);
colors.Add(color);
uvs1.Add(uv1);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5559d6b8bb3f13441ab42a4b013d2b84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,117 @@
using UnityEngine;
using System;
namespace Pinwheel.Poseidon
{
[System.Serializable]
public class PSplineSegment : IDisposable
{
[SerializeField]
private int startIndex;
public int StartIndex
{
get
{
return startIndex;
}
set
{
startIndex = value;
}
}
[SerializeField]
private int endIndex;
public int EndIndex
{
get
{
return endIndex;
}
set
{
endIndex = value;
}
}
[SerializeField]
private Vector3 startTangent;
public Vector3 StartTangent
{
get
{
return startTangent;
}
set
{
startTangent = value;
}
}
[SerializeField]
private Vector3 endTangent;
public Vector3 EndTangent
{
get
{
return endTangent;
}
set
{
endTangent = value;
}
}
[SerializeField]
private float resolutionMultiplierY = 1;
public float ResolutionMultiplierY
{
get
{
resolutionMultiplierY = Mathf.Clamp(resolutionMultiplierY, 0f, 2f);
return resolutionMultiplierY;
}
set
{
resolutionMultiplierY = Mathf.Clamp(value, 0f, 2f);
}
}
[SerializeField]
private Mesh mesh;
public Mesh Mesh
{
get
{
if (mesh == null)
{
mesh = new Mesh();
mesh.name = "Spline Segment";
mesh.MarkDynamic();
}
return mesh;
}
}
public void Dispose()
{
if (mesh != null)
{
PUtilities.DestroyObject(mesh);
}
}
#if GRIFFIN_2020
public static explicit operator PSplineSegment(Pinwheel.Griffin.SplineTool.GSplineSegment s)
{
PSplineSegment segment = new PSplineSegment();
segment.StartIndex = s.StartIndex;
segment.EndIndex = s.EndIndex;
segment.StartTangent = s.StartTangent;
segment.EndTangent = s.EndTangent;
segment.ResolutionMultiplierY = 1;
return segment;
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5a05d68193d47f0469728a067a095d3b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public static class PSplineUtilities
{
public static void WaterPivotToSplineCenter(PWater water)
{
PSpline spline = water.Spline;
List<PSplineAnchor> anchors = spline.Anchors;
if (anchors.Count == 0)
return;
Vector3 splineCenterLocal = Vector3.zero;
for (int i = 0; i < anchors.Count; ++i)
{
splineCenterLocal += anchors[i].Position;
}
splineCenterLocal = splineCenterLocal / anchors.Count;
for (int i = 0; i < anchors.Count; ++i)
{
anchors[i].Position -= splineCenterLocal;
}
List<PSplineSegment> segments = spline.Segments;
for (int i = 0; i < segments.Count; ++i)
{
segments[i].StartTangent -= splineCenterLocal;
segments[i].EndTangent -= splineCenterLocal;
}
Vector3 splineCenterWorld = water.transform.TransformPoint(splineCenterLocal);
water.transform.position = splineCenterWorld;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf81b497610d74941a50b07e6cadaaca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public enum PTimeMode
{
Auto, Manual
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0563f0fe5141cca4ea28800ad98f64f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 462e8506f0cffa44b9bb1e626e1dfb7c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,148 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Poseidon
{
public static class PWaterExtension
{
public static Vector3 GetLocalVertexPosition(this PWater water, Vector3 localPos, bool applyRipple = false)
{
if (water.Profile == null)
{
throw new NullReferenceException("The water must have a profile to calculate vertex position.");
}
if (water.Profile.EnableWave)
{
water.ApplyWaveHQ(ref localPos);
}
if (applyRipple)
{
water.ApplyRipple(ref localPos);
}
return localPos;
}
}
internal static class PWaveCalculator
{
public static void ApplyWaveHQ(this PWater water, ref Vector3 v0)
{
Vector3 offset0 = water.CalculateWaveOffsetHQ(v0);
v0 += offset0;
}
private static Vector3 CalculateWaveOffsetHQ(this PWater water, Vector3 vertex)
{
PWaterProfile profile = water.Profile;
Vector2 waveDirection = new Vector2(Mathf.Cos(profile.WaveDirection * Mathf.Deg2Rad), Mathf.Sin(profile.WaveDirection * Mathf.Deg2Rad));
float time = (float)water.GetTimeParam();
//Vector3 worldPos = water.transform.localToWorldMatrix.MultiplyPoint(vertex);
Vector3 worldPos = water.transform.TransformPoint(vertex);
Vector2 worldXZ = new Vector2(worldPos.x, worldPos.z);
Vector2 noisePos = worldXZ - 2 * profile.WaveSpeed * waveDirection * time;
float noise = PNoiseTextureSampler.SampleVertexNoise(noisePos * 0.001f) * profile.WaveDeform;
float dotValue = Vector2.Dot(worldXZ, waveDirection);
float t = Frac((dotValue - profile.WaveSpeed * time) / profile.WaveLength - noise * profile.WaveDeform * 0.25f);
Vector2 p = SampleWaveCurve(t, profile.WaveSteepness);
p.y -= Mathf.Lerp(0.5f, 1f, noise * 0.5f + 0.5f);
Vector3 offset = new Vector3(0, profile.WaveHeight * p.y, 0);
if (water.UseWaveMask && water.WaveMask != null)
{
Rect waveMaskBounds = water.WaveMaskBounds;
float maskU = InverseLerpUnclamped(waveMaskBounds.min.x, waveMaskBounds.max.x, worldPos.x);
float maskV = InverseLerpUnclamped(waveMaskBounds.min.y, waveMaskBounds.max.y, worldPos.z);
Color mask = water.WaveMask.GetPixelBilinear(maskU, maskV);
float inbounds = (maskU >= 0 && maskU <= 1 && maskV >= 0 && maskV <= 1) ? 1 : 0;
float heightMask = Mathf.Lerp(1, mask.a, inbounds);
offset.y *= heightMask;
}
return offset;
}
private static float Frac(float v)
{
return v - Mathf.Floor(v);
}
private static Vector2 SampleWaveCurve(float t, float waveSteepness)
{
Vector2 left = Vector2.zero;
Vector2 right = Vector2.right;
Vector2 middle = new Vector2(Mathf.Lerp(0.5f, 0.95f, waveSteepness), 1);
Vector2 anchor0 = left * ((t < middle.x) ? 1 : 0) + middle * ((t >= middle.x) ? 1 : 0);
Vector2 anchor1 = middle * ((t < middle.x) ? 1 : 0) + right * ((t >= middle.x) ? 1 : 0);
float tangentLength = 0.5f;
Vector2 tangent0 = new Vector2(tangentLength, 0) * ((t < middle.x) ? 1 : 0) + new Vector2(middle.x + tangentLength, middle.y) * ((t >= middle.x) ? 1 : 0);
Vector2 tangent1 = new Vector2(middle.x - tangentLength, middle.y) * ((t < middle.x) ? 1 : 0) + new Vector2(1 - tangentLength, 0) * ((t >= middle.x) ? 1 : 0);
float splineT = InverseLerpUnclamped(anchor0.x, anchor1.x, t);
Vector2 p = SampleSpline(splineT, anchor0, anchor1, tangent0, tangent1);
return p;
}
private static float InverseLerpUnclamped(float a, float b, float value)
{
//adding a==b check if needed
return (value - a) / (b - a + 0.000001f);
}
private static Vector2 SampleSpline(float t, Vector2 anchor0, Vector2 anchor1, Vector2 tangent0, Vector2 tangent1)
{
float oneMinusT = 1 - t;
Vector2 p =
oneMinusT * oneMinusT * oneMinusT * anchor0 +
3 * oneMinusT * oneMinusT * t * tangent0 +
3 * oneMinusT * t * t * tangent1 +
t * t * t * anchor1;
return p;
}
}
internal static class PRippleCalculator
{
private static Vector3 CalculateRippleVertexOffset(this PWater water, Vector3 localPos, float rippleHeight, float rippleSpeed, float rippleScale, Vector3 flowDir)
{
Vector3 worldPos = water.transform.localToWorldMatrix.MultiplyPoint(localPos);
Vector2 noisePos = new Vector2(worldPos.x, worldPos.z);
rippleScale *= 0.01f;
rippleSpeed *= 0.1f;
Vector2 flowDirXZ = new Vector2(flowDir.x, flowDir.z);
float time = (float)water.GetTimeParam();
float noiseBase = PNoiseTextureSampler.SampleVertexNoise((noisePos - flowDirXZ * time * rippleSpeed) * rippleScale) * 0.5f + 0.5f;
float noiseFade = Mathf.Lerp(0.5f, 1f, PNoiseTextureSampler.SampleVertexNoise((noisePos + flowDirXZ * time * rippleSpeed * 3) * rippleScale) * 0.5f + 0.5f);
float noise = Mathf.Abs(noiseBase - noiseFade);
Vector3 offset = new Vector3(0, noise * rippleHeight, 0);
return offset;
}
public static void ApplyRipple(this PWater water, ref Vector3 v0)
{
Vector3 flowDir = Vector3.one;
v0 += water.CalculateRippleVertexOffset(v0, water.Profile.RippleHeight, water.Profile.RippleSpeed, water.Profile.RippleNoiseScale, flowDir);
}
}
internal static class PNoiseTextureSampler
{
public static float SampleVertexNoise(Vector2 uv)
{
Texture2D tex = PPoseidonSettings.Instance.NoiseTexture;
return tex.GetPixelBilinear(uv.x, uv.y, 0).r * 2 - 1;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5342ce96179326340ae2eb0000ac93af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public enum PWaterMeshType
{
TileablePlane, Area, Spline, CustomMesh
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 23475789bc4dd9a469f00e9707d60d63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public enum PWaterMode
{
CalmWater
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0b34f2eb5e487054fa9c941c239590c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,869 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Poseidon
{
[CreateAssetMenu(menuName = "Poseidon/Water Profile")]
public class PWaterProfile : ScriptableObject
{
[SerializeField]
private PLightingModel lightingModel;
public PLightingModel LightingModel
{
get
{
return lightingModel;
}
set
{
lightingModel = value;
}
}
[SerializeField]
private bool useFlatLighting;
public bool UseFlatLighting
{
get
{
return useFlatLighting;
}
set
{
useFlatLighting = value;
}
}
[SerializeField]
private int renderQueueIndex;
public int RenderQueueIndex
{
get
{
return renderQueueIndex;
}
set
{
renderQueueIndex = value;
}
}
[SerializeField]
private Color color;
public Color Color
{
get
{
return color;
}
set
{
color = value;
}
}
[SerializeField]
private Color specColor;
public Color SpecColor
{
get
{
return specColor;
}
set
{
specColor = value;
}
}
[SerializeField]
private float smoothness;
public float Smoothness
{
get
{
return smoothness;
}
set
{
smoothness = Mathf.Clamp01(value);
}
}
[FormerlySerializedAs("enableLightAbsorbtion")]
[SerializeField]
private bool enableLightAbsorption;
public bool EnableLightAbsorption
{
get
{
return enableLightAbsorption;
}
set
{
enableLightAbsorption = value;
}
}
[SerializeField]
private Color depthColor;
public Color DepthColor
{
get
{
return depthColor;
}
set
{
depthColor = value;
}
}
[SerializeField]
private float maxDepth;
public float MaxDepth
{
get
{
return maxDepth;
}
set
{
maxDepth = Mathf.Max(0, value);
}
}
[SerializeField]
private bool enableFoam;
public bool EnableFoam
{
get
{
return enableFoam;
}
set
{
enableFoam = value;
}
}
[SerializeField]
private Color foamColor;
public Color FoamColor
{
get
{
return foamColor;
}
set
{
foamColor = value;
}
}
[SerializeField]
private float foamDistance;
public float FoamDistance
{
get
{
return foamDistance;
}
set
{
foamDistance = Mathf.Max(0, value);
}
}
[SerializeField]
private bool enableFoamHQ;
public bool EnableFoamHQ
{
get
{
return enableFoamHQ;
}
set
{
enableFoamHQ = value;
}
}
[SerializeField]
private float foamNoiseScaleHQ;
public float FoamNoiseScaleHQ
{
get
{
return foamNoiseScaleHQ;
}
set
{
foamNoiseScaleHQ = value;
}
}
[SerializeField]
private float foamNoiseSpeedHQ;
public float FoamNoiseSpeedHQ
{
get
{
return foamNoiseSpeedHQ;
}
set
{
foamNoiseSpeedHQ = value;
}
}
[SerializeField]
private float shorelineFoamStrength;
public float ShorelineFoamStrength
{
get
{
return shorelineFoamStrength;
}
set
{
shorelineFoamStrength = Mathf.Clamp01(value);
}
}
[SerializeField]
private float crestFoamStrength;
public float CrestFoamStrength
{
get
{
return crestFoamStrength;
}
set
{
crestFoamStrength = Mathf.Clamp01(value);
}
}
[SerializeField]
private float crestMaxDepth;
public float CrestMaxDepth
{
get
{
return crestMaxDepth;
}
set
{
crestMaxDepth = Mathf.Max(0, value);
}
}
[SerializeField]
private float slopeFoamStrength;
public float SlopeFoamStrength
{
get
{
return slopeFoamStrength;
}
set
{
slopeFoamStrength = Mathf.Clamp01(value);
}
}
[SerializeField]
private float slopeFoamFlowSpeed;
public float SlopeFoamFlowSpeed
{
get
{
return slopeFoamFlowSpeed;
}
set
{
slopeFoamFlowSpeed = Mathf.Max(0, value);
}
}
[SerializeField]
private float slopeFoamDistance;
public float SlopeFoamDistance
{
get
{
return slopeFoamDistance;
}
set
{
slopeFoamDistance = Mathf.Max(0, value);
}
}
[SerializeField]
private float rippleHeight;
public float RippleHeight
{
get
{
return rippleHeight;
}
set
{
rippleHeight = Mathf.Clamp01(value);
}
}
[SerializeField]
private float rippleSpeed;
public float RippleSpeed
{
get
{
return rippleSpeed;
}
set
{
rippleSpeed = value;
}
}
[SerializeField]
private float rippleNoiseScale;
public float RippleNoiseScale
{
get
{
return rippleNoiseScale;
}
set
{
rippleNoiseScale = value;
}
}
[SerializeField]
private bool enableWave;
public bool EnableWave
{
get
{
return enableWave;
}
set
{
enableWave = value;
}
}
[SerializeField]
private float waveDirection;
public float WaveDirection
{
get
{
return waveDirection;
}
set
{
waveDirection = Mathf.Clamp(value, 0f, 360f);
}
}
[SerializeField]
private float waveSpeed;
public float WaveSpeed
{
get
{
return waveSpeed;
}
set
{
waveSpeed = value;
}
}
[SerializeField]
private float waveHeight;
public float WaveHeight
{
get
{
return waveHeight;
}
set
{
waveHeight = Mathf.Max(0, value);
}
}
[SerializeField]
private float waveLength;
public float WaveLength
{
get
{
return waveLength;
}
set
{
waveLength = Mathf.Max(1, value);
}
}
[SerializeField]
private float waveSteepness;
public float WaveSteepness
{
get
{
return waveSteepness;
}
set
{
waveSteepness = Mathf.Clamp01(value);
}
}
[SerializeField]
private float waveDeform;
public float WaveDeform
{
get
{
return waveDeform;
}
set
{
waveDeform = Mathf.Clamp01(value);
}
}
[SerializeField]
private float fresnelStrength;
public float FresnelStrength
{
get
{
return fresnelStrength;
}
set
{
fresnelStrength = Mathf.Max(0, value);
}
}
[SerializeField]
private float fresnelBias;
public float FresnelBias
{
get
{
return fresnelBias;
}
set
{
fresnelBias = Mathf.Clamp01(value);
}
}
[SerializeField]
private bool enableReflection;
public bool EnableReflection
{
get
{
return enableReflection;
}
set
{
enableReflection = value;
}
}
[SerializeField]
private int reflectionTextureResolution;
public int ReflectionTextureResolution
{
get
{
return reflectionTextureResolution;
}
set
{
reflectionTextureResolution = Mathf.Clamp(Mathf.ClosestPowerOfTwo(value), 32, 2048);
}
}
[SerializeField]
private bool enableReflectionPixelLight;
public bool EnableReflectionPixelLight
{
get
{
return enableReflectionPixelLight;
}
set
{
enableReflectionPixelLight = value;
}
}
[SerializeField]
private float reflectionClipPlaneOffset;
public float ReflectionClipPlaneOffset
{
get
{
return reflectionClipPlaneOffset;
}
set
{
reflectionClipPlaneOffset = value;
}
}
[SerializeField]
private LayerMask reflectionLayers;
public LayerMask ReflectionLayers
{
get
{
return reflectionLayers;
}
set
{
reflectionLayers = value;
}
}
[SerializeField]
private bool reflectCustomSkybox;
public bool ReflectCustomSkybox
{
get
{
return reflectCustomSkybox;
}
set
{
reflectCustomSkybox = value;
}
}
[SerializeField]
private float reflectionDistortionStrength;
public float ReflectionDistortionStrength
{
get
{
return reflectionDistortionStrength;
}
set
{
reflectionDistortionStrength = value;
}
}
[SerializeField]
private bool enableRefraction;
public bool EnableRefraction
{
get
{
return enableRefraction;
}
set
{
enableRefraction = value;
}
}
[SerializeField]
private float refractionDistortionStrength;
public float RefractionDistortionStrength
{
get
{
return refractionDistortionStrength;
}
set
{
refractionDistortionStrength = value;
}
}
[SerializeField]
private bool enableCaustic;
public bool EnableCaustic
{
get
{
return enableCaustic;
}
set
{
enableCaustic = value;
}
}
[SerializeField]
private Texture causticTexture;
public Texture CausticTexture
{
get
{
return causticTexture;
}
set
{
causticTexture = value;
}
}
[SerializeField]
private float causticSize;
public float CausticSize
{
get
{
return causticSize;
}
set
{
causticSize = value;
}
}
[SerializeField]
private float causticStrength;
public float CausticStrength
{
get
{
return causticStrength;
}
set
{
causticStrength = Mathf.Max(0, value);
}
}
[SerializeField]
private float causticDistortionStrength;
public float CausticDistortionStrength
{
get
{
return causticDistortionStrength;
}
set
{
causticDistortionStrength = value;
}
}
#if AURA_IN_PROJECT
[SerializeField]
private bool applyAuraLighting;
public bool ApplyAuraLighting
{
get
{
return applyAuraLighting;
}
set
{
applyAuraLighting = value;
}
}
[SerializeField]
private float auraLightingFactor;
public float AuraLightingFactor
{
get
{
return auraLightingFactor;
}
set
{
auraLightingFactor = Mathf.Max(0, value);
}
}
[SerializeField]
private bool applyAuraFog;
public bool ApplyAuraFog
{
get
{
return applyAuraFog;
}
set
{
applyAuraFog = value;
}
}
#endif
public void Reset()
{
PWaterProfile defaultProfile = PPoseidonSettings.Instance.CalmWaterProfile;
if (defaultProfile != null)
{
CopyFrom(defaultProfile);
}
}
public void UpdateMaterialProperties(Material mat)
{
if (mat == null)
return;
PMat.SetActiveMaterial(mat);
PMat.SetKeywordEnable(PMat.KW_LIGHTING_BLINN_PHONG, lightingModel == PLightingModel.BlinnPhong);
PMat.SetKeywordEnable(PMat.KW_LIGHTING_LAMBERT, lightingModel == PLightingModel.Lambert);
PMat.SetKeywordEnable(PMat.KW_FLAT_LIGHTING, useFlatLighting);
PMat.SetRenderQueue(PMat.QUEUE_TRANSPARENT + RenderQueueIndex);
PMat.SetColor(PMat.COLOR, color);
PMat.SetColor(PMat.SPEC_COLOR, specColor);
PMat.SetColor(PMat.SPEC_COLOR_BLINN_PHONG, specColor);
PMat.SetFloat(PMat.SMOOTHNESS, smoothness);
PMat.SetKeywordEnable(PMat.KW_LIGHT_ABSORPTION, enableLightAbsorption);
PMat.SetColor(PMat.DEPTH_COLOR, depthColor);
PMat.SetFloat(PMat.MAX_DEPTH, maxDepth);
PMat.SetKeywordEnable(PMat.KW_FOAM, enableFoam);
PMat.SetKeywordEnable(PMat.KW_FOAM_HQ, enableFoamHQ);
PMat.SetKeywordEnable(PMat.KW_FOAM_CREST, crestFoamStrength > 0);
PMat.SetKeywordEnable(PMat.KW_FOAM_SLOPE, slopeFoamStrength > 0);
PMat.SetColor(PMat.FOAM_COLOR, foamColor);
PMat.SetFloat(PMat.FOAM_DISTANCE, foamDistance);
PMat.SetFloat(PMat.FOAM_NOISE_SCALE_HQ, foamNoiseScaleHQ);
PMat.SetFloat(PMat.FOAM_NOISE_SPEED_HQ, foamNoiseSpeedHQ);
PMat.SetFloat(PMat.SHORELINE_FOAM_STRENGTH, shorelineFoamStrength);
PMat.SetFloat(PMat.CREST_FOAM_STRENGTH, crestFoamStrength);
PMat.SetFloat(PMat.CREST_MAX_DEPTH, crestMaxDepth);
PMat.SetFloat(PMat.SLOPE_FOAM_STRENGTH, slopeFoamStrength);
PMat.SetFloat(PMat.SLOPE_FOAM_FLOW_SPEED, slopeFoamFlowSpeed);
PMat.SetFloat(PMat.SLOPE_FOAM_DISTANCE, slopeFoamDistance);
PMat.SetFloat(PMat.RIPPLE_HEIGHT, rippleHeight);
PMat.SetFloat(PMat.RIPPLE_NOISE_SCALE, rippleNoiseScale);
PMat.SetFloat(PMat.RIPPLE_SPEED, rippleSpeed);
PMat.SetKeywordEnable(PMat.KW_WAVE, enableWave);
PMat.SetVector(PMat.WAVE_DIRECTION, new Vector4(Mathf.Cos(waveDirection * Mathf.Deg2Rad), Mathf.Sin(waveDirection * Mathf.Deg2Rad), 0, 0));
PMat.SetFloat(PMat.WAVE_SPEED, waveSpeed);
PMat.SetFloat(PMat.WAVE_HEIGHT, waveHeight);
PMat.SetFloat(PMat.WAVE_LENGTH, waveLength);
PMat.SetFloat(PMat.WAVE_STEEPNESS, waveSteepness);
PMat.SetFloat(PMat.WAVE_DEFORM, waveDeform);
PMat.SetFloat(PMat.FRESNEL_STRENGTH, fresnelStrength);
PMat.SetFloat(PMat.FRESNEL_BIAS, fresnelBias);
PMat.SetKeywordEnable(PMat.KW_REFLECTION, enableReflection);
PMat.SetFloat(PMat.REFLECTION_DISTORTION_STRENGTH, reflectionDistortionStrength);
PMat.SetKeywordEnable(PMat.KW_REFRACTION, enableRefraction);
PMat.SetFloat(PMat.REFRACTION_DISTORTION_STRENGTH, enableRefraction ? refractionDistortionStrength : 0);
PMat.SetKeywordEnable(PMat.KW_CAUSTIC, enableCaustic);
PMat.SetTexture(PMat.CAUSTIC_TEX, causticTexture);
PMat.SetFloat(PMat.CAUSTIC_SIZE, causticSize);
PMat.SetFloat(PMat.CAUSTIC_STRENGTH, causticStrength);
PMat.SetFloat(PMat.CAUSTIC_DISTORTION_STRENGTH, causticDistortionStrength);
#if AURA_IN_PROJECT
PMat.SetKeywordEnable(PMat.KW_AURA_LIGHTING, applyAuraLighting);
PMat.SetFloat(PMat.AURA_LIGHTING_FACTOR, auraLightingFactor);
PMat.SetKeywordEnable(PMat.KW_AURA_FOG, applyAuraFog);
#else
PMat.SetKeywordEnable(PMat.KW_AURA_LIGHTING, false);
PMat.SetKeywordEnable(PMat.KW_AURA_FOG, false);
#endif
PMat.SetActiveMaterial(null);
}
public void CopyFrom(PWaterProfile p)
{
LightingModel = p.LightingModel;
RenderQueueIndex = p.RenderQueueIndex;
UseFlatLighting = p.UseFlatLighting;
Color = p.Color;
SpecColor = p.SpecColor;
Smoothness = p.Smoothness;
EnableLightAbsorption = p.EnableLightAbsorption;
DepthColor = p.DepthColor;
MaxDepth = p.MaxDepth;
EnableFoam = p.EnableFoam;
FoamColor = p.FoamColor;
FoamDistance = p.FoamDistance;
EnableFoamHQ = p.EnableFoamHQ;
FoamNoiseScaleHQ = p.FoamNoiseScaleHQ;
FoamNoiseSpeedHQ = p.FoamNoiseSpeedHQ;
ShorelineFoamStrength = p.ShorelineFoamStrength;
CrestFoamStrength = p.CrestFoamStrength;
CrestMaxDepth = p.CrestMaxDepth;
SlopeFoamStrength = p.SlopeFoamStrength;
SlopeFoamFlowSpeed = p.SlopeFoamFlowSpeed;
SlopeFoamDistance = p.SlopeFoamDistance;
RippleHeight = p.RippleHeight;
RippleSpeed = p.RippleSpeed;
RippleNoiseScale = p.RippleNoiseScale;
EnableWave = p.EnableWave;
WaveDirection = p.WaveDirection;
WaveSpeed = p.WaveSpeed;
WaveHeight = p.WaveHeight;
WaveLength = p.WaveLength;
WaveSteepness = p.WaveSteepness;
WaveDeform = p.WaveDeform;
FresnelStrength = p.FresnelStrength;
FresnelBias = p.FresnelBias;
EnableReflection = p.EnableReflection;
ReflectionTextureResolution = p.ReflectionTextureResolution;
EnableReflectionPixelLight = p.EnableReflectionPixelLight;
ReflectionClipPlaneOffset = p.ReflectionClipPlaneOffset;
ReflectionLayers = p.ReflectionLayers;
ReflectCustomSkybox = p.ReflectCustomSkybox;
ReflectionDistortionStrength = p.ReflectionDistortionStrength;
EnableRefraction = p.EnableRefraction;
RefractionDistortionStrength = p.RefractionDistortionStrength;
EnableCaustic = p.EnableCaustic;
CausticTexture = p.CausticTexture;
CausticSize = p.CausticSize;
CausticStrength = p.CausticStrength;
CausticDistortionStrength = p.CausticDistortionStrength;
#if AURA_IN_PROJECT
ApplyAuraLighting = p.ApplyAuraLighting;
AuraLightingFactor = p.AuraLightingFactor;
ApplyAuraFog = p.ApplyAuraFog;
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 004ffb8c9b4e90d438d35887f7b002e4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
[System.Serializable]
public struct PWaterProfileDefault
{
[SerializeField]
private int meshResolution;
public int MeshResolution
{
get
{
return meshResolution;
}
set
{
meshResolution = value;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 642c289e9dfb783488eb541784d6e562
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,226 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public static class PWaterShaderProvider
{
private static Shader waterBasicShader;
public static Shader WaterBasicShader
{
get
{
if (waterBasicShader == null)
{
waterBasicShader = Shader.Find("Poseidon/Default/WaterBasic");
}
return waterBasicShader;
}
}
private static Shader waterAdvancedShader;
public static Shader WaterAdvancedShader
{
get
{
if (waterAdvancedShader == null)
{
waterAdvancedShader = Shader.Find("Poseidon/Default/WaterAdvanced");
}
return waterAdvancedShader;
}
}
private static Shader waterBasicShaderURP;
public static Shader WaterBasicShaderURP
{
get
{
if (waterBasicShaderURP == null)
{
waterBasicShaderURP = Shader.Find("Poseidon/URP/WaterBasicURP");
}
return waterBasicShaderURP;
}
}
private static Shader waterAdvancedShaderURP;
public static Shader WaterAdvancedShaderURP
{
get
{
if (waterAdvancedShaderURP == null)
{
waterAdvancedShaderURP = Shader.Find("Poseidon/URP/WaterAdvancedURP");
}
return waterAdvancedShaderURP;
}
}
private static Shader waterBackFaceShader;
public static Shader WaterBackFaceShader
{
get
{
if (waterBackFaceShader == null)
{
waterBackFaceShader = Shader.Find("Poseidon/Default/WaterBackFace");
}
return waterBackFaceShader;
}
}
private static Shader waterBackFaceShaderURP;
public static Shader WaterBackFaceShaderURP
{
get
{
if (waterBackFaceShaderURP == null)
{
waterBackFaceShaderURP = Shader.Find("Poseidon/URP/WaterBackFaceURP");
}
return waterBackFaceShaderURP;
}
}
private static Shader riverShader;
public static Shader RiverShader
{
get
{
if (riverShader == null)
{
riverShader = Shader.Find("Poseidon/Default/River");
}
return riverShader;
}
}
private static Shader riverShaderURP;
public static Shader RiverShaderURP
{
get
{
if (riverShaderURP == null)
{
riverShaderURP = Shader.Find("Poseidon/URP/RiverURP");
}
return riverShaderURP;
}
}
public static Shader GetBackFaceShader()
{
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
return WaterBackFaceShader;
}
else if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
return WaterBackFaceShaderURP;
}
else
{
return null;
}
}
public static Shader GetShader(PWater water)
{
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
return GetBuiltinRPShader(water);
}
else if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
return GetUniversalRPShader(water);
}
else
{
return null;
}
}
public static Shader GetBuiltinRPShader(PWater water)
{
if (water.Profile == null)
return null;
if (water.MeshType == PWaterMeshType.Spline)
{
return RiverShader;
}
else
{
if (water.Profile.EnableReflection || water.Profile.EnableRefraction)
{
return WaterAdvancedShader;
}
else
{
return WaterBasicShader;
}
}
}
public static Shader GetUniversalRPShader(PWater water)
{
if (water.Profile == null)
return null;
if (water.MeshType == PWaterMeshType.Spline)
{
return RiverShaderURP;
}
else
{
if (water.Profile.EnableReflection || water.Profile.EnableRefraction)
{
return WaterAdvancedShaderURP;
}
else
{
return WaterBasicShaderURP;
}
}
}
public static bool Validate(PWater water)
{
bool validate = true;
bool validateBackFace = true;
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
validate =
water.MaterialToRender.shader == WaterBasicShader ||
water.MaterialToRender.shader == WaterAdvancedShader ||
water.MaterialToRender.shader == RiverShader;
validateBackFace =
water.ShouldRenderBackface && water.MaterialBackFace.shader == WaterBackFaceShader;
}
else if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
validate =
water.MaterialToRender.shader == WaterBasicShaderURP ||
water.MaterialToRender.shader == WaterAdvancedShaderURP ||
water.MaterialToRender.shader == RiverShaderURP;
validateBackFace =
water.ShouldRenderBackface && water.MaterialBackFace.shader == WaterBackFaceShaderURP;
}
return validate && validateBackFace;
}
public static void ResetShaderReferences()
{
waterBasicShader = null;
waterAdvancedShader = null;
waterBackFaceShader = null;
riverShader = null;
waterBasicShaderURP = null;
waterAdvancedShaderURP = null;
waterBackFaceShaderURP = null;
riverShaderURP = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce17ea928bfb35f46bbc99d8a5d46822
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 60e570b518ac2dc448234d44fafec07d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b57584cef44bfbe4dbdf385c1bc61f27
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
#if UNITY_POST_PROCESSING_STACK_V2
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering.PostProcessing;
namespace Pinwheel.Poseidon.FX.PostProcessing
{
[System.Serializable]
[PostProcess(typeof(PUnderwaterRenderer), PostProcessEvent.BeforeStack, "Poseidon/Underwater", false)]
public sealed class PUnderwater : PostProcessEffectSettings
{
[Header("Water Body")]
public FloatParameter waterLevel = new FloatParameter();
public FloatParameter maxDepth = new FloatParameter() { value = 10 };
[Range(0f, 3f)]
public FloatParameter surfaceColorBoost = new FloatParameter() { value = 1 };
[Header("Fog")]
public ColorParameter shallowFogColor = new ColorParameter();
public ColorParameter deepFogColor = new ColorParameter();
public FloatParameter viewDistance = new FloatParameter() { value = 40 };
[Header("Caustic")]
public BoolParameter enableCaustic = new BoolParameter();
public TextureParameter causticTexture = new TextureParameter();
public FloatParameter causticSize = new FloatParameter();
[Range(0f, 1f)]
public FloatParameter causticStrength = new FloatParameter();
[Header("Distortion")]
public BoolParameter enableDistortion = new BoolParameter();
public TextureParameter distortionNormalMap = new TextureParameter();
public FloatParameter distortionStrength = new FloatParameter();
public FloatParameter waterFlowSpeed = new FloatParameter();
[Header("Internal")]
[Range(0f, 1f)]
public FloatParameter intensity = new FloatParameter();
public override bool IsEnabledAndSupported(PostProcessRenderContext context)
{
return enabled.value
&& intensity.value > 0
&& context.camera.transform.position.y <= waterLevel.value;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82593716811bfb449b4a447ef9eb28b9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
#if UNITY_POST_PROCESSING_STACK_V2
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering.PostProcessing;
namespace Pinwheel.Poseidon.FX.PostProcessing
{
public class PUnderwaterRenderer : PostProcessEffectRenderer<PUnderwater>
{
public override void Render(PostProcessRenderContext context)
{
PropertySheet sheet = context.propertySheets.Get(PPoseidonSettings.Instance.UnderwaterShader);
sheet.properties.SetFloat(PMat.PP_WATER_LEVEL, settings.waterLevel);
sheet.properties.SetFloat(PMat.PP_MAX_DEPTH, settings.maxDepth);
sheet.properties.SetFloat(PMat.PP_SURFACE_COLOR_BOOST, settings.surfaceColorBoost);
sheet.properties.SetColor(PMat.PP_SHALLOW_FOG_COLOR, settings.shallowFogColor);
sheet.properties.SetColor(PMat.PP_DEEP_FOG_COLOR, settings.deepFogColor);
sheet.properties.SetFloat(PMat.PP_VIEW_DISTANCE, settings.viewDistance);
if (settings.enableCaustic && settings.causticTexture.value != null)
{
sheet.EnableKeyword(PMat.KW_PP_CAUSTIC);
sheet.properties.SetTexture(PMat.PP_NOISE_TEX, PPoseidonSettings.Instance.NoiseTexture);
sheet.properties.SetTexture(PMat.PP_CAUSTIC_TEX, settings.causticTexture.value);
sheet.properties.SetFloat(PMat.PP_CAUSTIC_SIZE, settings.causticSize);
sheet.properties.SetFloat(PMat.PP_CAUSTIC_STRENGTH, settings.causticStrength);
}
else
{
sheet.DisableKeyword(PMat.KW_PP_CAUSTIC);
}
if (settings.enableDistortion && settings.distortionNormalMap.value != null)
{
sheet.EnableKeyword(PMat.KW_PP_DISTORTION);
sheet.properties.SetTexture(PMat.PP_DISTORTION_TEX, settings.distortionNormalMap.value);
sheet.properties.SetFloat(PMat.PP_DISTORTION_STRENGTH, settings.distortionStrength);
sheet.properties.SetFloat(PMat.PP_WATER_FLOW_SPEED, settings.waterFlowSpeed);
}
else
{
sheet.DisableKeyword(PMat.KW_PP_DISTORTION);
}
sheet.properties.SetVector(PMat.PP_CAMERA_VIEW_DIR, context.camera.transform.forward);
sheet.properties.SetFloat(PMat.PP_CAMERA_FOV, context.camera.fieldOfView);
sheet.properties.SetMatrix(PMat.PP_CAMERA_TO_WORLD_MATRIX, context.camera.cameraToWorldMatrix);
sheet.properties.SetFloat(PMat.PP_INTENSITY, settings.intensity);
context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
}
public override DepthTextureMode GetCameraFlags()
{
return DepthTextureMode.Depth;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1232f4a297f2128449d5381cfd47cce0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
#if UNITY_POST_PROCESSING_STACK_V2
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering.PostProcessing;
namespace Pinwheel.Poseidon.FX.PostProcessing
{
[System.Serializable]
[PostProcess(typeof(PWetLensRenderer), PostProcessEvent.BeforeStack, "Poseidon/Wet Lens", false)]
public sealed class PWetLens : PostProcessEffectSettings
{
[Header("Lens Distort")]
public TextureParameter normalMap = new TextureParameter();
[Range(0f, 1f)]
public FloatParameter strength = new FloatParameter();
[Header("Internal")]
[Range(0f, 1f)]
public FloatParameter intensity = new FloatParameter();
public override bool IsEnabledAndSupported(PostProcessRenderContext context)
{
return enabled.value
&& normalMap.value != null
&& intensity.value > 0;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ea78e3311d3bc648ac0f3f022f2f307
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
#if UNITY_POST_PROCESSING_STACK_V2
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering.PostProcessing;
namespace Pinwheel.Poseidon.FX.PostProcessing
{
public class PWetLensRenderer : PostProcessEffectRenderer<PWetLens>
{
public override void Render(PostProcessRenderContext context)
{
PropertySheet sheet = context.propertySheets.Get(PPoseidonSettings.Instance.WetLensShader);
Texture normalMap = settings.normalMap.value ?? PPoseidonSettings.Instance.DefaultNormalMap;
sheet.properties.SetTexture(PMat.PP_WET_LENS_TEX, normalMap);
sheet.properties.SetFloat(PMat.PP_WET_LENS_STRENGTH, settings.strength * settings.intensity);
context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6475c569b1d701745953c7e26ea7d7f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,417 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Events;
#if UNITY_POST_PROCESSING_STACK_V2
using Pinwheel.Poseidon.FX.PostProcessing;
using UnityEngine.Rendering.PostProcessing;
#endif
#if POSEIDON_URP
using Pinwheel.Poseidon.FX.Universal;
#endif
namespace Pinwheel.Poseidon.FX
{
[ExecuteInEditMode]
[RequireComponent(typeof(PWater))]
public class PWaterFX : MonoBehaviour
{
[SerializeField]
private PWater water;
public PWater Water
{
get
{
return water;
}
set
{
water = value;
}
}
[SerializeField]
private PWaterFXProfile profile;
public PWaterFXProfile Profile
{
get
{
return profile;
}
set
{
PWaterFXProfile oldProfile = profile;
PWaterFXProfile newProfile = value;
profile = newProfile;
if (oldProfile != newProfile && newProfile != null)
{
UpdatePostProcessOrVolumeProfile();
}
}
}
#if UNITY_POST_PROCESSING_STACK_V2
public PostProcessProfile PostProcessProfile { get; private set; }
public PostProcessVolume PostProcessVolume { get; private set; }
#endif
#if POSEIDON_URP
public VolumeProfile VolumeProfile { get; private set; }
public Volume Volume { get; private set; }
#endif
[SerializeField]
private Vector3 volumeExtent;
public Vector3 VolumeExtent
{
get
{
return volumeExtent;
}
set
{
Vector3 v = value;
//v.x = Mathf.Max(0, v.x);
//v.y = Mathf.Max(0, v.y);
//v.z = Mathf.Max(0, v.z);
volumeExtent = v;
}
}
[SerializeField]
private LayerMask volumeLayer;
public LayerMask VolumeLayer
{
get
{
return volumeLayer;
}
set
{
volumeLayer = value;
}
}
private float lastDistanceToSurface;
private float wetLensTime;
[SerializeField]
private UnityEvent onEnterWater;
public UnityEvent OnEnterWater
{
get
{
return onEnterWater;
}
set
{
onEnterWater = value;
}
}
[SerializeField]
private UnityEvent onExitWater;
public UnityEvent OnExitWater
{
get
{
return onExitWater;
}
set
{
onExitWater = value;
}
}
private void Reset()
{
Water = GetComponent<PWater>();
#if UNITY_POST_PROCESSING_STACK_V2
VolumeExtent = new Vector3(0, 100, 0);
#endif
}
private void OnEnable()
{
Camera.onPreCull += OnCameraPreCull;
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
if (Camera.main != null)
{
float waterHeight = GetWaterHeight(Camera.main.transform.position);
lastDistanceToSurface = Camera.main.transform.position.y - waterHeight;
}
wetLensTime = Mathf.Infinity;
if (PUtilities.IsPlaying)
{
SetupQuickVolume();
}
}
private void OnDisable()
{
Camera.onPreCull -= OnCameraPreCull;
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
CleanupQuickVolume();
}
private void OnBeginCameraRendering(ScriptableRenderContext context, Camera cam)
{
OnCameraPreCull(cam);
}
private void OnCameraPreCull(Camera cam)
{
UpdateEffects(cam);
if (cam == Camera.main && Water != null)
{
Vector3 cameraPos = cam.transform.position;
float waterHeight = GetWaterHeight(cam.transform.position);
float distanceToSuface = cam.transform.position.y - waterHeight;
if (distanceToSuface <= 0 && lastDistanceToSurface > 0)
{
if (Water.CheckTilesContainPoint(cameraPos))
{
OnEnterWater.Invoke();
}
}
if (distanceToSuface > 0 && lastDistanceToSurface <= 0)
{
if (Water.CheckTilesContainPoint(cameraPos))
{
OnExitWater.Invoke();
}
}
lastDistanceToSurface = cameraPos.y - waterHeight;
}
}
private void SetupQuickVolume()
{
if (Water == null || Profile == null)
return;
Water.ReCalculateBounds();
Bounds bounds = Water.Bounds;
GameObject volumeGO = null;
#if UNITY_POST_PROCESSING_STACK_V2
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
PostProcessEffectSettings[] settings = new PostProcessEffectSettings[0];
PostProcessVolume volume = PostProcessManager.instance.QuickVolume(VolumeLayer, 0, settings);
volume.isGlobal = false;
volumeGO = volume.gameObject;
PostProcessVolume = volume;
PostProcessProfile = volume.profile;
PostProcessProfile.name = "~TemporaryEffectProfile";
Profile.UpdatePostProcessingProfile(PostProcessProfile);
}
#endif
#if POSEIDON_URP
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
volumeGO = new GameObject();
volumeGO.layer = VolumeLayer;
Volume volume = volumeGO.AddComponent<Volume>();
volume.isGlobal = false;
VolumeProfile profile = ScriptableObject.CreateInstance<VolumeProfile>();
volume.profile = profile;
this.Volume = volume;
this.VolumeProfile = profile;
this.VolumeProfile.name = "~TemporaryEffectProfile";
Profile.UpdateVolumeProfile(VolumeProfile);
}
#endif
volumeGO.hideFlags = HideFlags.DontSave;
volumeGO.transform.parent = transform;
volumeGO.transform.localPosition = bounds.center;
volumeGO.transform.localRotation = Quaternion.identity;
volumeGO.transform.localScale = Vector3.one;
volumeGO.name = "~WaterPostFXVolume";
BoxCollider b = volumeGO.AddComponent<BoxCollider>();
b.center = new Vector3(0, 0, 0);
b.size = bounds.size + VolumeExtent;
b.isTrigger = true;
}
private void CleanupQuickVolume()
{
#if UNITY_POST_PROCESSING_STACK_V2
if (PostProcessProfile != null)
{
PUtilities.DestroyObject(PostProcessProfile);
}
if (PostProcessVolume != null)
{
PUtilities.DestroyGameobject(PostProcessVolume.gameObject);
}
#endif
#if POSEIDON_URP
if (VolumeProfile != null)
{
PUtilities.DestroyObject(VolumeProfile);
}
if (Volume != null)
{
PUtilities.DestroyGameobject(Volume.gameObject);
}
#endif
}
private void UpdateEffects(Camera cam)
{
if (cam == null)
return;
if (cam != Camera.main)
return;
if (Profile == null)
return;
float waterHeight = GetWaterHeight(cam.transform.position);
if (Profile.EnableUnderwater)
{
float intensity = cam.transform.position.y < waterHeight ? 1 : 0;
UpdateUnderwaterIntensityAndWaterLevel(intensity, waterHeight);
}
float distanceToSurface = Camera.main.transform.position.y - waterHeight;
if (Profile.EnableWetLens)
{
if (distanceToSurface > 0 && lastDistanceToSurface <= 0)
{
wetLensTime = 0;
}
float intensity;
if (distanceToSurface <= 0)
{
intensity = 0;
}
else if (wetLensTime > Profile.WetLensDuration)
{
intensity = 0;
}
else
{
float f = Mathf.InverseLerp(0, Profile.WetLensDuration, wetLensTime);
intensity = Profile.WetLensFadeCurve.Evaluate(f);
}
UpdateWetLensIntensity(intensity);
}
wetLensTime += PUtilities.DeltaTime;
}
private void UpdateUnderwaterIntensityAndWaterLevel(float intensity, float waterLevel)
{
#if UNITY_POST_PROCESSING_STACK_V2
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
if (PostProcessProfile == null)
return;
PUnderwater underwaterSettings;
if (PostProcessProfile.TryGetSettings<PUnderwater>(out underwaterSettings))
{
underwaterSettings.intensity.Override(intensity);
underwaterSettings.waterLevel.Override(waterLevel);
}
}
#endif
#if POSEIDON_URP
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
if (VolumeProfile == null)
return;
PUnderwaterOverride underwaterSettigns;
if (VolumeProfile.TryGet<PUnderwaterOverride>(out underwaterSettigns))
{
underwaterSettigns.intensity.Override(intensity);
underwaterSettigns.waterLevel.Override(waterLevel);
}
}
#endif
}
private void UpdateWetLensIntensity(float intensity)
{
#if UNITY_POST_PROCESSING_STACK_V2
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
if (PostProcessProfile == null)
return;
PWetLens wetlensSettings;
if (PostProcessProfile.TryGetSettings<PWetLens>(out wetlensSettings))
{
wetlensSettings.intensity.Override(intensity);
}
}
#endif
#if POSEIDON_URP
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
if (VolumeProfile == null)
return;
PWetLensOverride wetlensSettings;
if (VolumeProfile.TryGet<PWetLensOverride>(out wetlensSettings))
{
wetlensSettings.intensity.Override(intensity);
}
}
#endif
}
public void UpdatePostProcessOrVolumeProfile()
{
if (profile == null)
return;
#if UNITY_POST_PROCESSING_STACK_V2
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
{
if (PostProcessProfile != null)
{
profile.UpdatePostProcessingProfile(PostProcessProfile);
}
}
#endif
#if POSEIDON_URP
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
{
if (VolumeProfile != null)
{
profile.UpdateVolumeProfile(VolumeProfile);
}
}
#endif
}
private float GetWaterHeight(Vector3 worldPos)
{
if (water == null)
return 0;
if (water.Profile.EnableWave)
{
Vector3 localPos = water.transform.InverseTransformPoint(worldPos);
localPos.y = 0;
localPos = water.GetLocalVertexPosition(localPos, false);
worldPos = water.transform.TransformPoint(localPos);
return worldPos.y;
}
else
{
return water.transform.position.y;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61bb74f3f8e394c4c93cc61a6c3221bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,438 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
#if UNITY_POST_PROCESSING_STACK_V2
using Pinwheel.Poseidon.FX.PostProcessing;
using UnityEngine.Rendering.PostProcessing;
#endif
#if UNITY_EDITOR
using UnityEditor;
#endif
#if POSEIDON_URP
using Pinwheel.Poseidon.FX.Universal;
#endif
namespace Pinwheel.Poseidon.FX
{
[CreateAssetMenu(menuName = "Poseidon/Water FX Profile")]
public class PWaterFXProfile : ScriptableObject
{
[SerializeField]
private bool enableUnderwater;
public bool EnableUnderwater
{
get
{
return enableUnderwater;
}
set
{
enableUnderwater = value;
}
}
[SerializeField]
private float underwaterMaxDepth;
public float UnderwaterMaxDepth
{
get
{
return underwaterMaxDepth;
}
set
{
underwaterMaxDepth = Mathf.Max(0, value);
}
}
[SerializeField]
private float underwaterSurfaceColorBoost;
public float UnderwaterSurfaceColorBoost
{
get
{
return underwaterSurfaceColorBoost;
}
set
{
underwaterSurfaceColorBoost = Mathf.Max(0, value);
}
}
[SerializeField]
private Color underwaterShallowFogColor;
public Color UnderwaterShallowFogColor
{
get
{
return underwaterShallowFogColor;
}
set
{
underwaterShallowFogColor = value;
}
}
[SerializeField]
private Color underwaterDeepFogColor;
public Color UnderwaterDeepFogColor
{
get
{
return underwaterDeepFogColor;
}
set
{
underwaterDeepFogColor = value;
}
}
[SerializeField]
private float underwaterViewDistance;
public float UnderwaterViewDistance
{
get
{
return underwaterViewDistance;
}
set
{
underwaterViewDistance = Mathf.Max(0, value);
}
}
[SerializeField]
private bool underwaterEnableCaustic;
public bool UnderwaterEnableCaustic
{
get
{
return underwaterEnableCaustic;
}
set
{
underwaterEnableCaustic = value;
}
}
[SerializeField]
private Texture underwaterCausticTexture;
public Texture UnderwaterCausticTexture
{
get
{
return underwaterCausticTexture;
}
set
{
underwaterCausticTexture = value;
}
}
[SerializeField]
private float underwaterCausticSize;
public float UnderwaterCausticSize
{
get
{
return underwaterCausticSize;
}
set
{
underwaterCausticSize = value;
}
}
[SerializeField]
private float underwaterCausticStrength;
public float UnderwaterCausticStrength
{
get
{
return underwaterCausticStrength;
}
set
{
underwaterCausticStrength = Mathf.Clamp01(value);
}
}
[SerializeField]
private bool underwaterEnableDistortion;
public bool UnderwaterEnableDistortion
{
get
{
return underwaterEnableDistortion;
}
set
{
underwaterEnableDistortion = value;
}
}
[SerializeField]
private Texture underwaterDistortionTexture;
public Texture UnderwaterDistortionTexture
{
get
{
return underwaterDistortionTexture;
}
set
{
underwaterDistortionTexture = value;
}
}
[SerializeField]
private float underwaterDistortionStrength;
public float UnderwaterDistortionStrength
{
get
{
return underwaterDistortionStrength;
}
set
{
underwaterDistortionStrength = value;
}
}
[SerializeField]
private float underwaterWaterFlowSpeed;
public float UnderwaterWaterFlowSpeed
{
get
{
return underwaterWaterFlowSpeed;
}
set
{
underwaterWaterFlowSpeed = value;
}
}
private float underwaterIntensity;
public float UnderwaterIntensity
{
get
{
return underwaterIntensity;
}
set
{
underwaterIntensity = value;
}
}
[SerializeField]
private bool enableWetLens;
public bool EnableWetLens
{
get
{
return enableWetLens;
}
set
{
enableWetLens = value;
}
}
[SerializeField]
private Texture wetLensNormalMap;
public Texture WetLensNormalMap
{
get
{
return wetLensNormalMap;
}
set
{
wetLensNormalMap = value;
}
}
[SerializeField]
private float wetLensStrength;
public float WetLensStrength
{
get
{
return wetLensStrength;
}
set
{
wetLensStrength = Mathf.Clamp01(value);
}
}
private float wetLensIntensity;
public float WetLensIntensity
{
get
{
return wetLensIntensity;
}
set
{
wetLensIntensity = Mathf.Clamp01(value);
}
}
[SerializeField]
private float wetLensDuration;
public float WetLensDuration
{
get
{
return wetLensDuration;
}
set
{
wetLensDuration = Mathf.Max(0.01f, value);
}
}
[SerializeField]
private AnimationCurve wetLensFadeCurve;
public AnimationCurve WetLensFadeCurve
{
get
{
if (wetLensFadeCurve == null)
{
wetLensFadeCurve = AnimationCurve.Linear(0, 1, 1, 0);
}
return wetLensFadeCurve;
}
set
{
wetLensFadeCurve = value;
}
}
public void Reset()
{
EnableUnderwater = true;
UnderwaterMaxDepth = 10;
UnderwaterShallowFogColor = new Color(0, 0, 0, 0.5f);
UnderwaterDeepFogColor = new Color(0, 0, 0, 0.95f);
UnderwaterViewDistance = 50;
UnderwaterEnableCaustic = false;
UnderwaterCausticTexture = null;
UnderwaterCausticSize = 10;
UnderwaterCausticStrength = 1;
UnderwaterEnableDistortion = true;
UnderwaterDistortionTexture = PPoseidonSettings.Instance.DefaultUnderwaterDistortionMap;
UnderwaterDistortionStrength = 0.5f;
UnderwaterWaterFlowSpeed = 1;
EnableWetLens = true;
WetLensNormalMap = PPoseidonSettings.Instance.DefaultWetLensDistortionMap;
WetLensStrength = 1;
WetLensDuration = 3;
WetLensFadeCurve = AnimationCurve.Linear(0, 1, 1, 0);
}
#if UNITY_POST_PROCESSING_STACK_V2
public void UpdatePostProcessingProfile(PostProcessProfile p)
{
if (!p.HasSettings<PUnderwater>())
{
p.AddSettings<PUnderwater>();
}
PUnderwater underwaterSettings = p.GetSetting<PUnderwater>();
underwaterSettings.active = EnableUnderwater;
underwaterSettings.enabled.Override(EnableUnderwater);
if (EnableUnderwater)
{
underwaterSettings.maxDepth.Override(UnderwaterMaxDepth);
underwaterSettings.surfaceColorBoost.Override(UnderwaterSurfaceColorBoost);
underwaterSettings.shallowFogColor.Override(UnderwaterShallowFogColor);
underwaterSettings.deepFogColor.Override(UnderwaterDeepFogColor);
underwaterSettings.viewDistance.Override(UnderwaterViewDistance);
underwaterSettings.enableCaustic.Override(UnderwaterEnableCaustic);
underwaterSettings.causticTexture.Override(UnderwaterCausticTexture);
underwaterSettings.causticSize.Override(UnderwaterCausticSize);
underwaterSettings.causticStrength.Override(UnderwaterCausticStrength);
underwaterSettings.enableDistortion.Override(UnderwaterEnableDistortion);
underwaterSettings.distortionNormalMap.Override(UnderwaterDistortionTexture);
underwaterSettings.distortionStrength.Override(UnderwaterDistortionStrength);
underwaterSettings.waterFlowSpeed.Override(UnderwaterWaterFlowSpeed);
}
if (!p.HasSettings<PWetLens>())
{
p.AddSettings<PWetLens>();
}
PWetLens wetLensSettings = p.GetSetting<PWetLens>();
wetLensSettings.active = EnableWetLens;
wetLensSettings.enabled.Override(EnableWetLens);
if (EnableWetLens)
{
wetLensSettings.normalMap.Override(WetLensNormalMap);
wetLensSettings.strength.Override(WetLensStrength);
}
}
#endif
#if POSEIDON_URP
public void UpdateVolumeProfile(VolumeProfile p)
{
if (!p.Has<PUnderwaterOverride>())
{
p.Add<PUnderwaterOverride>();
}
PUnderwaterOverride underwaterSettings;
if (p.TryGet<PUnderwaterOverride>(out underwaterSettings))
{
underwaterSettings.active = EnableUnderwater;
if (EnableUnderwater)
{
underwaterSettings.maxDepth.Override(UnderwaterMaxDepth);
underwaterSettings.surfaceColorBoost.Override(UnderwaterSurfaceColorBoost);
underwaterSettings.shallowFogColor.Override(UnderwaterShallowFogColor);
underwaterSettings.deepFogColor.Override(UnderwaterDeepFogColor);
underwaterSettings.viewDistance.Override(UnderwaterViewDistance);
underwaterSettings.enableCaustic.Override(UnderwaterEnableCaustic);
underwaterSettings.causticTexture.Override(UnderwaterCausticTexture);
underwaterSettings.causticSize.Override(UnderwaterCausticSize);
underwaterSettings.causticStrength.Override(UnderwaterCausticStrength);
underwaterSettings.enableDistortion.Override(UnderwaterEnableDistortion);
underwaterSettings.distortionNormalMap.Override(UnderwaterDistortionTexture);
underwaterSettings.distortionStrength.Override(UnderwaterDistortionStrength);
underwaterSettings.waterFlowSpeed.Override(UnderwaterWaterFlowSpeed);
}
}
if (!p.Has<PWetLensOverride>())
{
p.Add<PWetLensOverride>();
}
PWetLensOverride wetLensSettings;
if (p.TryGet<PWetLensOverride>(out wetLensSettings))
{
wetLensSettings.active = EnableWetLens;
if (EnableWetLens)
{
wetLensSettings.normalMap.Override(WetLensNormalMap);
wetLensSettings.strength.Override(WetLensStrength);
}
}
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1198c0a6311ad44408a8d6bd3161243c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 74b436c737d963648b2e6896d0332e79
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
#if POSEIDON_URP
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace Pinwheel.Poseidon.FX.Universal
{
[System.Serializable]
[VolumeComponentMenu("Poseidon/Underwater")]
public class PUnderwaterOverride : VolumeComponent
{
[Header("Water Body")]
public FloatParameter waterLevel = new FloatParameter(0);
public FloatParameter maxDepth = new FloatParameter(10);
[Range(0f, 3f)]
public FloatParameter surfaceColorBoost = new FloatParameter(1);
[Header("Fog")]
public ColorParameter shallowFogColor = new ColorParameter(new Color(0,0,1,0.5f));
public ColorParameter deepFogColor = new ColorParameter(new Color(0,0,1,1));
public FloatParameter viewDistance = new FloatParameter(40);
[Header("Caustic")]
public BoolParameter enableCaustic = new BoolParameter(false);
public TextureParameter causticTexture = new TextureParameter(null);
public FloatParameter causticSize = new FloatParameter(10);
[Range(0f, 1f)]
public FloatParameter causticStrength = new FloatParameter(1);
[Header("Distortion")]
public BoolParameter enableDistortion = new BoolParameter(false);
public TextureParameter distortionNormalMap = new TextureParameter(null);
public FloatParameter distortionStrength = new FloatParameter(1);
public FloatParameter waterFlowSpeed = new FloatParameter(1);
[Header("Internal")]
[Range(0f, 1f)]
public FloatParameter intensity = new FloatParameter(0);
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 737bb5c030cbe824a900bc5999ac94f9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,143 @@
#if POSEIDON_URP
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Pinwheel.Poseidon.FX.Universal
{
public class PWaterEffectRendererFeature : ScriptableRendererFeature
{
public class PWaterEffectPass : ScriptableRenderPass
{
public const string PROFILER_TAG = "Water FX";
private Material underwaterMaterial;
private Material wetLensMaterial;
private RenderTargetIdentifier cameraTarget;
private RenderTargetHandle temporaryRenderTexture;
public PWaterEffectPass(RenderTargetIdentifier cameraTarget)
{
this.cameraTarget = cameraTarget;
renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
}
private void ConfigureMaterial(ref RenderingData renderingData, PUnderwaterOverride underwater, PWetLensOverride wetLens)
{
if (underwater.intensity.value > 0)
{
if (underwaterMaterial == null)
{
Shader shader = PPoseidonSettings.Instance.UnderwaterShaderURP;
underwaterMaterial = CoreUtils.CreateEngineMaterial(shader);
}
underwaterMaterial.SetFloat(PMat.PP_WATER_LEVEL, underwater.waterLevel.value);
underwaterMaterial.SetFloat(PMat.PP_MAX_DEPTH, underwater.maxDepth.value);
underwaterMaterial.SetFloat(PMat.PP_SURFACE_COLOR_BOOST, underwater.surfaceColorBoost.value);
underwaterMaterial.SetColor(PMat.PP_SHALLOW_FOG_COLOR, underwater.shallowFogColor.value);
underwaterMaterial.SetColor(PMat.PP_DEEP_FOG_COLOR, underwater.deepFogColor.value);
underwaterMaterial.SetFloat(PMat.PP_VIEW_DISTANCE, underwater.viewDistance.value);
if (underwater.enableCaustic.value == true)
{
underwaterMaterial.EnableKeyword(PMat.KW_PP_CAUSTIC);
underwaterMaterial.SetTexture(PMat.PP_CAUSTIC_TEX, underwater.causticTexture.value);
underwaterMaterial.SetFloat(PMat.PP_CAUSTIC_SIZE, underwater.causticSize.value);
underwaterMaterial.SetFloat(PMat.PP_CAUSTIC_STRENGTH, underwater.causticStrength.value);
}
else
{
underwaterMaterial.DisableKeyword(PMat.KW_PP_CAUSTIC);
}
if (underwater.enableDistortion.value == true)
{
underwaterMaterial.EnableKeyword(PMat.KW_PP_DISTORTION);
underwaterMaterial.SetTexture(PMat.PP_DISTORTION_TEX, underwater.distortionNormalMap.value);
underwaterMaterial.SetFloat(PMat.PP_DISTORTION_STRENGTH, underwater.distortionStrength.value);
underwaterMaterial.SetFloat(PMat.PP_WATER_FLOW_SPEED, underwater.waterFlowSpeed.value);
}
else
{
underwaterMaterial.DisableKeyword(PMat.KW_PP_DISTORTION);
}
underwaterMaterial.SetTexture(PMat.PP_NOISE_TEX, PPoseidonSettings.Instance.NoiseTexture);
underwaterMaterial.SetVector(PMat.PP_CAMERA_VIEW_DIR, renderingData.cameraData.camera.transform.forward);
underwaterMaterial.SetFloat(PMat.PP_CAMERA_FOV, renderingData.cameraData.camera.fieldOfView);
underwaterMaterial.SetMatrix(PMat.PP_CAMERA_TO_WORLD_MATRIX, renderingData.cameraData.camera.cameraToWorldMatrix);
underwaterMaterial.SetFloat(PMat.PP_INTENSITY, underwater.intensity.value);
}
if (wetLens.strength.value * wetLens.intensity.value > 0)
{
if (wetLensMaterial == null)
{
Shader shader = PPoseidonSettings.Instance.WetLensShaderURP;
wetLensMaterial = CoreUtils.CreateEngineMaterial(shader);
}
Texture normalMap = wetLens.normalMap.value ?? PPoseidonSettings.Instance.DefaultNormalMap;
wetLensMaterial.SetTexture(PMat.PP_WET_LENS_TEX, normalMap);
wetLensMaterial.SetFloat(PMat.PP_WET_LENS_STRENGTH, wetLens.strength.value * wetLens.intensity.value);
}
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (renderingData.cameraData.camera != Camera.main)
return;
VolumeStack stack = VolumeManager.instance.stack;
PUnderwaterOverride underwater = stack.GetComponent<PUnderwaterOverride>();
PWetLensOverride wetLens = stack.GetComponent<PWetLensOverride>();
bool willRenderUnderwater = underwater.intensity.value > 0;
bool willRenderWetLens = wetLens.strength.value * wetLens.intensity.value > 0;
if (!willRenderUnderwater && !willRenderWetLens)
return;
ConfigureMaterial(ref renderingData, underwater, wetLens);
CommandBuffer cmd = CommandBufferPool.Get(PROFILER_TAG);
RenderTextureDescriptor cameraTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor;
cameraTargetDescriptor.depthBufferBits = 0;
cmd.GetTemporaryRT(temporaryRenderTexture.id, cameraTargetDescriptor);
Material material = willRenderUnderwater ? underwaterMaterial : wetLensMaterial;
Blit(cmd, cameraTarget, temporaryRenderTexture.Identifier(), material, 0);
Blit(cmd, temporaryRenderTexture.Identifier(), cameraTarget);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public override void FrameCleanup(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(temporaryRenderTexture.id);
}
}
private PWaterEffectPass waterEffectPass;
public override void Create()
{
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
waterEffectPass = new PWaterEffectPass(renderer.cameraColorTarget);
renderer.EnqueuePass(waterEffectPass);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52820e82bff58474cbdc4c685df7f99a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
#if POSEIDON_URP
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace Pinwheel.Poseidon.FX.Universal
{
[System.Serializable]
[VolumeComponentMenu("Poseidon/Wet Lens")]
public class PWetLensOverride : VolumeComponent
{
[Header("Lens Distort")]
public TextureParameter normalMap = new TextureParameter(null);
[Range(0f, 1f)]
public FloatParameter strength = new FloatParameter(1);
[Header("Internal")]
[Range(0f, 1f)]
public FloatParameter intensity = new FloatParameter(0);
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 720855a007109dd4190a93defd8e3bb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 555c9d77f9fe0d246a57cb48a9d41de0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
#if GRIFFIN && GRIFFIN_2020
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pinwheel.Griffin.SplineTool;
using Pinwheel.Griffin;
namespace Pinwheel.Poseidon
{
[GDisplayName("Poseidon/Water Spline Sync")]
[ExecuteInEditMode]
public class PWaterSplineSync : GSplineModifier
{
[SerializeField]
private PWater water;
public PWater Water
{
get
{
return water;
}
set
{
water = value;
}
}
[SerializeField]
private float heightOffset;
public float HeightOffset
{
get
{
return heightOffset;
}
set
{
heightOffset = value;
}
}
private void OnEnable()
{
GSplineCreator.Editor_SplineChanged += OnSplineChanged;
}
private void OnDisable()
{
GSplineCreator.Editor_SplineChanged -= OnSplineChanged;
}
private void OnValidate()
{
Apply();
}
private void OnSplineChanged(GSplineCreator creator)
{
if (creator == this.SplineCreator)
{
Apply();
}
}
public override void Apply()
{
if (SplineCreator == null && Water == null)
return;
if (Water.MeshType != PWaterMeshType.Spline)
return;
GSpline gSpline = SplineCreator.Spline;
PSpline pSpline = Water.Spline;
pSpline.Dispose();
pSpline.Anchors.Clear();
pSpline.Segments.Clear();
for (int i = 0; i < gSpline.Anchors.Count; ++i)
{
PSplineAnchor a = (PSplineAnchor)gSpline.Anchors[i];
a.Position += Vector3.up * HeightOffset;
pSpline.Anchors.Add(a);
}
for (int i = 0; i < gSpline.Segments.Count; ++i)
{
PSplineSegment s = (PSplineSegment)gSpline.Segments[i];
s.StartTangent += Vector3.up * HeightOffset;
s.EndTangent += Vector3.up * HeightOffset;
pSpline.Segments.Add(s);
}
Water.transform.position = transform.position;
Water.transform.rotation = transform.rotation;
Water.transform.localScale = transform.localScale;
Water.SplineWidth = SplineCreator.Width + SplineCreator.FalloffWidth * 2;
Water.GenerateSplineMesh();
Water.ReCalculateBounds();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 928f78f1e4e8d524f8af949880997802
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e55ce90e1f8a9bb488b8e0a6047a2057
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Poseidon
{
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class PDisplayName : Attribute
{
public string DisplayName { get; set; }
public PDisplayName(string name)
{
DisplayName = name;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f23ee4d317e43a4b9f7c5d7a9ad5bbe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
namespace Pinwheel.Poseidon
{
public static class PGeometryUtilities
{
public static bool IsIntersectHorizontalLine(
float x1, float y1,
float x2, float y2,
float lineY,
out Vector2 intersection)
{
bool isIntersect = false;
intersection = Vector2.zero;
float minX = Mathf.Min(x1, x2);
float maxX = Mathf.Max(x1, x2);
float minY = Mathf.Min(y1, y2);
float maxY = Mathf.Max(y1, y2);
if (lineY < minY || lineY > maxY)
{
isIntersect = false;
return isIntersect;
}
if (x1 == x2 && y1 == y2)
{
if (lineY == y1)
{
isIntersect = true;
intersection.Set(x1, y1);
return isIntersect;
}
else
{
isIntersect = false;
}
}
Vector2 direction = new Vector2(x2 - x1, y2 - y1).normalized;
Vector3 normal = new Vector3(-direction.y, direction.x);
if (direction == Vector2.left || direction == Vector2.right)
{
isIntersect = false;
return isIntersect;
}
float num = (x2 - x1) * lineY + (x1 * y2 - x2 * y1);
float denom = -y1 + y2;
float intersectX = num / denom;
if (intersectX >= minX && intersectX <= maxX)
{
intersection.Set(intersectX, lineY);
isIntersect = true;
return isIntersect;
}
isIntersect = false;
return isIntersect;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 210448ef7a04a2a43aa3eb03b3293f98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Pinwheel.Poseidon
{
/// <summary>
/// Indicate an index in 2D grid with 2 component X, Z
/// </summary>
[System.Serializable]
public struct PIndex2D
{
[SerializeField]
private int x;
public int X
{
get
{
return x;
}
set
{
x = value;
}
}
[SerializeField]
private int z;
public int Z
{
get
{
return z;
}
set
{
z = value;
}
}
public PIndex2D(int x, int z)
{
this.x = x;
this.z = z;
}
public static PIndex2D operator +(PIndex2D i1, PIndex2D i2)
{
return new PIndex2D(i1.x + i2.x, i1.z + i2.z);
}
public static PIndex2D operator -(PIndex2D i1, PIndex2D i2)
{
return new PIndex2D(i1.x - i2.x, i1.z - i2.z);
}
public static bool operator ==(PIndex2D i1, PIndex2D i2)
{
return i1.x == i2.x && i1.z == i2.z;
}
public static bool operator !=(PIndex2D i1, PIndex2D i2)
{
return i1.x != i2.x || i1.z != i2.z;
}
public override string ToString()
{
return string.Format("({0}, {1})", x, z);
}
public override bool Equals(object obj)
{
if (!(obj is PIndex2D))
{
return false;
}
var d = (PIndex2D)obj;
return x == d.x &&
z == d.z;
}
public override int GetHashCode()
{
var hashCode = 1553271884;
hashCode = hashCode * -1521134295 + x.GetHashCode();
hashCode = hashCode * -1521134295 + z.GetHashCode();
return hashCode;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ffd21657777e8545a7649cfe28f73b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public static class PInternalMaterials
{
private static Material copyTextureMaterial;
public static Material CopyTextureMaterial
{
get
{
if (copyTextureMaterial == null)
{
copyTextureMaterial = new Material(PPoseidonSettings.Instance.InternalShaders.CopyTextureShader);
}
return copyTextureMaterial;
}
}
private static Material solidColorMaterial;
public static Material SolidColorMaterial
{
get
{
if (solidColorMaterial == null)
{
solidColorMaterial = new Material(PPoseidonSettings.Instance.InternalShaders.SolidColorShader);
}
return solidColorMaterial;
}
}
private static Material unlitTextureMaterial;
public static Material UnlitTextureMaterial
{
get
{
if (unlitTextureMaterial == null)
{
unlitTextureMaterial = new Material(Shader.Find("Unlit/Texture"));
}
return unlitTextureMaterial;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a0f74f6c4ea3694ea088a19d13922dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
[System.Serializable]
public struct PInternalShaderSettings
{
[SerializeField]
private Shader copyTextureShader;
public Shader CopyTextureShader
{
get
{
return copyTextureShader;
}
set
{
copyTextureShader = value;
}
}
[SerializeField]
private Shader solidColorShader;
public Shader SolidColorShader
{
get
{
return solidColorShader;
}
set
{
solidColorShader = value;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a640a71d32534704f8801234c11d2a56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Poseidon
{
public class PProgressCancelledException : Exception
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc5b0a1572a0da346866ab317355eaf2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
public enum PRenderPipelineType
{
Builtin, Universal, Unsupported
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 482afd6d4d70f5b41b9d3fa8387f1be0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,782 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Poseidon
{
/// <summary>
/// Utility class for helper function
/// </summary>
public static class PUtilities
{
public static float DELTA_TIME = 0.0167f;
public static bool IsPlaying
{
get
{
#if UNITY_EDITOR
return EditorApplication.isPlaying;
#else
return true;
#endif
}
}
public static float DeltaTime
{
get
{
#if UNITY_EDITOR
return EditorApplication.isPlaying ? Time.deltaTime : DELTA_TIME;
#else
return Time.deltaTime;
#endif
}
}
private static Mesh quadMesh;
public static Mesh QuadMesh
{
get
{
if (quadMesh == null)
{
quadMesh = PUtilities.GetPrimitiveMesh(PrimitiveType.Quad);
}
return quadMesh;
}
}
public static string ListElementsToString<T>(this IEnumerable<T> list, string separator)
{
IEnumerator<T> i = list.GetEnumerator();
System.Text.StringBuilder s = new System.Text.StringBuilder();
if (i.MoveNext())
s.Append(i.Current.ToString());
while (i.MoveNext())
s.Append(separator).Append(i.Current.ToString());
return s.ToString();
}
public static T[][] CreateJaggedArray<T>(int dimension1, int dimension2)
{
T[][] jaggedArray = new T[dimension1][];
for (int i = 0; i < dimension1; ++i)
{
jaggedArray[i] = new T[dimension2];
}
return jaggedArray;
}
public static T[] To1dArray<T>(T[][] jaggedArray)
{
List<T> result = new List<T>();
for (int z = 0; z < jaggedArray.Length; ++z)
{
for (int x = 0; x < jaggedArray[z].Length; ++x)
{
result.Add(jaggedArray[z][x]);
}
}
return result.ToArray();
}
public static T[] To1dArray<T>(T[,] grid)
{
int height = grid.GetLength(0);
int width = grid.GetLength(1);
T[] result = new T[height * width];
for (int z = 0; z < height; ++z)
{
for (int x = 0; x < width; ++x)
{
result[To1DIndex(x, z, width)] = grid[z, x];
}
}
return result;
}
public static void Fill<T>(T[] array, T value)
{
for (int i = 0; i < array.Length; ++i)
{
array[i] = value;
}
}
public static void CopyTo<T>(T[] src, T[] des)
{
int limit = Mathf.Min(src.Length, des.Length);
for (int i = 0; i < limit; ++i)
{
des[i] = src[i];
}
}
public static int Sum(int[,] array)
{
int sum = 0;
int length = array.GetLength(0);
int width = array.GetLength(1);
for (int z = 0; z < length; ++z)
{
for (int x = 0; x < width; ++x)
{
sum += array[z, x];
}
}
return sum;
}
public static int To1DIndex(int x, int z, int width)
{
return z * width + x;
}
public static bool IsInRange(float number, float minValue, float maxValue)
{
return number >= minValue && number <= maxValue;
}
public static bool IsInRangeExclusive(float number, float minValue, float maxValue)
{
return number > minValue && number < maxValue;
}
public static float GetFraction(float value, float floor, float ceil)
{
return (value - floor) / (ceil - floor);
}
public static void ClearChildren(Transform t)
{
int childCount = t.childCount;
for (int i = childCount - 1; i >= 0; --i)
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying)
{
GameObject.DestroyImmediate(t.GetChild(i).gameObject);
}
else
{
GameObject.Destroy(t.GetChild(i).gameObject);
}
#else
GameObject.Destroy(t.GetChild(i).gameObject);
#endif
}
}
public static Gradient CreateFullWhiteGradient()
{
Gradient g = new Gradient();
GradientColorKey color = new GradientColorKey(Color.white, 1);
GradientAlphaKey alpha = new GradientAlphaKey(1, 1);
g.SetKeys(new GradientColorKey[] { color }, new GradientAlphaKey[] { alpha });
return g;
}
public static Gradient CreateFullTransparentGradient()
{
Gradient g = new Gradient();
GradientColorKey color = new GradientColorKey(Color.white, 1);
GradientAlphaKey alpha = new GradientAlphaKey(0, 1);
g.SetKeys(new GradientColorKey[] { color }, new GradientAlphaKey[] { alpha });
return g;
}
public static void CalculateBarycentricCoord(Vector2 p, Vector2 p1, Vector2 p2, Vector2 p3, ref Vector3 bary)
{
Vector2 v0 = p2 - p1;
Vector2 v1 = p3 - p1;
Vector2 v2 = p - p1;
float d00 = Vector2.Dot(v0, v0);
float d01 = Vector2.Dot(v0, v1);
float d11 = Vector2.Dot(v1, v1);
float d20 = Vector2.Dot(v2, v0);
float d21 = Vector2.Dot(v2, v1);
float inverseDenom = 1 / (d00 * d11 - d01 * d01);
bary.y = (d11 * d20 - d01 * d21) * inverseDenom;
bary.z = (d00 * d21 - d01 * d20) * inverseDenom;
bary.x = 1.0f - bary.y - bary.z;
}
public static void ExpandTrisUvCoord(Texture2D tex, Vector2[] trisUv)
{
Vector2 texelSize = tex.texelSize;
Vector2 center = (trisUv[0] + trisUv[1] + trisUv[2]) / 3;
trisUv[0] += (trisUv[0] - center).normalized * texelSize.magnitude;
trisUv[0].x = Mathf.Clamp01(trisUv[0].x);
trisUv[0].y = Mathf.Clamp01(trisUv[0].y);
trisUv[1] += (trisUv[1] - center).normalized * texelSize.magnitude;
trisUv[1].x = Mathf.Clamp01(trisUv[1].x);
trisUv[1].y = Mathf.Clamp01(trisUv[1].y);
trisUv[2] += (trisUv[2] - center).normalized * texelSize.magnitude;
trisUv[2].x = Mathf.Clamp01(trisUv[2].x);
trisUv[2].y = Mathf.Clamp01(trisUv[2].y);
}
public static bool ContainIdenticalElements<T>(T[] arr1, T[] arr2)
{
if (arr1 == null && arr2 == null)
return true;
if (arr1 == null && arr2 != null)
return false;
if (arr1 != null && arr2 == null)
return false;
if (arr1.Length != arr2.Length)
return false;
for (int i = 0; i < arr1.Length; ++i)
{
if (!arr1[i].Equals(arr2[i]))
return false;
}
return true;
}
public static float GetNearestMultiple(float number, float multipleOf)
{
int multiplier = 0;
while (multipleOf * multiplier < number)
{
multiplier += 1;
}
float floor = multipleOf * (multiplier - 1);
float ceil = multipleOf * multiplier;
float f0 = number - floor;
float f1 = ceil - number;
if (f0 < f1)
return floor;
else
return ceil;
}
public static Transform GetChildrenWithName(Transform parent, string name)
{
Transform t = parent.Find(name);
if (t == null)
{
GameObject g = new GameObject(name);
g.transform.parent = parent;
ResetTransform(g.transform, parent);
t = g.transform;
}
return t;
}
public static void ResetTransform(Transform t, Transform parent)
{
t.parent = parent;
t.localPosition = Vector3.zero;
t.localRotation = Quaternion.identity;
t.localScale = Vector3.one;
}
public static void DestroyGameobject(GameObject g)
{
#if UNITY_EDITOR
if (UnityEditor.EditorApplication.isPlaying)
GameObject.Destroy(g);
else
GameObject.DestroyImmediate(g);
#else
GameObject.Destroy(g);
#endif
}
public static void DestroyGameObjectWithUndo(GameObject g)
{
#if UNITY_EDITOR
Undo.DestroyObjectImmediate(g);
#else
DestroyGameobject(g);
#endif
}
public static void DestroyObject(Object o)
{
#if UNITY_EDITOR
if (UnityEditor.EditorApplication.isPlaying)
Object.Destroy(o);
else
Object.DestroyImmediate(o, true);
#else
GameObject.Destroy(o);
#endif
}
public static string Repeat(char src, int count)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(src, count);
return sb.ToString();
}
public static void MarkCurrentSceneDirty()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying)
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
#endif
}
public static GameObject[] GetChildrenGameObjects(Transform parent)
{
GameObject[] children = new GameObject[parent.childCount];
for (int i = 0; i < parent.childCount; ++i)
{
children[i] = parent.GetChild(i).gameObject;
}
return children;
}
public static Transform[] GetChildrenTransforms(Transform parent)
{
Transform[] children = new Transform[parent.childCount];
for (int i = 0; i < parent.childCount; ++i)
{
children[i] = parent.GetChild(i);
}
return children;
}
/// <summary>
/// https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
/// </summary>
/// <param name="vector"></param>
/// <param name="normal"></param>
/// <param name="angleDegree"></param>
/// <returns></returns>
public static Vector3 RotateVectorAroundNormal(Vector3 vector, Vector3 normal, float angleDegree)
{
float sin = Mathf.Sin(angleDegree * Mathf.Deg2Rad);
float cos = Mathf.Cos(angleDegree * Mathf.Deg2Rad);
Vector3 rotatedVector =
vector * cos +
Vector3.Cross(normal, vector) * sin +
normal * Vector3.Dot(normal, vector) * (1 - cos);
return rotatedVector;
}
public static Mesh GetPrimitiveMesh(PrimitiveType type)
{
GameObject g = GameObject.CreatePrimitive(type);
Mesh m = g.GetComponent<MeshFilter>().sharedMesh;
DestroyGameobject(g);
return m;
}
public static void ShuffleList<T>(List<T> list)
{
int length = list.Count;
for (int i = 0; i < length - 1; ++i)
{
int j = UnityEngine.Random.Range(0, length);
T tmp = list[i];
list[i] = list[j];
list[j] = tmp;
}
}
public static int[] GetShuffleIndicesArray(int length)
{
int[] indices = GetIndicesArray(length);
for (int i = 0; i < length - 1; ++i)
{
int j = UnityEngine.Random.Range(0, length);
int tmp = indices[i];
indices[i] = indices[j];
indices[j] = tmp;
}
return indices;
}
public static int[] GetIndicesArray(int length)
{
int[] indices = new int[length];
for (int i = 0; i < length; ++i)
{
indices[i] = i;
}
return indices;
}
public static void ResetArray<T>(ref T[] array, int count, T defaultValue)
{
if (array != null && array.Length == count)
{
PUtilities.Fill(array, defaultValue);
}
else
{
array = new T[count];
}
}
public static bool EnsureArrayLength<T>(ref T[] array, int count)
{
if (array == null || array.Length != count)
{
array = new T[count];
return false;
}
return true;
}
public static float GetValueBilinear(float[] data, int width, int height, Vector2 uv)
{
float value = 0;
Vector2 pixelCoord = new Vector2(
Mathf.Lerp(0, width - 1, uv.x),
Mathf.Lerp(0, height - 1, uv.y));
//apply a bilinear filter
int xFloor = Mathf.FloorToInt(pixelCoord.x);
int xCeil = Mathf.CeilToInt(pixelCoord.x);
int yFloor = Mathf.FloorToInt(pixelCoord.y);
int yCeil = Mathf.CeilToInt(pixelCoord.y);
float f00 = data[PUtilities.To1DIndex(xFloor, yFloor, width)];
float f01 = data[PUtilities.To1DIndex(xFloor, yCeil, width)];
float f10 = data[PUtilities.To1DIndex(xCeil, yFloor, width)];
float f11 = data[PUtilities.To1DIndex(xCeil, yCeil, width)];
Vector2 unitCoord = new Vector2(
pixelCoord.x - xFloor,
pixelCoord.y - yFloor);
value =
f00 * (1 - unitCoord.x) * (1 - unitCoord.y) +
f01 * (1 - unitCoord.x) * unitCoord.y +
f10 * unitCoord.x * (1 - unitCoord.y) +
f11 * unitCoord.x * unitCoord.y;
return value;
}
public static Color GetColorBilinear(Color[] textureData, int width, int height, Vector2 uv)
{
Color color = Color.clear;
Vector2 pixelCoord = new Vector2(
Mathf.Lerp(0, width - 1, uv.x),
Mathf.Lerp(0, height - 1, uv.y));
//apply a bilinear filter
int xFloor = Mathf.FloorToInt(pixelCoord.x);
int xCeil = Mathf.CeilToInt(pixelCoord.x);
int yFloor = Mathf.FloorToInt(pixelCoord.y);
int yCeil = Mathf.CeilToInt(pixelCoord.y);
Color f00 = textureData[PUtilities.To1DIndex(xFloor, yFloor, width)];
Color f01 = textureData[PUtilities.To1DIndex(xFloor, yCeil, width)];
Color f10 = textureData[PUtilities.To1DIndex(xCeil, yFloor, width)];
Color f11 = textureData[PUtilities.To1DIndex(xCeil, yCeil, width)];
Vector2 unitCoord = new Vector2(
pixelCoord.x - xFloor,
pixelCoord.y - yFloor);
color =
f00 * (1 - unitCoord.x) * (1 - unitCoord.y) +
f01 * (1 - unitCoord.x) * unitCoord.y +
f10 * unitCoord.x * (1 - unitCoord.y) +
f11 * unitCoord.x * unitCoord.y;
return color;
}
public static GameObject CreatePreviewGameObject(Mesh m, Material mat, Vector3 position)
{
GameObject g = new GameObject("GO");
g.transform.position = position;
g.transform.rotation = Quaternion.identity;
g.transform.localScale = Vector3.one;
MeshFilter mf = g.AddComponent<MeshFilter>();
mf.sharedMesh = m;
MeshRenderer mr = g.AddComponent<MeshRenderer>();
mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
mr.receiveShadows = false;
mr.sharedMaterial = mat;
return g;
}
public static Camera CreatePreviewCamera(GameObject target, float distance, float padding)
{
GameObject g = new GameObject("CAM");
g.transform.rotation = Quaternion.identity;
g.transform.localScale = Vector3.one;
Camera cam = g.AddComponent<Camera>();
cam.orthographic = true;
cam.clearFlags = CameraClearFlags.Nothing;
cam.aspect = 1;
MeshRenderer mr = target.GetComponent<MeshRenderer>();
Bounds bounds = mr.bounds;
cam.transform.position = bounds.center + new Vector3(-1, 0.5f, -1) * distance;
cam.transform.LookAt(bounds.center);
cam.orthographicSize = Mathf.Max(bounds.size.x, bounds.size.y, bounds.size.z) / 2 + padding;
return cam;
}
public static void EnsureDirectoryExists(string dir)
{
if (!System.IO.Directory.Exists(dir))
{
System.IO.Directory.CreateDirectory(dir);
}
}
public static void SetStaticRecursively(GameObject g, bool isStatic)
{
#if UNITY_EDITOR
g.isStatic = isStatic;
GameObject[] children = GetChildrenGameObjects(g.transform);
for (int i = 0; i < children.Length; ++i)
{
SetStaticRecursively(children[i], isStatic);
}
#endif
}
public static void EnsureLengthSufficient<T>(List<T> list, int preferredLength) where T : Object
{
if (list == null)
list = new List<T>();
while (list.Count < preferredLength)
{
list.Add(null);
}
}
public static void EnsureLengthSufficient(List<bool> list, int preferredLength)
{
if (list == null)
list = new List<bool>();
while (list.Count < preferredLength)
{
list.Add(false);
}
}
public static string Ellipsis(string s, int length)
{
if (s.Length < length)
return s;
string s0 = s.Substring(0, length);
return s0 + "...";
}
public static bool IsRectContainPointExclusive(Rect r, Vector2 p)
{
return
p.x > r.min.x &&
p.x < r.max.x &&
p.y > r.min.y &&
p.y < r.max.y;
}
public static Color GetColor(Color baseColor, float alpha)
{
return new Color(baseColor.r, baseColor.g, baseColor.b, alpha);
}
public static Rect GetRectContainsPoints(params Vector2[] points)
{
float xMin = float.MaxValue;
float xMax = float.MinValue;
float yMin = float.MaxValue;
float yMax = float.MinValue;
for (int i = 0; i < points.Length; ++i)
{
xMin = points[i].x < xMin ? points[i].x : xMin;
xMax = points[i].x > xMax ? points[i].x : xMax;
yMin = points[i].y < yMin ? points[i].y : yMin;
yMax = points[i].y > yMax ? points[i].y : yMax;
}
return Rect.MinMaxRect(xMin, yMin, xMax, yMax);
}
public static float InverseLerpUnclamped(float a, float b, float value)
{
if (a != b)
{
return (value - a) / (b - a);
}
return 0f;
}
public static Vector2 PointToNormalizedUnclampled(Rect r, Vector2 point)
{
return new Vector2(InverseLerpUnclamped(r.x, r.xMax, point.x), InverseLerpUnclamped(r.y, r.yMax, point.y));
}
public static Rect GetUvRect(Vector2 v0, Vector2 v1, Vector2 v2)
{
return Rect.MinMaxRect(
Mathf.Min(v0.x, v1.x, v2.x),
Mathf.Min(v0.y, v1.y, v2.y),
Mathf.Max(v0.x, v1.x, v2.x),
Mathf.Max(v0.y, v1.y, v2.y));
}
public static Gradient Clone(Gradient src)
{
if (src == null)
return null;
Gradient des = new Gradient();
des.SetKeys(src.colorKeys, src.alphaKeys);
return des;
}
public static AnimationCurve Clone(AnimationCurve src)
{
if (src == null)
return null;
AnimationCurve des = new AnimationCurve();
Keyframe[] keys = src.keys;
for (int i = 0; i < keys.Length; ++i)
{
des.AddKey(keys[i]);
}
des.preWrapMode = src.preWrapMode;
des.postWrapMode = src.postWrapMode;
return des;
}
public static bool IsPointInsideQuadXZ(Vector3 point, Vector3[] quad)
{
Vector3 bary = Vector3.zero;
CalculateBarycentricCoord(
new Vector2(point.x, point.z),
new Vector2(quad[0].x, quad[0].z),
new Vector2(quad[1].x, quad[1].z),
new Vector2(quad[2].x, quad[2].z),
ref bary);
if (bary.x >= 0 && bary.y >= 0 && bary.z >= 0)
return true;
CalculateBarycentricCoord(
new Vector2(point.x, point.z),
new Vector2(quad[0].x, quad[0].z),
new Vector2(quad[2].x, quad[2].z),
new Vector2(quad[3].x, quad[3].z),
ref bary);
if (bary.x >= 0 && bary.y >= 0 && bary.z >= 0)
return true;
return false;
}
public static void DestroyMeshArray(Mesh[] meshes)
{
for (int i = 0; i < meshes.Length; ++i)
{
if (meshes[i] != null)
{
Object.DestroyImmediate(meshes[i], true);
}
}
}
public static Vector2 FlipY(Vector2 v)
{
return new Vector2(v.x, 1 - v.y);
}
/// <summary>
/// https://en.wikipedia.org/wiki/Delaunay_triangulation#Algorithms
/// </summary>
/// <param name="v0"></param>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <param name="p"></param>
/// <returns></returns>
public static bool IsPointInCircumcircle(Vector2 v0, Vector2 v1, Vector2 v2, Vector2 p)
{
Matrix4x4 mat = new Matrix4x4();
mat.SetRow(0, new Vector4(v0.x, v0.y, v0.x * v0.x + v0.y * v0.y, 1));
mat.SetRow(1, new Vector4(v2.x, v2.y, v2.x * v2.x + v2.y * v2.y, 1)); //a,b,c counterclockwise
mat.SetRow(2, new Vector4(v1.x, v1.y, v1.x * v1.x + v1.y * v1.y, 1));
mat.SetRow(3, new Vector4(p.x, p.y, p.x * p.x + p.y * p.y, 1));
return mat.determinant > 0;
}
public static bool IsPointInCircumcircleXZ(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 p)
{
Matrix4x4 mat = new Matrix4x4();
mat.SetRow(0, new Vector4(v0.x, v0.z, v0.x * v0.x + v0.z * v0.z, 1));
mat.SetRow(1, new Vector4(v2.x, v2.z, v2.x * v2.x + v2.z * v2.z, 1)); //a,b,c counterclockwise
mat.SetRow(2, new Vector4(v1.x, v1.z, v1.x * v1.x + v1.z * v1.z, 1));
mat.SetRow(3, new Vector4(p.x, p.z, p.x * p.x + p.z * p.z, 1));
return mat.determinant > 0;
}
public static bool AreSetEqual(ushort[] setA, ushort[] setB)
{
HashSet<ushort> a = new HashSet<ushort>(setA);
HashSet<ushort> b = new HashSet<ushort>(setB);
return a.SetEquals(b);
}
public static T GetOrAddComponent<T>(GameObject g) where T : Component
{
T comp = g.GetComponent<T>();
if (comp == null)
{
comp = g.AddComponent<T>();
}
return comp;
}
public static void Distinct<T>(this List<T> list)
{
list.Distinct();
}
public static void AddIfNotContains<T>(this IList<T> list, IEnumerable<T> items)
{
IEnumerator<T> iter = items.GetEnumerator();
while (iter.MoveNext())
{
T current = iter.Current;
if (!list.Contains(current))
{
list.Add(current);
}
}
}
public static void AddIfNotContains<T>(this IList<T> list, T item)
{
if (!list.Contains(item))
{
list.Add(item);
}
}
public static void DoubleMeshBounds(Mesh m)
{
Bounds b = m.bounds;
b.Expand(2);
m.bounds = b;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b0fc59c1c3b1c142af7d8c71d61f3ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Poseidon
{
/// <summary>
/// Utility class contains product info
/// </summary>
public static class PVersionInfo
{
public static float Number
{
get
{
return 175;
}
}
public static string Code
{
get
{
return "1.7.5";
}
}
public static string ProductName
{
get
{
return "Poseidon - Low Poly Water System";
}
}
public static string ProductNameAndVersion
{
get
{
return string.Format("{0} v{1}", ProductName, Code);
}
}
public static string ProductNameShort
{
get
{
return "Poseidon";
}
}
public static string ProductNameAndVersionShort
{
get
{
return string.Format("{0} v{1}", ProductNameShort, Code);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 800c99e85ae6abb408449d888bae7b5c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: