You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中为Perlin噪声添加随机种子以生成3D体素地形

解决Unity中Perlin噪声随机种子的问题

嘿,我懂你想要每次运行都生成不一样的3D体素地形,而不是每次都用固定种子得到重复结果的需求。Unity内置的Mathf.PerlinNoise确实没有直接提供设置随机种子的接口,但我们有几个实用的办法来实现随机化:

方法1:坐标偏移法(最简单快速)

Perlin噪声的输出是基于输入坐标计算的,所以我们可以给x和y坐标加上随机生成的偏移值,相当于让噪声的“起始位置”随机变化,这样每次生成的地形就不一样了。

修改你的代码如下,我标注了新增的关键部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PerlinCubeGenScript01 : MonoBehaviour
{
    public float perlinNoise = 0f;
    public float refinement = 0.1f; // 建议给个默认值,0的话噪声会全是同一个值
    public int multiplier = 5; // 给个默认值让效果更直观
    public int cubes = 10; // 默认生成10x10的体素网格
    public float darkness;
    // 新增:存储随机偏移量的变量
    private float offsetX;
    private float offsetY;

    void Start()
    {
        // 生成随机偏移量,范围选大一点避免噪声图案变化不明显
        // 如果需要可复现的随机地形,可以先调用 Random.InitState(你的种子值)
        offsetX = Random.Range(0f, 10000f);
        offsetY = Random.Range(0f, 10000f);

        for (int i = 0; i < cubes; i++)
        {
            for (int j = 0; j < cubes; j++)
            {
                // 计算噪声时给坐标加上随机偏移
                perlinNoise = Mathf.PerlinNoise((i * refinement) + offsetX, (j * refinement) + offsetY);
                GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
                go.transform.position = new Vector3(i, Mathf.Round(perlinNoise * multiplier), j);
                int cubeY = (int)Mathf.Round(perlinNoise * multiplier);
                Debug.Log(cubeY);
                go.GetComponent<Renderer>().material.color = new Color(1, 1, 1, 0f);
            }
        }
    }

    void Update()
    {
    }
}

小提示:

  • 如果需要可复现的随机地形,可以在生成偏移量前调用Random.InitState(你的种子值),比如Random.InitState(42),这样同一个种子会生成完全一致的地形,换种子就能得到新地形。

方法2:使用Unity的Noise类(Unity 2020.2及以上版本)

Unity在2020.2版本引入了更灵活的Noise类,它支持直接传入种子参数,比坐标偏移更直观,还支持3D噪声计算。

替换噪声计算的代码示例:

// 在Start方法的循环里替换原有噪声计算行
int randomSeed = Random.Range(0, 10000);
perlinNoise = Noise.Perlin((i * refinement), (j * refinement), 0f, seed: randomSeed);

这个方法可以直接指定种子,后续想要调整地形细节也更方便。

方法3:自定义带种子的Perlin噪声实现

如果你需要完全控制噪声的生成逻辑,也可以自己实现一个带种子参数的Perlin噪声函数。这里给一个简化的框架示例:

public static class CustomPerlin
{
    private static int[] permutation;
    private static float[] p;

    // 用种子初始化噪声的排列表
    public static void Initialize(int seed)
    {
        permutation = new int[256];
        System.Random rng = new System.Random(seed);
        for (int i = 0; i < 256; i++)
        {
            permutation[i] = rng.Next(256);
        }
        p = new float[512];
        for (int i = 0; i < 512; i++)
        {
            p[i] = permutation[i % 256];
        }
    }

    // 自定义的2D Perlin噪声计算
    public static float Noise(float x, float y)
    {
        // 这里可以补充完整的Perlin噪声算法逻辑
        // 标准Perlin算法的实现可以参考公开的代码示例
        int xi = (int)x & 255;
        int yi = (int)y & 255;
        float xf = x - (int)x;
        float yf = y - (int)y;
        // ... 后续插值、梯度计算等步骤
        return Mathf.Clamp01((p[xi + p[yi]] * xf + p[xi + 1 + p[yi]] * (1 - xf)) * yf + 
                            (p[xi + p[yi + 1]] * xf + p[xi + 1 + p[yi + 1]] * (1 - xf)) * (1 - yf));
    }
}

使用时先调用CustomPerlin.Initialize(你的种子值),再用CustomPerlin.Noise(x,y)获取噪声值即可。


内容的提问来源于stack exchange,提问作者Couches

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:18:13