【问题标题】:Unity - Perlin noise OctavesUnity - Perlin 噪声八度
【发布时间】:2019-05-05 09:00:31
【问题描述】:

我正在尝试按照教程在统一中设置简单的地形生成器,到目前为止它按预期工作,但我想做更“自然”的外观,发现我需要做八度或多级噪声。

我在网上找到的关于多级 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

用这种方法可以达到这样的效果吗? 如果可以显示脚本示例?

非常感谢。

*再次更新代码

【问题讨论】:

    标签: c# visual-studio unity3d perlin-noise


    【解决方案1】:

    多级或多倍频程 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 ;
    

    您放入数组的数字将决定噪声的最终形状。频率数组中的值乘以您的输入,幅度数组中的值乘以该层的结果 perlin。

    【讨论】:

    • 谢谢你,这至少为我清除了一点,但我认为我仍然做错了,因为这感觉仍然是“人工”链接:imgur.com/a/ZvQJ7Ut我从中检索“Y”:float Calculate(float x, float z) 你的代码在哪里。
    • 在这个频率下看起来大致像 perlin,八度音阶可以很好地显示你的分辨率(在这种情况下是顶点数)应该更高一点(或者你的基频更低),看起来更高阶的 perlin别名
    • 试图增加顶点数,这是 512x 256,它会完全破坏图形:/ 并且看起来仍然很平坦,我在主要问题中再次更新了代码。 imgur.com/a/NRkXVPl
    • 好吧,我实现了我想要的东西,但没有你的代码,我无法实现我只是使用了巨大的值,这就是为什么它不能正常工作,不能使用更多 256x256 的问题顶点仍然存在。 addig valleys / 河流现在会很容易,因为我更清楚地理解它,我非常感谢你:) imgur.com/a/29jusDe
    猜你喜欢
    • 1970-01-01
    • 2014-02-15
    • 2017-09-02
    • 2020-06-06
    • 2011-09-20
    • 2013-10-14
    • 2021-06-30
    • 2013-07-23
    • 2020-06-22
    相关资源
    最近更新 更多