グローバルイルミネーション(32) スペクトルレンダリング

スペクトルでレンダリング出来るようにしています。
レンダラが大体出来るとスペクトルへの対応は8割は終わっているようなものだと思います。
というのも処理の流れは全く同じなはずで若干のスペクトルへの対応があるだけですが残りの2割は以外に壁が厚い。

処理自体はまったく同じ具合な(はず)ので修正は殆ど要りませんがRGBで扱っているところは波長にするだけです。C/C++ならtypedefで終わり。
後は反射屈折の対応です。これらは波長で変わる必要があります。
レンダリングは波長(サンプリング)で行うので最終的にはRGBで出力しなおす必要がありますが波長->XYZ->RGBという流れで変換できます。

で得られる表を使えば波長->XYZが分かるので関数を作れば良いですが私は以下の方法で対応しました。
Simple Analytic Approximations to the CIE XYZ
Color Matching Functions
が参考になります(Listing 1. Simple C code for our multi-lobe Gaussian fit from Equation 4.)。連続な関数として定義できるので中途半端な波長でも値が得られます。

しかし、最大の難題はRGB->波長です。
一意に変換できないのは常識的分かりますがこれが出来ないと面倒な事になります。
つまり、レンダリングしようとしているのが赤い球だと普通は赤(255,0,0)のように入力しておくことが出来ますがこれを波長で入力しなければならなくなります。
さらに複数の波長が絡んで出来ている色(灰色とか?)とかどんな波長を入力としたら良いのか分かりません。
参考になるのは以下の論文です。

An RGB to Spectrum Conversion for Reflectances

Brian Smits1
University of Utah

Spectrum RGBToSpectrum(red,green,blue)の擬似コードがあります。whiteSpectrum;とかcyanSpectrumとかが分かりませんが論文の最後(Data)に380nm to 720nm.の表が役に立ちます。

しかし、380nm to 720nmを10個に離散化している荒い表なのですが今はこの表の値を使って実装しています。もっと細かいデータならフィッティングして連続的な関数にしてしまえば便利なんでしょうが。。。
一応、http://www.cs.utah.edu/~bes/papers/color/にこの表を作ったMATLABのコードがあるのですが、、、私はMATLABを持っていないのでなんとも成りません。