少し質問があります。シンプレックスノイズの動作を示すコードまたはサンプルはありますか?私はそれについて何も見つけることができません...アルゴリズムがどのように機能するかを知らずに、どのようにそれを実装するべきですか?...
もう1つの質問は、シンプレックスノイズはアイランド生成に適したアルゴリズムですか?レイヤーが大きく(砂、グラ、石)、エッジがソフトではっきりと見える大きな島(本当に巨大)が必要です。これにより、凹凸のある表面を飛び越えずに水に出入りできます。
少し質問があります。シンプレックスノイズの動作を示すコードまたはサンプルはありますか?私はそれについて何も見つけることができません...アルゴリズムがどのように機能するかを知らずに、どのようにそれを実装するべきですか?...
もう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ではありますが、ほぼ正確にあなたが望むものです。
助けてくれてありがとう。
2日前、「Libnoise」と優れたC#ポートを見つけました。より滑らかなハイトマップをレンダリングするレンダラーがあるので、これを取り上げます:)
まだこれに出会っていない場合は、Stefan GustavsonのSimplex Noise Demystifiedがアルゴリズムの動作をよく説明しています。