282 lines
7.7 KiB
C#
282 lines
7.7 KiB
C#
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<Camera>();
|
|
}
|
|
|
|
private void Clear()
|
|
{
|
|
_camera.ResetProjectionMatrix();
|
|
activeSample = Vector4.zero;
|
|
activeIndex = -2;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
Reset();
|
|
Clear();
|
|
}
|
|
|
|
private void OnPreCull()
|
|
{
|
|
if (_camera == null)
|
|
{
|
|
_camera = GetComponent<Camera>();
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
}
|