108

Web のあちこちで参照されているシェーダーで使用するためのこの疑似乱数ジェネレーターを見てきました。

float rand(vec2 co){
  return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

これは、「正規」または「どこかの Web で見つけたワンライナー」とさまざまに呼ばれます。

この機能の由来は何ですか?定数値は見た目ほど恣意的ですか、それとも選択に芸術性がありますか? この機能のメリットについての議論はありますか?

編集: 私が遭遇したこの関数への最も古い参照は、2008 年 2 月のこのアーカイブであり、元のページは現在 Web から削除されています。しかし、他のどこよりもそれについての議論はありません。

4

5 に答える 5

43

非常に興味深い質問です!

私は答えを入力しながらこれを理解しようとしています:)最初にそれで遊ぶ簡単な方法:http://www.wolframalpha.com/input/? i = plot%28 + mod%28 + sin%28x * 12.9898 +%2B + y * 78.233%29 + * + 43758.5453%2C1%29x%3D0..2%2C + y%3D0..2%29

次に、ここで何をしようとしているのかを考えてみましょう。2つの入力座標x、yに対して、「乱数」を返します。しかし、これは乱数ではありません。同じx、yを入力するたびに同じです。ハッシュ関数です!

関数が最初に行うことは、2Dから1Dに移行することです。それ自体は面白くありませんが、通常は繰り返されないように番号が選択されています。また、そこに浮動小数点の追加があります。yまたはxからさらにいくつかのビットがありますが、数字が正しく選択されている可能性があるため、混合されます。

次に、ブラックボックスのsin()関数をサンプリングします。これは実装に大きく依存します!

最後に、分数を乗算して取得することにより、sin()実装のエラーを増幅します。

一般的な場合、これは良いハッシュ関数ではないと思います。sin()は、数値的にはGPU上のブラックボックスです。ほとんどすべてのハッシュ関数を取得して変換することで、はるかに優れたものを構築できるはずです。難しいのは、CPUハッシュで使用される一般的な整数演算を浮動小数点(ハーフビットまたは32ビット)または固定小数点演算に変換することですが、それは可能であるはずです。

繰り返しますが、これをハッシュ関数として使用する場合の実際の問題は、sin()がブラックボックスであるということです。

于 2012-10-30T03:57:55.823 に答える
8

定数値は任意であり、特に非常に大きく、素数から 2 桁離れています。

高振幅正弦波の 1 に 4000 を掛けた係数は、周期関数です。それは窓のブラインドや波形の金属のようなもので、これは 4000 倍され、内積によって角度が付けられているため、非常に小さく作られています。

関数は 2 次元であるため、内積は X 軸と Y 軸に対して斜めに周期関数を回転させる効果があります。約13/79の比率で。それは非効率的です。(13x + 79y) の sinus を実行することで実際に同じことを達成することができます。

X と Y の両方で関数の周期が見つかった場合は、単純な正弦波のように見えるようにサンプリングできます。

グラフを拡大した写真がこちら

起源はわかりませんが、他の多くのものと似ています。一定の間隔でグラフィックスに使用すると、モアレ パターンが発生する傾向があり、最終的には再び一周することがわかります。

于 2013-09-21T07:39:28.047 に答える