柏林噪声的应用不止与模拟自然情况,也可以用于一些特殊图形的绘制,
该图片就是利用了噪声生成的平缓随机数将上帧标记为脏,重新刷新生成的随机图形
// 细节,值越大,边数越多,越近似圆
public int Detail = 60;
// 半径
public float Radius = 200;
// 噪声强度,值越大,噪声变化越大
public float Diff = 100;
// 噪声的偏移量,值越大,噪声的起始位置和形状越大,影响初始化
public float DataOffset = 100;
private Vector2 _offset;
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
// 添加中心顶点
vh.AddVert(Vector3.zero, color, Vector4.zero);
var deltaAngle = Mathf.PI * 2.0f / Detail;
var len = Detail - 1;
for (var i = 0; i < Detail; ++i)
{
var angle = deltaAngle * i;
// 根据角度和噪声生成半径值
var r = Radius + Mathf.PerlinNoise(_offset.x + DataOffset + Mathf.Cos(angle), _offset.y + DataOffset + Mathf.Sin(angle)) * Diff;
// 坐标转换添加顶点数据
vh.AddVert(new Vector3(r * Mathf.Cos(angle), r * Mathf.Sin(angle), 0), color, Vector4.zero);
if (i == len)
vh.AddTriangle(0, i + 1, 1); // 最后一个顶点与第一个顶点连线
else
vh.AddTriangle(0, i + 1, i + 2); // 当前顶点与下一个顶点连线
}
}
protected override void Start()
{
base.Start();
StartCoroutine(OnUpdate()); // 启动协程
}
protected override void OnDisable()
{
StopAllCoroutines(); // 停止所有协程
base.OnDisable();
}
private IEnumerator OnUpdate()
{
while (gameObject.activeSelf)
{
_offset += Vector2.right * 0.01f; // 更新偏移量
SetVerticesDirty(); // 标记顶点为脏
yield return null; // 下一帧
}
}
该代码同时利用了协程来进行更新而不是Update()函数,该段是为了更好的控制生成与减少更新频率,在Update()函数中效果相同