(client) feat:实现摄像机跟踪与移动,实现任意位置生成实体,实现更安全的资源加载方式(指定unity内部加载资源) (#42)
Co-authored-by: zzdxxz <2079238449@qq.com> Co-committed-by: zzdxxz <2079238449@qq.com>
This commit is contained in:
@ -2,14 +2,19 @@ using System;
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
public class PerlinNoise
|
||||
public class PerlinNoise : Utils.Singleton<PerlinNoise>
|
||||
{
|
||||
private readonly int[] _p; // 混淆表
|
||||
private int[] _p; // 混淆表
|
||||
private const int DefaultSeed = 0; // 默认种子
|
||||
|
||||
// 构造函数:初始化混淆表
|
||||
public PerlinNoise(int seed)
|
||||
public PerlinNoise()
|
||||
{
|
||||
Initialize(DefaultSeed);
|
||||
}
|
||||
|
||||
// 初始化混淆表
|
||||
private void Initialize(int seed)
|
||||
{
|
||||
// 初始化为0-255的随机排列
|
||||
_p = new int[512]; // 混淆表加倍以方便使用
|
||||
var permutation = new int[256];
|
||||
var random = new Random(seed);
|
||||
@ -34,67 +39,67 @@ namespace Utils
|
||||
}
|
||||
}
|
||||
|
||||
// 重新指定种子
|
||||
public void Reinitialize(int seed)
|
||||
{
|
||||
Initialize(seed);
|
||||
}
|
||||
|
||||
// 平滑函数 (6t^5 - 15t^4 + 10t^3)
|
||||
private double Fade(double t)
|
||||
private static double Fade(double t)
|
||||
{
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
// 线性插值
|
||||
private double Lerp(double t, double a, double b)
|
||||
private static double Lerp(double t, double a, double b)
|
||||
{
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
// 计算梯度向量和距离向量的点积
|
||||
private double Grad(int hash, double x, double y, double z)
|
||||
private static double Grad(int hash, double x, double y, double z)
|
||||
{
|
||||
// 根据hash值确定使用哪个梯度向量
|
||||
// 12个梯度向量由以下组合构成:(+/-1, +/-1, 0), (+/-1, 0, +/-1), (0, +/-1, +/-1)
|
||||
switch (hash & 0xF) // 取hash值的最后4位
|
||||
return (hash & 0xF) switch // 取hash值的最后4位
|
||||
{
|
||||
case 0x0: return x + y;
|
||||
case 0x1: return -x + y;
|
||||
case 0x2: return x - y;
|
||||
case 0x3: return -x - y;
|
||||
case 0x4: return x + z;
|
||||
case 0x5: return -x + z;
|
||||
case 0x6: return x - z;
|
||||
case 0x7: return -x - z;
|
||||
case 0x8: return y + z;
|
||||
case 0x9: return -y + z;
|
||||
case 0xA: return y - z;
|
||||
case 0xB: return -y - z;
|
||||
case 0xC: return y + x; // 这四个是重复的,但Ken Perlin的原始实现中包含它们。
|
||||
case 0xD: return -y + x; // 它们对噪声质量影响不大,但保持了表格的一致性。
|
||||
case 0xE: return y - x;
|
||||
case 0xF: return -y - x;
|
||||
default: return 0; // 不应该发生
|
||||
}
|
||||
0x0 => x + y,
|
||||
0x1 => -x + y,
|
||||
0x2 => x - y,
|
||||
0x3 => -x - y,
|
||||
0x4 => x + z,
|
||||
0x5 => -x + z,
|
||||
0x6 => x - z,
|
||||
0x7 => -x - z,
|
||||
0x8 => y + z,
|
||||
0x9 => -y + z,
|
||||
0xA => y - z,
|
||||
0xB => -y - z,
|
||||
0xC => y + x,
|
||||
0xD => -y + x,
|
||||
0xE => y - x,
|
||||
0xF => -y - x,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为给定的(x, y, z)坐标生成3D Perlin噪声。
|
||||
/// 输出值通常在-1到1之间。
|
||||
/// </summary>
|
||||
public double Noise(double x, double y, double z)
|
||||
public double Noise(double x, double y=0, double z = 0)
|
||||
{
|
||||
// 找到包含该点的单位立方体
|
||||
var X = (int)Math.Floor(x) & 255;
|
||||
var Y = (int)Math.Floor(y) & 255;
|
||||
var Z = (int)Math.Floor(z) & 255;
|
||||
|
||||
// 找到该点在立方体内的相对x, y, z坐标
|
||||
x -= Math.Floor(x);
|
||||
y -= Math.Floor(y);
|
||||
z -= Math.Floor(z);
|
||||
|
||||
// 计算x, y, z的平滑曲线
|
||||
var u = Fade(x);
|
||||
var v = Fade(y);
|
||||
var w = Fade(z);
|
||||
|
||||
// 对立方体的8个角进行哈希计算
|
||||
var A = _p[X] + Y;
|
||||
var AA = _p[A] + Z;
|
||||
var AB = _p[A + 1] + Z;
|
||||
@ -102,7 +107,6 @@ namespace Utils
|
||||
var BA = _p[B] + Z;
|
||||
var BB = _p[B + 1] + Z;
|
||||
|
||||
// 获取所有8个角的哈希值
|
||||
var H000 = _p[AA];
|
||||
var H100 = _p[BA];
|
||||
var H010 = _p[AB];
|
||||
@ -112,19 +116,14 @@ namespace Utils
|
||||
var H011 = _p[AB + 1];
|
||||
var H111 = _p[BB + 1];
|
||||
|
||||
// 计算所有8个角的点积并插值
|
||||
double x0, x1, y0, y1;
|
||||
|
||||
x0 = Lerp(u, Grad(H000, x, y, z), // (0,0,0)
|
||||
Grad(H100, x - 1, y, z)); // (1,0,0)
|
||||
x1 = Lerp(u, Grad(H010, x, y - 1, z), // (0,1,0)
|
||||
Grad(H110, x - 1, y - 1, z)); // (1,1,0)
|
||||
x0 = Lerp(u, Grad(H000, x, y, z), Grad(H100, x - 1, y, z));
|
||||
x1 = Lerp(u, Grad(H010, x, y - 1, z), Grad(H110, x - 1, y - 1, z));
|
||||
y0 = Lerp(v, x0, x1);
|
||||
|
||||
x0 = Lerp(u, Grad(H001, x, y, z - 1), // (0,0,1)
|
||||
Grad(H101, x - 1, y, z - 1)); // (1,0,1)
|
||||
x1 = Lerp(u, Grad(H011, x, y - 1, z - 1), // (0,1,1)
|
||||
Grad(H111, x - 1, y - 1, z - 1)); // (1,1,1)
|
||||
x0 = Lerp(u, Grad(H001, x, y, z - 1), Grad(H101, x - 1, y, z - 1));
|
||||
x1 = Lerp(u, Grad(H011, x, y - 1, z - 1), Grad(H111, x - 1, y - 1, z - 1));
|
||||
y1 = Lerp(v, x0, x1);
|
||||
|
||||
return Lerp(w, y0, y1);
|
||||
|
Reference in New Issue
Block a user