私は (愛好家として) 疑似乱数ノイズの生成、特にパーリンおよびシンプレックス アルゴリズムに興味を持っています。シンプレックスの利点は速度です (特に高次元で) が、パーリンは比較的簡単にタイルを張ることができます。誰かがタイリング シンプレックス アルゴリズムを知っているかどうか疑問に思っていましたか? 固定次元で問題ありませんが、ジェネリックの方が優れています。擬似コードは問題ありませんが、c/c++ の方が優れています。
4 に答える
Perlin で行うのと同じ方法でノイズを並べるだけで、スキューの後でのみ行うことができます。これを行うには、順列を取得する部分を変更して mod 256 (または & 255、使用しているものは何でも) を実行し、(前ではなく) オフセットに追加して、ベース コーナーから他のコーナーを取得します。これは、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 ユニットで自動的にタイル表示されると思います。
数年経った今でも、この質問は Google での最良の結果の 1 つです。
シンプレックス ノイズでは、直線 (直交) グリッドの x と y が歪んで、ポイントが存在するシンプレックス (2D の三角形) が検出されるため、一般的なタイリング手法 (%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;
残念ながら、それはどこか奇妙に見える効果 (つまり、少し歪んで見える :D ) を生成しますが、これは通常は問題ではありませんが、そのノイズが何のために必要かによって異なります。
それは私にとっては問題だったので、この「逆歪曲」を、最終出力でより重みのあるいくつかのオクターブにのみ適用してみました。代わりに、「より軽い」オクターブに補間を使用しました。このソリューションにより、シンプレックス パーリン ノイズに基づいた満足のいくタイリングが得られました。これは、すべてのオクターブで補間を行うと、タイルの境界で過度の減衰が発生するためであり、人為的なスキューなしでさらにオクターブを追加すると、ストレッジに見える効果が追加のノイズに埋もれてしまいます。
最近、シンプレックス ノイズのタイリングが必要になり、この質問に遭遇しました。
任意のノイズ関数を使用したタイリング ノイズの場合、追加のタイル サンプルを線形補間できます。
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 は個々のタイル内の座標でなければならないことに注意してください: [0, w) の x、[0, h) の y。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