伪随机数算法:https://editor.csdn.net/md/?articleId=103834623
实现:
namespace Game.Randoms
{
/// <summary>
/// 线性同余随机算法(LGC)
/// </summary>
public static class LGC {
/// <summary>
/// 随机序列
/// </summary>
private static int[] RandomSequence = null;
/// <summary>
/// 最大值
/// </summary>
private static int _maxNum = 1024;
public static int MaxNum { get { return _maxNum; } set { _maxNum = value; } }
/// <summary>
/// 种子
/// </summary>
private static int _seed = 12345;
public static int Seed { get { return _seed; } }
/// <summary>
/// 乘数
/// </summary>
private static int _multiplier = 9;
public static int Multiplier { get { return _multiplier; } }
/// <summary>
/// 增量
/// </summary>
private static int _increment = 7;
public static int Increment { get { return _increment; } }
/// <summary>
/// 设置种子
/// </summary>
/// <param name="seed"></param>
public static void SetSeed(int seed)
{
_seed = seed;
RandomSequence = new int[MaxNum];
RandomSequence[0] = seed;
for (int i = 1; i < MaxNum; i++)
{
RandomSequence[i] = (_multiplier * RandomSequence[i - 1] + _increment) % MaxNum;
}
}
public static float Random(float x)
{
InitRandomSequence();
int index = (int)(x % MaxNum);
return RandomSequence[index];
}
public static float Random01(float x)
{
return Random(x) / MaxNum;
}
public static float Random(float x, float y)
{
InitRandomSequence();
int xIndex = (int)(x % MaxNum);
int yIndex = (int)(y % MaxNum);
return (RandomSequence[xIndex] + RandomSequence[yIndex]) % MaxNum;
}
public static float Random01(float x, float y)
{
return Random(x, y) / MaxNum;
}
private static void InitRandomSequence()
{
if (RandomSequence.Length < 1)
SetSeed(Seed);
}
}
}
1.Value Noise:
文档连接:https://zhuanlan.zhihu.com/p/52054806
实现:
using UnityEngine;
using System.Collections;
using Game.Randoms;
/// <summary>
/// 差值方法
/// </summary>
public enum LerpType
{
Line,
Smooth,
}
public class ValueNoise : MonoBehaviour {
/// <summary>
/// 种子
/// </summary>
public int Seed = 50;
/// <summary>
/// 图片宽度
/// </summary>
public int widht = 512;
/// <summary>
/// 图片高度
/// </summary>
public int height = 512;
/// <summary>
/// 偏移
/// </summary>
public Vector2 Offset = Vector2.one;
/// <summary>
/// 缩放
/// </summary>
public float Scale = 1;
/// <summary>
/// 差值算法
/// </summary>
public LerpType Type = LerpType.Line;
/// <summary>
/// 晶格尺寸
/// </summary>
public int ValueSize = 32;
/// <summary>
/// 图片
/// </summary>
private Texture2D texture = null;
/// <summary>
/// 当Inspector 界面中的属性方式改变会调用此方法
/// </summary>
void OnValidate()
{
Create(Seed,widht,height);
}
/// <summary>
/// 生成texture2D
/// </summary>
/// <param name="seed">种子</param>
/// <param name="width">高度</param>
/// <param name="height">宽度</param>
public void Create(int seed,int width,int height)
{
LGC.SetSeed(seed);
if (texture == null) texture = new Texture2D(width, height);
Color[] colors = new Color[width * height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
float value = Noise(Offset.x+j*Scale, Offset.y + i*Scale);
colors[i * width + j] = new Color(value, value, value);
}
}
texture.SetPixels(colors);
texture.Apply();
transform.GetComponent<Renderer>().sharedMaterial.mainTexture = texture;
}
public float Noise(float x, float y)
{
//晶格尺寸
//正好位于晶格的顶点则直接返回
if (x % ValueSize == 0 && y % ValueSize == 0)
return LGC.Random01(x/ ValueSize, y/ ValueSize);
//确定左下角点
int xIndex = (int)(x / ValueSize);
int yIndex = (int)(y / ValueSize);
//4角的点
Vector2 bl = new Vector2(xIndex, yIndex);
Vector2 br = new Vector2(bl.x+1,bl.y);
Vector2 tl = new Vector2(bl.x,bl.y+1);
Vector2 tr = new Vector2(bl.x + 1, bl.y + 1);
//4角的随机值
float vbl = LGC.Random01(bl.x,bl.y);
float vbr = LGC.Random01(br.x, br.y);
float vtl = LGC.Random01(tl.x,tl.y);
float vtr = LGC.Random01(tr.x,tr.y);
//差值计算
float alerp, blerp, plerp;
if (Type == LerpType.Smooth)
{
//圆滑差值
blerp = SmoothLerp(vbl, vbr, (x % ValueSize) / ValueSize);
alerp = SmoothLerp(vtl, vtr, (x % ValueSize) / ValueSize);
plerp = SmoothLerp(blerp, alerp, (y % ValueSize) / ValueSize);
}
else
{
//线性差值
blerp = Mathf.Lerp(vbl, vbr, (x % ValueSize) / ValueSize);
alerp = Mathf.Lerp(vtl, vtr, (x % ValueSize) / ValueSize);
plerp = Mathf.Lerp(blerp, alerp, (y % ValueSize) / ValueSize);
}
return plerp;
}
public float SmoothLerp(float v1, float v2, float t)
{
float k = Mathf.Pow(t, 5) * 6 - Mathf.Pow(t, 4) * 15 + Mathf.Pow(t, 3) * 10;
return (1 - k) * v1 + k * v2;
}
}
效果:
Line差值:
Smooth差值: