Perlin噪声波对3d球面的影响

时间:2019-08-27 09:50:32

标签: c# unity3d wave perlin-noise

我一直在尝试找出如何使用Perlin Noise在3d球面上创建波浪效果

我找到了一些有关如何在飞机上进行操作的教程,但是在3d对象上却没有, 这段代码在飞机上工作得很好,有人知道如何在3D球体上进行修改吗? 预先感谢您的帮助

using UnityEngine;
using System.Collections;
public class PerlinTerrain : MonoBehaviour {

    public float perlinScale;
    public float waveSpeed;
    public float waveHeight;
    public float offset;

    void Update () {
        CalcNoise();
    }

    void CalcNoise() {
        MeshFilter mF = GetComponent<MeshFilter>();
        MeshCollider mC = GetComponent<MeshCollider>();

        mC.sharedMesh = mF.mesh;

        Vector3[] verts = mF.mesh.vertices;

        for (int i=0; i< verts.Length; i++) {
            float pX = (verts[i].x * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
            float pZ = (verts[i].z * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
            verts[i].y = Mathf.PerlinNoise(pX, pZ) * waveHeight;
        }

        mF.mesh.vertices = verts;
        mF.mesh.RecalculateNormals();
        mF.mesh.RecalculateBounds();
    }

}

2 个答案:

答案 0 :(得分:0)

最简单的方法是将2D噪声应用于表面。您可以通过使用顶点法线来确定将位置移动到哪个方向。

在代码中,您仅移动Y位置。对于平面,这意味着您将顶点沿其法线方向移动了噪波函数给您的量。对于spheere,您可以执行以下操作:

verts[i] = verts[i] + (Mathf.PerlinNoise(pX, pZ) * waveHeight * mF.mesh.normals[i].normalized);

这将适用于任何网格,因为它考虑了其原始位置并且仅将顶点沿其法线方向移动。

这将使顶点向上移动,这意味着它将始终高于原始位置,您可以对噪波函数应用简单的偏移以使其也变低

verts[i] = verts[i] + ((Mathf.PerlinNoise(pX, pZ) - 0.5f) * waveHeight * mF.mesh.normals[i].normalized);

我注意到您正在对此噪声进行动画处理,对于每次更新都使用原始网格物体而不是对其施加噪声的新网格物体而言,这一点很重要。所以最终看起来像这样

using UnityEngine;
using System.Collections;

public class PerlinTerrain : MonoBehaviour
{

    public float perlinScale;
    public float waveSpeed;
    public float waveHeight;
    public float offset;

    Vector3[] baseVertices;

    private void OnEnable()
    {
        MeshFilter mF = GetComponent<MeshFilter>();

        baseVertices = mF.mesh.vertices;
    }

    void Update()
    {
        CalcNoise();
    }

    void CalcNoise()
    {
        MeshFilter mF = GetComponent<MeshFilter>();

        mF.sharedMesh.vertices = baseVertices;
        mF.sharedMesh.RecalculateNormals();

        Vector3[] verts = mF.sharedMesh.vertices;

        for (int i = 0; i < verts.Length; i++)
        {
            float pX = (verts[i].x * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
            float pZ = (verts[i].z * perlinScale) + (Time.timeSinceLevelLoad * waveSpeed) + offset;
            verts[i] = verts[i] + ((Mathf.PerlinNoise(pX, pZ)) * waveHeight * mF.sharedMesh.normals[i].normalized);
        }

        mF.sharedMesh.vertices = verts;
    }
}

但是您仍然有1个问题。有多个具有相同位置但具有不同法线的顶点。您将必须找出共享哪些顶点并计算其法线。

按位置将顶点分组,并取平均法线,并且仅在每个唯一顶点上迭代一次。

答案 1 :(得分:-2)

因为这将被称为单纯噪声

https://en.wikipedia.org/wiki/Simplex_noise

Perlin是2D版本的特定名称