简体   繁体   English

Unity-佩林噪声八度

[英]Unity - Perlin noise Octaves

I'am trying to setup simple Terrain Generator in unity following tutorial, so far it works as intended, but i wanted to do more "natural" look and found out that i need to do Octaves or MultiLevel noise. 我正在尝试按照以下教程统一设置简单的Terrain Generator,到目前为止,它可以按预期工作,但是我想做得更“自然”,并发现我需要做Octaves或MultiLevel噪声。

Everything i found online regarding Multilevel Perlin noise, was not understandable for me or used completly different methode. 我在网上发现的有关多级Perlin噪声的所有信息,对我来说都是无法理解的,或者使用了完全不同的方法。

using UnityEngine;

[RequireComponent(typeof(MeshFilter))]
public class Mesh_Generator : MonoBehaviour
{

    #region Variables
    Mesh mesh;

    Vector3[] vertices;
    //Vector2[] Uvs;
    Color[] colors;
    int[] triangles;

    [Range(1, 9999)]
    public int xSize = 100;
    [Range(1, 9999)]
    public int zSize = 100;

    public Gradient gradient;

    public float MinHeight = 0;
    public float MaxHeight = 0;

    public bool Reset_Min_Max;
    #endregion
    #region Octaves
    [Range(1, 6)]
    public int Octaves = 6;
    public int Scale = 50;

    public float offsetX = 0f;
    public float offsetY = 0f;

    public float Frequency_01 = 5f;
    public float FreqAmp_01 = 3f;

    public float Frequency_02 = 6f;
    public float FreqAmp_02 = 2.5f;

    public float Frequency_03 = 3f;
    public float FreqAmp_03 = 1.5f;

    public float Frequency_04 = 2.5f;
    public float FreqAmp_04 = 1f;

    public float Frequency_05 = 2f;
    public float FreqAmp_05 = .7f;

    public float Frequency_06 = 1f;
    public float FreqAmp_06 = .5f;
    #endregion
    #region Start
    void Start()
    {
        mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;

        offsetX = Random.Range(0f, 99999f);
        offsetY = Random.Range(0f, 99999f);
    }
    #endregion
void ResetMinMax()
{
    MinHeight = 0f;
    MaxHeight = 0f;
        Reset_Min_Max = false;
}
#region Update
private void Update()
    {
        if (Reset_Min_Max)
            ResetMinMax();

        CreateShape();
        UpdateMesh();
    }
    #endregion
    #region CreateShape
    void CreateShape()
    {
        #region Vertices
        vertices = new Vector3[(xSize + 1) * (zSize + 1)];

        for (int i = 0, z = 0; z <= zSize; z++)
        {
            for (int x = 0; x <= xSize; x++)
            {
                float y = Calculate(x, z);
                vertices[i] = new Vector3(x, y, z);

                if (y > MaxHeight)
                    MaxHeight = y;
                if (y < MinHeight)
                    MinHeight = y;

                i++;
            }
        }

        int vert = 0;
        int tris = 0;
        #endregion
        #region Triangles
        triangles = new int[xSize * zSize * 6];

        for (int z = 0; z < zSize; z++)
        {
            for (int x = 0; x < xSize; x++)
            {
                triangles[tris + 0] = vert + 0;
                triangles[tris + 1] = vert + xSize + 1;
                triangles[tris + 2] = vert + 1;
                triangles[tris + 3] = vert + 1;
                triangles[tris + 4] = vert + xSize + 1;
                triangles[tris + 5] = vert + xSize + 2;

                vert++;
                tris += 6;
            }
            vert++;
        }
        #endregion
        #region Gradient Color
        colors = new Color[vertices.Length];
        for (int i = 0, z = 0; z <= zSize; z++)
        {
            for (int x = 0; x <= xSize; x++)
            {
                float Height = Mathf.InverseLerp(MinHeight, MaxHeight, vertices[i].y);
                colors[i] = gradient.Evaluate(Height);
                i++;
            }
        }
        #endregion
        #region UVs
        /*
         Uvs = new Vector2[vertices.Length];
         for (int i = 0, z = 0; z <= zSize; z++)
         {
             for (int x = 0; x <= xSize; x++)
             {
                 Uvs[i] = new Vector2((float)x / xSize, (float)z / zSize);
                 i++;
             }
         }
         */
        #endregion
    }
    #endregion
    #region Octaves Calculation
    float Calculate(float x, float z)
    {
        float[] octaveFrequencies = new float[] { Frequency_01, Frequency_02, Frequency_03, Frequency_04, Frequency_05, Frequency_06 };
        float[] octaveAmplitudes = new float[] { FreqAmp_01, FreqAmp_02, FreqAmp_03, FreqAmp_04, FreqAmp_05, FreqAmp_06 };
        float y = 0;

        for (int i = 0; i < Octaves; i++)
        {
            y += octaveAmplitudes[i] * Mathf.PerlinNoise(
                     octaveFrequencies[i] * x + offsetX * Scale,
                     octaveFrequencies[i] * z + offsetY * Scale) ;

        }

        return y;
    }
    #endregion
    #region UpdateMesh
    void UpdateMesh()
    {
        mesh.Clear();

        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.colors = colors;
        //mesh.uv = Uvs;

        mesh.RecalculateNormals();

    }
    #endregion
    #region  Gizmos
    /* 
     private void OnDrawGizmos()
    {
        if (vertices == null)
            return;

        for (int i = 0; i < vertices.Length; i++){
            Gizmos.DrawSphere(vertices[i], .1f);
        }           
    }
    */
    #endregion
}

In link below is my current result and result which i'am trying to achieve. 在下面的链接中是我当前的结果以及我正在尝试实现的结果。

https://imgur.com/a/m9B6ga4 https://imgur.com/a/m9B6ga4

is it possible to achieve such result using this method ? 使用这种方法能否达到这样的结果? if so would be possible to show script example ? 如果可以的话,可以显示脚本示例吗?

Thank you a lot. 非常感谢。

*updated code again *再次更新代码

multi level, or multi octave perlin is just few iterations of standard perlin added together. 多级或多倍频程perlin只是将标准perlin加在一起的几次迭代。 An example code could look like this: 示例代码如下所示:

float[] octaveFrequencies=new float() {1,1.5f,2,2.5f} ;
float[] octaveAmplitudes=new float() {1,0.9f,0.7f,0.f} ;
float y=0;
for(int i=0;i<octaveFrequencies.Length;i++)
 y += octaveAmplitudes[i]* Mathf.PerlinNoise(
      octaveFrequencies[i]*x + .3f, 
      octaveFrequencies[i]* z + .3f) * 2f ;

The numbers you put into arrays will decide the final shape of the noise. 放入数组中的数字将决定噪声的最终形状。 Values from the frequencies array are multiplied by your input, values from the amplitudes array are multiplied by the resulting perlin at that layer. 频率阵列中的值乘以您的输入,振幅阵列中的值乘以该层上得到的贝林。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM