Top > ComputerGraphics > HLSL > XNA > CantUsePerlinNoiseFunction
Last-modified: Sun, 01 Jul 2012 02:42:19 JST
Counter:3046 Today:4 Yesterday:0 Online:9
このエントリーをはてなブックマークに追加

noise関数が使える環境は限られている(XNA4.0では使えない)

About

このページでは上げている問題を解決していません。根本的な問題があったことについて言及しています。

 HLSL内で乱数を使うにはどうしたら良いものかとReferenceを見ていたら「noise (DirectX HLSL)- MSDN」関数が用意されていて、CGではお馴染みのパーリンノイズが生成できることが分かった(寧ろパーリンノイズを使いたかった)。使えるものは使ってやろうと思いたってPixelShaderの中でnoise関数を呼び出したものの、何故か上手くコンパイルされない。そこで最小のセットにしてみるとコンパイルが通る。どういうことだ、となってしまった。この時点できちんとリファレンスを洗っておけば良かったと後に気が付く。良く見ればnoiseの隣に(DirectX HLSL)って書いてある…。

コンパイルされるパターン:固定値を与える

    temp = noise(1);

コンパイルされないパターン:変動値を与える

    temp = noise(texCoord.x);

 ちなみにこの時点でのシェーダバージョンは2_0とXNAでは標準的なバージョンでした。

DirectXのTextureShaderでなければnoise関数を利用できない

 値をいろいろ変えてみても、どうにも理想的な環境でコンパイルされない。そこでリファレンスを再度参照した結果分かったのは、DirectXのTextureShader内でなければnoise関数は利用できない、という根本的にどうしようもない問題だった。Webで調べてみればこのことについては様々な箇所で言及されていて、当然ながらMS公式でも言及されていた。

 noise 組み込み関数は、Ken Perlin 氏によって定義されたパーリン ノイズを生成します。この HLSL 関数は、現時点ではテクスチャー シェーダー内でテクスチャーを塗りつぶすためにのみ使用できます。これは、現在のハードウェアがこのメソッドをネイティブにサポートしていないためです。テクスチャー シェーダーは、便利なヘルパー関数である D3DXFill*Texture() 関数と共に使用されることで、プロシージャで定義されるテクスチャーをロード時に生成します。

 言葉はおかしいけれども「パーリンノイズは連続的に変化する乱数」なのでハードウェア側が対応していないと確かに利用することはできない。シェーダ内で利用・参照された値は、次回以降のシェーダの呼び出しに連続して持ち越すことができないためである(良く考えてみれば当たり前)。パーリンノイズのアルゴリズムについては知らないものの、その特徴を鑑みれば素直に納得できる。

一応他のMS公式では次のURLにも言及されている。シェーダモデルの隣に(DirectX HLSL)と記述されている。

XNAはDirectX9上に作られている

 上で紹介した「noise (DirectX HLSL)」- MSDN Magazineを見て同じように気がついた方がいるかもしれないのだけれど「シェーダモデルが4以降なら、noise関数使えるんじゃないの?」と今度はそう思った。ダメなんです。XNA4.0はDirectX9の上に乗っかっているフレームワークで、DirectX9はシェーダモデルを3までしか対応していない。つまり根底的にHLSL内で乱数を扱う術がなくなってしまった(特に標準では)。

References