簡體   English   中英

Unity-佩林噪聲八度

[英]Unity - Perlin noise Octaves

我正在嘗試按照以下教程統一設置簡單的Terrain Generator,到目前為止,它可以按預期工作,但是我想做得更“自然”,並發現我需要做Octaves或MultiLevel噪聲。

我在網上發現的有關多級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
}

在下面的鏈接中是我當前的結果以及我正在嘗試實現的結果。

https://imgur.com/a/m9B6ga4

使用這種方法能否達到這樣的結果? 如果可以的話,可以顯示腳本示例嗎?

非常感謝。

*再次更新代碼

多級或多倍頻程perlin只是將標准perlin加在一起的幾次迭代。 示例代碼如下所示:

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 ;

放入數組中的數字將決定噪聲的最終形狀。 頻率陣列中的值乘以您的輸入,振幅陣列中的值乘以該層上得到的貝林。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM