2009-08-21 8 views
3

私は擬似ランダムノイズ生成、特にPerlinとSimplexアルゴリズムに興味を持っています。シンプレックスの利点はスピード(特に高次元で)ですが、比較的容易にペリンをタイル貼りすることができます。もし誰かがタイルシンプレックスアルゴリズムを知っていたのかしら?固定ディメンションは問題ありませんが、一般的です。擬似コードは良いですが、c/C++が優れています。タイルシンプレックスノイズ?

+1

[この質問にも回答しました](http://gamedev.stackexchange.com/questions/23625/how-do-you-generate-tileable-perlin-noise)ここでの回答も興味深いですが – bobobobo

+0

Iシンプレックスノイズをタイル張りに取り組んで数日間無駄にしてしまったことが判明しただけです(特許番号:6867776)。私の時間の無駄です。あなたのことを無駄にしないで、代わりに "クラシックノイズ"を使用してください。 –

+0

そしてPerlin Noiseは特許を取得していませんか? http://www.wikipatents.com/US-Patent-6867776/standard-for-perlin-noiseあなたが知らなかった場合に備えて、Kenneth Perlinは古いPerlinノイズを置き換えるためにSimplexノイズを作成しました。人工物が少ない。 – raRaRa

答えて

2

この問題は、hereと合理的に解決されているようであり、作業用ソリューションの背後にあるアイデアの詳細な説明はhereです。長年の問題に対する素晴らしい答え!

1

私は最近、シンプレックスノイズをタイルする必要があり、この質問に出くわしました。

任意のノイズ関数を使用してノイズをタイリングするために、あなたは直線的に追加のタイルのサンプルを補間することができます

Ftileable(x, y) = ( 
     F(x, y) * (w - x) * (h - y) + 
     F(x - w, y) * (x) * (h - y) + 
     F(x - w, y - h) * (x) * (y) + 
     F(x, y - h) * (w - x) * (y) 
)/(wh) 

F()はあなたのノイズの関数です。 x、yは個々のタイル内の座標でなければならないことに注意してください。xは[0、w]、yは[0、h]です。 tileX = x - Math.Floor(x/w)* wやfmod()のようなものを使うことができます。

パフォーマンスが重要な場合や高次元の場合は、次元Dに対して2^Dルックアップが必要であるため、これは方法ではありません。また、タイルの中心に向かって値が低くなります。 http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html

+0

しかし、これはPerlinノイズをタイル化していますが、Simplexノイズではありません。 – fbrereto

+0

このリンクでは、Perlinノイズについて説明していますが、そのメソッドがそれ専用であることを明示的に述べていません。私は、シンプレックスノイズをタイル張りして動作する2D実装を持っていますが、振幅がタイルの中心に向かって減少するため、代替を選択しました。ガボールノイズは、この方法(http://graphics.cs.kuleuven.be/publications/LLDD09PNSGC/)に頼ることなく、良い結果とタイルを生成するようです。 – BenC

3

ジャストタイルあなたノイズあなたはパーリンにのみスキュー後にそれを行うだろうと同じように:

から撮影します。これを行うには、ベースコーナーから他のコーナーを取得するためにオフセットに追加した後(前にではなく)mod 256(または使用しているものであれば何でも)を実行するパーツを変更します。これはHLSLのコードの変更ビットである:

uint3 iIdx0 = p0SI % 256; 
uint3 iIdx1 = (p0SI + pI1) % 256; 
uint3 iIdx2 = (p0SI + pI2) % 256; 
uint3 iIdx3 = (p0SI + 1.0f) % 256; 
uint iGI0 = gPerm[ iIdx0.x + gPerm[ iIdx0.y + gPerm[ iIdx0.z ] ] ] % 12; 
uint iGI1 = gPerm[ iIdx1.x + gPerm[ iIdx1.y + gPerm[ iIdx1.z ] ] ] % 12; 
uint iGI2 = gPerm[ iIdx2.x + gPerm[ iIdx2.y + gPerm[ iIdx2.z ] ] ] % 12; 
uint iGI3 = gPerm[ iIdx3.x + gPerm[ iIdx3.y + gPerm[ iIdx3.z ] ] ] % 12; 

p0SIは角0点であり、PI2とPI2は、通常の方法で算出された1コーナー2コーナーにベクターです。 HLSLスカラーは混在したオペランドでベクトルに自動的に昇格するので、1.0fは実際には(1.0,1.0,1.0)です。私はちょうどこのタイルスタフを考え出しましたが、実用的には機能します。あなたが大規模な惑星やいくつかのたわごとをシェードする必要があるが、あなたのカードに単精度だけを持っている場合は、いくつかのステップがあります。私を打つ。

編集:もう少し考えてみたら、何かを変更する必要はないと思います。私はそれが実装されているように自動的に256単位でタイルを並べると思います。

1

数年が経過しても、この質問は引き続きGoogleで最高の結果です。

シンプレックスノイズでは、直線(オルトノーマル)グリッドからのxとyがスキューされてシンプレックスが見つかる(2次元の三角形)ので、一般的なタイリング技術(%255など)では、しかし、歪んだ座標のタイルは、それは "斜めに"タイルであり、これはまったく役に立たない。

私が見つけた簡単な解決策は、元のXとYを最初に「左に」歪ませるように、結果を「歪ませない」ことです。アルゴリズムが「右に」歪んでしまいます。最終的な結果はスキューのないグリッドに再整列されます。

たとえば、シンプレックスの実装がSimplexNoiseに似ている場合。あなたはネット上でどこでも見つけることができますJavaは、それが使用してグリッドスキュー:

var F2 = 0.5*(Math.sqrt(3.0)-1.0); 
var s = (xin+yin)*F2; // Hairy factor for 2D 
var i = Math.floor(xin+s); 
var j = Math.floor(yin+s); 

をすることはできメソッドのエントリポイントで逆方向にそれを単に「前スキュー」:

var G2 = (3.0-Math.sqrt(3.0))/6.0; 
var t = (xin+yin)*G2; 
xin-=t; 
yin-=t; 

残念なことに、それは通常は問題ではありませんが、あなたがそのノイズを必要とするかどうかに依存して、何らかの形で見えないエフェクトを生成します(つまり、少し歪んで見えます)。

私にとっては問題だったので、この「逆スキューイング」は、最終出力でより重く、より軽いオクターブの補間を使用した2オクターブだけに適用してみました。このソリューションは、シンプレックス・パーリン・ノイズに基づいた満足のいくタイリングをもたらしました。すべてのオクターブでの補間がタイル境界線での減衰を大きくし、人工的な歪みなしにオクターブを追加すると、追加のノイズの下でストラッギング・エフェクトが埋められます。