マップ生成のためにタイル化可能なソリッドノイズを作成するにはどうすればよいですか?


16

やあみんな、私はコードでタイル化可能なフラクタルを生成する方法を見つけようとしています(ゲームマップ用ですそれは無関係です)私はGIMPに同梱されているSolid Noiseプラグインを変更しようとしています(方法は非常に限られていますがコードは動作します)が、正しく動作させることはできません。

これまでに修正したコード(Java)

(C)からコードを作成しているGIMPのソリッドノイズモジュール

これは私達成しようとしているものですが、 これは私が得ているものです

だから誰かが私が間違ったことを見ることができるか、または私がそれを別のやり方で行う方法を提案しているなら、私はそれを大いに感謝します。前もって感謝します。 そして、もし私が多くのことを求めているのなら、あるいは単に人生で大きな失敗をしているのなら、私は謝罪します。


バイリニアの代わりにバイキュービック補間を使用してみてくださいそれがあなたの問題かどうかはわかりませんが、それはそうです。
スティーブンフルラニ

回答:


4

私はあなたのコードに正確には従いませんが、ここに(投稿した画像に基づいて)効果をおおまかに達成するアルゴリズムの簡単な説明があります。

以下の説明は、最適化されたバージョンではありませんが、概念的に明確な説明です(願っています)。実行したら、それを最適化できます(実際、大幅に)。

  1. 均一なランダムノイズのn層を生成します(ランダムグレースケールピクセルのみ)。
  2. 次に、1、2、4、8、... 2 ^(n-1)ピクセルごとにサンプリングし、中間ピクセルを補間することにより、これらのそれぞれをサンプリングします。各レイヤーは前のレイヤーよりも滑らかです。
  3. ここで、これらを1、2、4、8などの係数でスケールします。各レイヤーは前のレイヤーよりも暗いです。
  4. これらすべてを一緒に追加します。
  5. 各ピクセルを(1 + 2 + 4 + 8 + ... 2 ^(n-1))で除算して正規化します。

難しいステップは、サンプリングと補間のステップです。レイヤー内でm番目のピクセルごとのサンプリングをスキップするとします。m> 1の基本的な考え方は次のとおりです(mが1の場合、画像をそのまま使用します)。

for each pixel x and y
   left_sample_coord = m *(x / m) //(integer division, automatically truncated)
   right_sample_coord = (left_sample_point + m) % image_width
   top_sample_point = m*(y / m) 
   bottom_sample_coord = (top_sample_point + m) % image_height

   horizontal_weight = (x - left_sample_point) / (m - 1)
   vertical_weight = (y - top_sample_point) / (m - 1)

   sample_top_left = image(left_sample_coord, top_sample_point)
   //and the same for the other four corners

   //now combine the top two points
   top_interpolate = sample_top_left * horizontal_weight + sample_top_right * (1-horizontal_weight)

  //now combine the bottom two points
  bottom_interpolate = sample_bottom_left * horizontal_weight + sample_bottom_right * (1-horizontal_weight)

  //and combine these two last obtained values

  smooth_noise(x, y) = top_interpolate * vertical_weight  + bottom_interpolate * (1 - vertical_weight)

いくつかのヒント:

  • 上記のアルゴリズムの結果は少し色あせたように見えるかもしれません。すべてのレイヤーに同じノイズレイヤーを使用することでこの効果を減らすか、後でイメージをコントラスト強調することができます。
  • 上記のアルゴリズムは線形補間を使用しますが、コサイン補間(検索を行う)はより良い結果をもたらします。
  • アルゴリズムのすべての部分でレイヤーを個別に確認できるようにします。これにより、バグをすばやくフラッシュできます。

3

元のペーストビンが何らかの理由で期限切れになったように見えるので、動作していないコードを比較する方法はありませんが、現在のゲームではGIMPコードを再度javaに変換し、正常に動作しているようです。

誰かがこのコードの使用を計画している場合は、コンストラクターを変更して設定パラメーター(詳細とサイズ)を変更し、希望どおりに機能させることをお勧めします。 編集:私の元々の質問はタイル化できるようにすることだと気づいたので、tilableをtrueに設定することを忘れないでください!

コード: http //pastebin.com/KsfZ99Xa

例: perlinジェネレーターの例


2

JavaとCのバージョンをざっと見て、ノイズ関数の使用方法にわずかな違いがあることに気付きました。ここにあなたのものがあります:

int val = Math.abs((int) Math.floor(255.0 * noise(((double)col/(double)width), ((double)row/(double)height))));

Cコード:

val = (guchar) floor (255.0 * noise ((col - xoffset) / width,

                                           (row - yoffset) / height));

オフセットを減算しないことを選択したのはなぜですか?(col-xoffset)および(row-yoffset)

ただ疑問に思う。コードを完全に分析する時間はありません。

お役に立てれば。


xoffsetとyoffsetは、GIMPが画像をグリッドに分割する方法で計算しますが、私のプログラムはすべて1つのタイルで動作するため、xとyのオフセットは0になります
ニックバダル

2

それが助けになるかどうかはわかりませんが、次のトリックは私にとってはうまくいきました:

http://www.gamedev.net/blog/33/entry-2138456-seamless-noise/

この仲間は4dノイズ関数を使用しており、2つの円のxy値を4dノイズのxyzw値として単純に提供しています。結果は完璧にループします。

1000 * 1000の画像のアイデア(簡略化)は次のとおりです。

for(i = 0;i < 1000; i++){

  for(j = 0; j < 1000; j++){

    nx = cos((i/1000) * 2 * PI);
    ny = cos((j/1000) * 2 * PI);
    nz = sin((i/1000) * 2 * PI);
    nw = sin((j/1000) * 2 * PI);

    looped_noise = noise_4D( nx, ny, nz, nw, octaves, persistence, lacunarity, blah...);
    noise_buffer[(i*1000)+j] = looped_noise;

  }
}

1

プラズマフラクタルまたはランダムな中点変位フラクタルとしても知られている菱形アルゴリズムを使用することをお勧めします。このアルゴリズムを使用すると、エッジを同じ値に制限するのが非常に簡単です。エッジの値を生成するとき、反対側の対応するエッジに値をコピーします。これにより、完全なタイルマップが作成されます。


0

ノイズ生成に関する素晴らしい記事がここにあります。記事が主張するように、それはパーリンノイズではありません(実際にはピンクノイズです)が、ノイズ画像がどのように生成されるかを理解することは依然として非常に便利です。

したがって、実際にあなたの質問に答えるには、タイル化可能なノイズ画像を作成するには、世代全体で「タイル」を維持する必要があります。つまり、ノイズが平滑化されると、あたかもそれがすべての方向に無限に繰り返されるように、つまりタイル状に平滑化されます。


0

スクリーンショットから、「大きな」レイヤーのみが生成されていると推測します。これが、ノイズが規則的になりすぎてディテールが欠けている理由です。

これは愚かに聞こえるかもしれませんが、「detail」変数を増やしてみましたか(16行目)。コードでは、1に設定されています。つまり、アルゴリズムは停止する前に2つの詳細レイヤーのみを生成します。8のような値に増やしてみてください。


0

また、Perlinノイズのいくつかの欠点を修正するためにKen Perlinによって開発されたSimplex Noiseもご覧ください。

私はC ++ゲームのシンプレックスノイズの実装に取り​​組んできました。マルチオクターブの1D / 2D / 3D / 4Dノイズをサポートします。現在、組み込みのテクスチャは大理石のみですが、簡単に追加できます。

(http://code.google.com/p/battlestar-tux/source/browse/trunk/src/lib/procedural/)

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