Heightmap や procedural texture を調べると、頻繁に Perlin noise という言葉が出てきます。このため、アルゴリズムの説明や公開コードも豊富であろうと考え、気楽に実装を始めたのですが・・・想定外のハマり方をしました。
結論からは、Perlin noise の説明や実装は簡単に見つかります。しかし、その多くが 「Perlin noise ではない」のです。この答えに到達するまでに随分時間が掛かりました。
Perlin noise は、gradient と呼ばれる擬似乱数のベクトルをグリッド上に配置し、任意の位置 (グリッドに沿っているとは限らない) のノイズ値を、それを取り囲む 4 点にある gradient から重み付けを考えて算出する仕組みかと思います。
恐らく、Perlin noise を理解しようとした場合、Matt Zucker による The Perlin noise math FAQ を読むことがベストだと思います。
Perlin noise は、gradient を元にしたアルゴリズムであることから、gradient noise として分類されるそうです。
Gradient noise: http://en.wikipedia.org/wiki/Gradient_noise上記ページには、興味深いことが書かれています。「しょっちゅう value noise と混同されます」と。事実、Perlin noise 実装を謳ったコードの多くが、この value noise に分類されるものです。Wikipedia の記述からは、あまりに混同されるために gradient noise と value noise という分類を作ったという印象を受けます。
Value noise: http://en.wikipedia.org/wiki/Value_noise上記ページには、Perlin noise ではないにもかかわらず Perlin noise として説明している某サイトへのリンクが value noise の説明として貼られています。
厄介なことに、Perlin noise を検索すると、このサイトが上位に現れます。このサイトでは、擬似乱数のスカラー値をグリッド上に配置し、それらにブラーをかけ、更に補間を行ない、滑らかなノイズとしているようです。
このサイトの内容は非常に有益でしたが、誤ったタイトルを付けたことで、Perlin noise ではないものを Perlin noise であると解釈した人が大量に生まれたのではないかと推測します。
僕も Ken Perlin にのみ従っていれば良かったのですが、誰かの C# コード丸パクリで済まそうとしたことで、この混乱の渦へ自ら身を投じてしまったようです。
と言うことで、Ken Perlin によるオリジナル コード、および、 Matt Zucker によるらしい C++ コードを見つけたので (見つけた場所が怪しいためリンクを貼りません) 、それらを元に XNA で実装しています。
先行して、Ken Perlin による Improved Noise reference implementation (Java 実装) を C# へ移植したのですが、ちょっと gradient の式が理解できていません・・・。
他には、libnoise というノイズ生成のためのオープンソース ライブラリも参考にして進めています。libnoise のコードはクラス設計が綺麗に纏められており、コードを読んでいて心地良いです。
0 件のコメント:
コメントを投稿