シンプレックスノイズで島の地形を生成する(C#/ XNA)


7

少し質問があります。シンプレックスノイズの動作を示すコードまたはサンプルはありますか?私はそれについて何も見つけることができません...アルゴリズムがどのように機能するかを知らずに、どのようにそれを実装するべきですか?...

もう1つの質問は、シンプレックスノイズはアイランド生成に適したアルゴリズムですか?レイヤーが大きく(砂、グラ、石)、エッジがソフトではっきりと見える大きな島(本当に巨大)が必要です。これにより、凹凸のある表面を飛び越えずに水に出入りできます。


gamedev.stackexchange.com/questions/4628/…ご覧ください。また、特にシンプレックスノイズを探していますか?自分で作成したノイズサンプルがありますが、それはシンプレックスではありません(または実際にはパーリンです。これは、いわゆる「値」ノイズであり、十分に近く見えます)
共産主義者ダック

うーん、シンプレックスノイズに関する情報はありません...それでも、それでも?サンプルは役に立ちます:)多分あなたは私にそれを与えることができますか?感謝:)
SharpShade

私の仕事ではないので、これが答えになりたくありませんが、ケンが書いたシンプレックスノイズに関するリサーチ記事を入手できます:cs.umbc.edu/~olano/s2002c36/ch02.pdf(このリンクは以下に投稿した記事からリンクされているウィキペディア記事の下部。)PS:記事の最後にCとJavaのコードが含まれています。
ジェームズ

回答:


1

これに基づいて、C#のノイズジェネレーター:

static class NoiseGenerator
{
    public static int Seed { get; private set; }

    public static int Octaves { get; set; }

    public static double Amplitude { get; set; }

    public static double Persistence { get; set; }

    public static double Frequency { get; set; }

    static NoiseGenerator()
    {
        Random r = new Random();
        //LOOOL
        NoiseGenerator.Seed = r.Next(Int32.MaxValue);
        NoiseGenerator.Octaves = 8;
        NoiseGenerator.Amplitude = 1;
        NoiseGenerator.Frequency = 0.015;
        NoiseGenerator.Persistence = 0.65;
    }

    public static double Noise(int x, int y)
    {
        //returns -1 to 1
        double total = 0.0;
        double freq = NoiseGenerator.Frequency, amp = NoiseGenerator.Amplitude;
        for (int i = 0; i < NoiseGenerator.Octaves; ++i)
        {
            total = total + NoiseGenerator.Smooth(x * freq, y * freq) * amp;
            freq *= 2;
            amp *= NoiseGenerator.Persistence;
        }
        if (total < -2.4) total = -2.4;
        else if (total > 2.4) total = 2.4;

        return (total/ 2.4);
    }

    public static double NoiseGeneration(int x, int y)
    {
        int n = x + y * 57;
        n = (n << 13) ^ n;

        return (1.0 - ((n * (n * n * 15731 + 789221) + NoiseGenerator.Seed) & 0x7fffffff) / 1073741824.0);
    }

    private static double Interpolate(double x, double y, double a)
    {
        double value = (1 - Math.Cos(a * Math.PI)) * 0.5;
        return x * (1 - value) + y * value;
    }

    private static double Smooth(double x, double y)
    {
        double n1 = NoiseGeneration((int)x, (int)y);
        double n2 = NoiseGeneration((int)x + 1, (int)y);
        double n3 = NoiseGeneration((int)x, (int)y + 1);
        double n4 = NoiseGeneration((int)x + 1, (int)y + 1);

        double i1 = Interpolate(n1, n2, x - (int)x);
        double i2 = Interpolate(n3, n4, x - (int)x);

        return Interpolate(i1, i2, y - (int)y);
    }
}

コメントはありませんが、主要な部分:

シードはランダムにするために使用される値です。そのため、毎回同じものを生成することはありません。ここでは、NoiseGeneratorに配置しています。

振幅、周波数、持続性、オクターブについては、記事で説明しています。これらは基本的に、結果として生じるノイズの外観に影響を与えます。

NoiseGenerator 関数は文字通りPRNGです-入力を与え、それをシードとして乱数を生成します。

Noiseノイズ値を取得するために呼び出すものです。私は値が約-2.4から2.4であることを発見し(実際には約2.40032483か何かでクランプされているため)、2倍に固定しました。-1 and 1

これで速度の問題はありませんでした。これで値が設定された1x1スプライトの400x400グリッドをレンダリングしていて、わずかな遅れしか得ていませんでした(そして、フレームごとにノイズを再計算していました)。

島の世代については、この質問をチェックしてください。特に、このリンクはAS3ではありますが、ほぼ正確にあなたが望むものです。


えっと、申し訳ありませんが、ハイトマップを生成するジェネレータが必要だと言うのを忘れていました。または、これを使用して地形を生成するにはどうすればよいですか?現時点では、高さマップを生成し(さまざまなアルゴリズムを試しました...)、頂点を計算します。重要なのは、見栄えの良い島を生成する生成アルゴリズムが必要だということです:-/わかっています、難しいのですが、どのようにすればよいのかわかりません...
SharpShade

@Razerハイトマップの座標(x、yなど)をノイズ関数への入力として使用します。各ポイントに-1から1までの値を割り当てるため、いくつかの正規化を行う必要がある場合があります((値+1)* 127.5fは0から255の間で取得するために機能します)
共産主義者ダック

それは動作しますが、あまり良くありません...私が欲しいのは次のようなものです:hazelmckendrick.com/demos/terrain-generation-tropical-island
SharpShade

1
@Razerなぜそのソースを使用しないのですか?
共産主義者のアヒル

使用されているアルゴリズムの説明がないため、コードも何もありません。はい、わかっています。ソースは含まれていますが、C ++です。C ++がわかり
ません

1

助けてくれてありがとう。

2日前、「Libnoise」と優れたC#ポートを見つけました。より滑らかなハイトマップをレンダリングするレンダラーがあるので、これを取り上げます:)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.