Noise算法-Value Noise

伪随机数算法: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差值:
在这里插入图片描述

发布了32 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_18192161/article/details/103843997