using System; using UnityEngine; namespace Artngame.SKYMASTER { [ExecuteInEditMode] [RequireComponent(typeof(Camera))] public class FrustumJitter : MonoBehaviour { public enum Pattern { Still = 0, Uniform2 = 1, Uniform4 = 2, Uniform4_Helix = 3, Uniform4_DoubleHelix = 4, SkewButterfly = 5, Rotated4 = 6, Rotated4_Helix = 7, Rotated4_Helix2 = 8, Poisson10 = 9, Pentagram = 10, Halton_2_3_X8 = 11, Halton_2_3_X16 = 12, Halton_2_3_X32 = 13, Halton_2_3_X256 = 14, MotionPerp2 = 15 } private static float[] points_Still; private static float[] points_Uniform2; private static float[] points_Uniform4; private static float[] points_Uniform4_Helix; private static float[] points_Uniform4_DoubleHelix; private static float[] points_SkewButterfly; private static float[] points_Rotated4; private static float[] points_Rotated4_Helix; private static float[] points_Rotated4_Helix2; private static float[] points_Poisson10; private static float[] points_Pentagram; private static float[] points_Halton_2_3_x8; private static float[] points_Halton_2_3_x16; private static float[] points_Halton_2_3_x32; private static float[] points_Halton_2_3_x256; private static float[] points_MotionPerp2; private Camera _camera; private Vector3 focalMotionPos = Vector3.zero; private Vector3 focalMotionDir = Vector3.right; public Pattern pattern = Pattern.Halton_2_3_X16; public float patternScale = 0.1f; public Vector4 activeSample = Vector4.zero; public int activeIndex = -2; private static void TransformPattern(float[] seq, float theta, float scale) { float num = Mathf.Cos(theta); float num2 = Mathf.Sin(theta); int num3 = 0; int num4 = 1; int num5 = seq.Length; while (num3 != num5) { float num6 = scale * seq[num3]; float num7 = scale * seq[num4]; seq[num3] = num6 * num - num7 * num2; seq[num4] = num6 * num2 + num7 * num; num3 += 2; num4 += 2; } } private static float HaltonSeq(int prime, int index = 1) { float num = 0f; float num2 = 1f; for (int num3 = index; num3 > 0; num3 = (int)Mathf.Floor((float)num3 / (float)prime)) { num2 /= (float)prime; num += num2 * (float)(num3 % prime); } return num; } private static void InitializeHalton_2_3(float[] seq) { int i = 0; for (int num = seq.Length / 2; i != num; i++) { float num2 = HaltonSeq(2, i + 1) - 0.5f; float num3 = HaltonSeq(3, i + 1) - 0.5f; seq[2 * i] = num2; seq[2 * i + 1] = num3; } } static FrustumJitter() { points_Still = new float[2] { 0.5f, 0.5f }; points_Uniform2 = new float[4] { -0.25f, -0.25f, 0.25f, 0.25f }; points_Uniform4 = new float[8] { -0.25f, -0.25f, 0.25f, -0.25f, 0.25f, 0.25f, -0.25f, 0.25f }; points_Uniform4_Helix = new float[8] { -0.25f, -0.25f, 0.25f, 0.25f, 0.25f, -0.25f, -0.25f, 0.25f }; points_Uniform4_DoubleHelix = new float[16] { -0.25f, -0.25f, 0.25f, 0.25f, 0.25f, -0.25f, -0.25f, 0.25f, -0.25f, -0.25f, 0.25f, -0.25f, -0.25f, 0.25f, 0.25f, 0.25f }; points_SkewButterfly = new float[8] { -0.25f, -0.25f, 0.25f, 0.25f, 0.125f, -0.125f, -0.125f, 0.125f }; points_Rotated4 = new float[8] { -0.125f, -0.375f, 0.375f, -0.125f, 0.125f, 0.375f, -0.375f, 0.125f }; points_Rotated4_Helix = new float[8] { -0.125f, -0.375f, 0.125f, 0.375f, 0.375f, -0.125f, -0.375f, 0.125f }; points_Rotated4_Helix2 = new float[8] { -0.125f, -0.375f, 0.125f, 0.375f, -0.375f, 0.125f, 0.375f, -0.125f }; points_Poisson10 = new float[20] { -0.0419899f, 0.16386227f, -0.17274007f, 0.14753993f, 0.12460955f, 0.2077493f, 0.043075375f, -0.009706758f, -0.15193167f, -0.015033968f, 0.16401598f, 0.060019f, 0.20087093f, -0.12024225f, 0.08359135f, -0.18251757f, -0.1195988f, -0.14001325f, -0.0309703f, -0.24158497f }; points_Pentagram = new float[10] { 0f, 0.2628655f, -0.1545085f, -0.2126625f, 0.25f, 0.08123f, -0.25f, 0.08123f, 0.1545085f, -0.2126625f }; points_Halton_2_3_x8 = new float[16]; points_Halton_2_3_x16 = new float[32]; points_Halton_2_3_x32 = new float[64]; points_Halton_2_3_x256 = new float[512]; points_MotionPerp2 = new float[4] { 0f, -0.25f, 0f, 0.25f }; TransformPattern(theta: MathF.PI / 180f * (0.5f * Vector2.Angle(to: new Vector2(points_Pentagram[0] - points_Pentagram[2], points_Pentagram[1] - points_Pentagram[3]), from: new Vector2(0f, 1f))), seq: points_Pentagram, scale: 1f); InitializeHalton_2_3(points_Halton_2_3_x8); InitializeHalton_2_3(points_Halton_2_3_x16); InitializeHalton_2_3(points_Halton_2_3_x32); InitializeHalton_2_3(points_Halton_2_3_x256); } private static float[] AccessPointData(Pattern pattern) { switch (pattern) { case Pattern.Still: return points_Still; case Pattern.Uniform2: return points_Uniform2; case Pattern.Uniform4: return points_Uniform4; case Pattern.Uniform4_Helix: return points_Uniform4_Helix; case Pattern.Uniform4_DoubleHelix: return points_Uniform4_DoubleHelix; case Pattern.SkewButterfly: return points_SkewButterfly; case Pattern.Rotated4: return points_Rotated4; case Pattern.Rotated4_Helix: return points_Rotated4_Helix; case Pattern.Rotated4_Helix2: return points_Rotated4_Helix2; case Pattern.Poisson10: return points_Poisson10; case Pattern.Pentagram: return points_Pentagram; case Pattern.Halton_2_3_X8: return points_Halton_2_3_x8; case Pattern.Halton_2_3_X16: return points_Halton_2_3_x16; case Pattern.Halton_2_3_X32: return points_Halton_2_3_x32; case Pattern.Halton_2_3_X256: return points_Halton_2_3_x256; case Pattern.MotionPerp2: return points_MotionPerp2; default: Debug.LogError("missing point distribution"); return points_Halton_2_3_x16; } } public static int AccessLength(Pattern pattern) { return AccessPointData(pattern).Length / 2; } public Vector2 Sample(Pattern pattern, int index) { float[] array = AccessPointData(pattern); int num = array.Length / 2; int num2 = index % num; float x = patternScale * array[2 * num2]; float y = patternScale * array[2 * num2 + 1]; if (pattern != Pattern.MotionPerp2) { return new Vector2(x, y); } return new Vector2(x, y).Rotate(Vector2.right.SignedAngle(focalMotionDir)); } private void Reset() { _camera = GetComponent(); } private void Clear() { _camera.ResetProjectionMatrix(); activeSample = Vector4.zero; activeIndex = -2; } private void Awake() { Reset(); Clear(); } private void OnPreCull() { if (_camera == null) { _camera = GetComponent(); } if (!Application.isPlaying) { return; } Vector3 vector = focalMotionPos; Vector3 vector2 = _camera.transform.TransformVector(_camera.nearClipPlane * Vector3.forward); Vector3 vector3 = _camera.worldToCameraMatrix * vector; Vector3 vector4 = ((Vector3)(_camera.worldToCameraMatrix * vector2) - vector3).WithZ(0f); float magnitude = vector4.magnitude; if (magnitude != 0f) { Vector3 b = vector4 / magnitude; if (b.sqrMagnitude != 0f) { focalMotionPos = vector2; focalMotionDir = Vector3.Slerp(focalMotionDir, b, 0.2f); } } if (_camera.stereoEnabled) { Clear(); return; } if (activeIndex == -2) { activeSample = Vector4.zero; activeIndex++; _camera.projectionMatrix = _camera.GetProjectionMatrix(); return; } activeIndex++; activeIndex %= AccessLength(pattern); Vector2 vector5 = Sample(pattern, activeIndex); activeSample.z = activeSample.x; activeSample.w = activeSample.y; activeSample.x = vector5.x; activeSample.y = vector5.y; _camera.projectionMatrix = _camera.GetProjectionMatrix(vector5.x, vector5.y); } private void OnDisable() { Clear(); } } }