private void CleanUp() { foreach (RenderTexture rt in ReflRenderTextures.Values) { if (rt == null) { continue; } rt.Release(); PUtilities.DestroyObject(rt); } foreach (Camera cam in ReflCameras.Values) { if (cam == null) { continue; } PUtilities.DestroyGameobject(cam.gameObject); } if (mesh != null) { PUtilities.DestroyObject(mesh); } if (spline != null) { spline.Dispose(); } }
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 void FillTexture(Texture2D t, Color c) { Color[] colors = new Color[t.width * t.height]; PUtilities.Fill(colors, c); t.SetPixels(colors); t.Apply(); }
public void Dispose() { if (mesh != null) { PUtilities.DestroyObject(mesh); } }
private void Update() { if (Water == null) { PUtilities.DestroyGameobject(gameObject); } }
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 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); }
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); }
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 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 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 ResetArray <T>(ref T[] array, int count, T defaultValue) { if (array != null && array.Length == count) { PUtilities.Fill(array, defaultValue); } else { array = new T[count]; } }
private void Update() { for (int i = 0; i < ObsoletedGameObject.Count; ++i) { GameObject o = ObsoletedGameObject[i]; if (o != null) { PUtilities.DestroyGameobject(o); } } ObsoletedGameObject.Clear(); SetUpSelfLayer(); SetUpDummyComponents(); if (MeshType == PWaterMeshType.TileablePlane && TilesFollowMainCamera && Camera.main != null) { SnapPosition(Camera.main.transform.position); } }
private RenderTexture GetReflectionRt(Camera cam) { if (!ReflRenderTextures.ContainsKey(cam)) { ReflRenderTextures.Add(cam, null); } int resolution = 128; if (Profile != null) { resolution = Profile.ReflectionTextureResolution; } RenderTexture rt = ReflRenderTextures[cam]; if (rt == null) { rt = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32); } if (rt.width != resolution || rt.height != resolution) { Camera reflCam; if (ReflCameras.TryGetValue(cam, out reflCam)) { reflCam.targetTexture = null; } rt.Release(); PUtilities.DestroyObject(rt); rt = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32); } rt.name = string.Format("~ReflectionRt_{0}_{1}", cam.name, resolution); ReflRenderTextures[cam] = rt; if (cam.stereoEnabled) { rt.Release(); } return(rt); }
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); }
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 HandleAddRemoveTiles() { Plane plane = new Plane(Vector3.up, water.transform.position); Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); float distance = -1; if (plane.Raycast(r, out distance)) { Vector3 hitWorldPos = r.origin + r.direction * distance; Vector3 hitLocalPos = water.transform.InverseTransformPoint(hitWorldPos); PIndex2D index = new PIndex2D( Mathf.FloorToInt(hitLocalPos.x / water.TileSize.x), Mathf.FloorToInt(hitLocalPos.z / water.TileSize.y)); Vector3 rectCenter = water.transform.TransformPoint(new Vector3( (index.X + 0.5f) * water.TileSize.x, hitLocalPos.y, (index.Z + 0.5f) * water.TileSize.y)); Vector3 rectSize = water.transform.TransformVector(new Vector3( water.TileSize.x, 0, water.TileSize.y)); if (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.MouseUp) { if (Event.current.button != 0) { return; } if (Event.current.control) { water.TileIndices.Remove(index); water.ReCalculateBounds(); } else if (Event.current.shift) { if (!water.TileIndices.Contains(index)) { water.TileIndices.Add(index); water.ReCalculateBounds(); } } PUtilities.MarkCurrentSceneDirty(); EditorUtility.SetDirty(water); } Handles.color = Handles.selectedColor; Handles.DrawWireCube(rectCenter, rectSize); string s = string.Format( "{0}" + "{1}" + "{2}", index.ToString(), "\nShift+Click to pin, Ctrl+Click to unpin water planes.", "\nClick End Editing Tiles when done."); GUIContent mouseMessage = new GUIContent(s); PEditorCommon.SceneViewMouseMessage(mouseMessage); } }
private void RenderReflectionTexture(Camera cam) { if (MeshType == PWaterMeshType.Spline) { return; } bool isBackface = cam.transform.position.y < transform.position.y; if (isBackface) { return; } if (cam.stereoEnabled) { return; } //prepare reflection camera if (!ReflCameras.ContainsKey(cam)) { ReflCameras.Add(cam, null); } if (ReflCameras[cam] == null) { GameObject g = new GameObject(); g.name = "~ReflectionCamera_" + cam.name; g.hideFlags = HideFlags.HideAndDontSave; Camera rCam = g.AddComponent <Camera>(); rCam.enabled = false; g.AddComponent <Skybox>(); g.AddComponent <FlareLayer>(); PUtilities.ResetTransform(g.transform, transform); ReflCameras[cam] = rCam; } //define reflection plane by position & normal in world space Vector3 planePos = transform.position; Vector3 planeNormal = Vector3.up; //disable pixel light if needed int oldPixelLightCount = QualitySettings.pixelLightCount; if (!Profile.EnableReflectionPixelLight) { QualitySettings.pixelLightCount = 0; } //set up camera and render Camera reflectionCamera = ReflCameras[cam]; reflectionCamera.enabled = false; reflectionCamera.targetTexture = GetReflectionRt(cam); MatchCameraSettings(cam, reflectionCamera); // Reflect camera around reflection plane float d = -Vector3.Dot(planeNormal, planePos) - Profile.ReflectionClipPlaneOffset; Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d); Matrix4x4 reflection = CalculateReflectionMatrix(reflectionPlane); Vector3 oldpos = cam.transform.position; Vector3 newpos = reflection.MultiplyPoint(oldpos); reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. bool isBackFace = cam.transform.position.y < transform.position.y; Vector4 clipPlane = CameraSpacePlane(reflectionCamera, planePos, planeNormal, Profile.ReflectionClipPlaneOffset, isBackFace ? -1.0f : 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & Profile.ReflectionLayers.value; // never render water layer //reflectionCamera.targetTexture = m_ReflectionTexture; bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.invertCulling = oldCulling; //restore pixel light if (!Profile.EnableReflectionPixelLight) { QualitySettings.pixelLightCount = oldPixelLightCount; } }
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()); }
private void RenderReflectionTextureSRP(ScriptableRenderContext context, Camera cam) { if (MeshType == PWaterMeshType.Spline) { return; } bool isBackface = cam.transform.position.y < transform.position.y; if (isBackface) { return; } if (cam.stereoEnabled) { return; } //prepare reflection camera if (!ReflCameras.ContainsKey(cam)) { ReflCameras.Add(cam, null); } if (ReflCameras[cam] == null) { GameObject g = new GameObject(); g.name = "~ReflectionCamera_" + cam.name; //g.hideFlags = HideFlags.HideAndDontSave; Camera rCam = g.AddComponent <Camera>(); rCam.enabled = false; g.AddComponent <Skybox>(); g.AddComponent <FlareLayer>(); ////TODO: Remove on release //if (cam.cameraType == CameraType.Game) //{ // PCameraFrustumVisualizer vis = g.AddComponent<PCameraFrustumVisualizer>(); ; // vis.drawGizmos = true; // vis.leftEye = true; // vis.rightEye = true; // vis.monoEye = true; // vis.alpha = 0.2f; // vis.cam = rCam; //} PUtilities.ResetTransform(g.transform, transform); ReflCameras[cam] = rCam; } //define reflection plane by position & normal in world space Vector3 planePos = transform.position; Vector3 planeNormal = transform.up; int lastPixelLightCount = QualitySettings.pixelLightCount; if (!Profile.EnableReflectionPixelLight) { QualitySettings.pixelLightCount = 0; } bool lastInvertCulling = GL.invertCulling; GL.invertCulling = !lastInvertCulling; //set up camera and render Camera reflectionCamera = ReflCameras[cam]; reflectionCamera.enabled = false; reflectionCamera.targetTexture = GetReflectionRt(cam); MatchCameraSettings(cam, reflectionCamera); // Reflect camera around reflection plane float d = -Vector3.Dot(planeNormal, planePos) - Profile.ReflectionClipPlaneOffset; Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d); Matrix4x4 reflection = CalculateReflectionMatrix(reflectionPlane, Camera.MonoOrStereoscopicEye.Mono); Vector3 oldpos = cam.transform.position; Vector3 newpos = reflection.MultiplyPoint(oldpos); reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. bool isBackFace = cam.transform.position.y < transform.position.y; Vector4 clipPlane = CameraSpacePlane(reflectionCamera, planePos, planeNormal, Profile.ReflectionClipPlaneOffset, isBackFace && ShouldRenderBackface ? -1.0f : 1.0f); Matrix4x4 obliqueMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.projectionMatrix = obliqueMatrix; // Set custom culling matrix from the current camera reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & Profile.ReflectionLayers.value; // never render water layer reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera); QualitySettings.pixelLightCount = lastPixelLightCount; GL.invertCulling = lastInvertCulling; }
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); }