~■はじめにこれだけHDR、HDRといわれてきた世の中で、「.hdr」の拡張子であらわされるHDR画像フォーマットを扱っていないのはもぐりでしょう。HDR画像フォーマットはエクスプローラでさえもプレビューできる世界です。いうことで、「.hdr」の画像を読み込んでテクスチャにRGBE(A)で保存するルーチンを作ってきました。Format"のページのソースをDirectX用にまとめただけです。ページにあるので、そこから引っ張ってきました。Debevecだらけだなこりゃ)。いつものようにプログラムです。BRDF」のプログラムにフレネル付きの環境マップとして追加します。ソースには、いつものように適当にファイルが入っています。大事なソースは次のようになります。アプリケーションで使うHLSLプログラムどうせ「hdr.h」と「hdr.cpp」をぱくって使うことが多くなるんでしょう...■HDR画像フォーマットさて、HDR画像フォーマットはどのようなものでしょうか?中身をテキストエディタで除き見ると、次のようになっています。ZZZ\\Z[c\c\fjmjlgmloop・svoopoo情報のコメントやフォーマットにサイズが続いてその後はごちゃごちゃとわけがわからなくなるように見えます。HDR画像フォーマットは最初はテキストデータで、途中からバイナリデータに切り替わる特殊なデータです。その中身は、空白しかない行をはさんで、ヘッダとデータに分かれる構造をしています。|+------------------+ヘッダは、「#?」に続いてその種類を表す文字列「RADIANCE」が続きます(といっても、今回は「RADIANCE」しかサポートしません)。その後で「***=***」の構文をしている行は、データの属性などを記述します(今回は、FORMATだけでさらにいえば32-bit_rle_rgbeしかサポートしません)。1.0000000000000データ部は、最初に画像の大きさを表すテキスト文が一行あって、あとはバイナリデータになります。N」しか対応していません。Yの前に-がついているのは、テクスチャのデータが下に伸びていくことを示しています(つまり、普通のテクスチャデータということです)。ZZZ\\Z[c\c\fjmjlgmloop・svoopooちなみに、その後に続くバイナリのデータですが、バイナリエディタで開いてよく見ると、特定の文字列で区切られていることがわかります。EE実際のデータでは、これらの列が画像の列数だけあることがわかると思います。ここで、最初の2バイトの「0x02」はマジックナンバーです。古いバージョンのデータではこの部分が異なっていて、それらと区別をつけるために設けられています。その後の2バイトは、画像の幅を2バイトで現したものです。この値と先ほどのテキストによる幅の違いからもデータの整合性をつけることができます。この幅は8~0x7fffまでの値が許されていて、この大きさを超える(下回る)サイズの画像は、「古いバージョン」の読み方でサポートされます(それは、圧縮効率が悪い方法で格納されます)。4つのデータが連続してまとめられています。指数は、128を基準として2のべき乗の強さを各色成分に与えます。pow(2,E-128)になります。ここで、R、G、Bは、画像データから得た色成分で、Eは画像データから得た指数成分です。このデータは可変長で、ランレングス圧縮されています。具体的な圧縮方法は、最初に読み込んだデータが128よりも大きければ、その次のデータを最初のデータから128を引いた数だけ続けます。0x0aなお、読み込んだデータが128以下ならば、その後のデータを読み込んだデータ数だけそのまま出力します。圧縮されていないデータがこの後何個続くかを表現します。0x0cあとは、その繰り返しで行数が尽きるまで続けます。■プログラムのフローさて、以上の読み込みをどうやっているかということですが、今回は、下のような関数を定義して実装しました。DirectXのデバイスで、pSrcFileは読み込むファイル名です。エラーが発生したときに、そのエラーメッセージを吐き出します。関数の中では次のように行動していきます。具体的なコードの解説は、してもいいけどフォーマットの解説そのままだから省略(それでいいですか?)。ピクセルシェーダ2_0でLDRのピクセルの色に変換することができます。基本的な色の出力方法は、テクスチャで読み取ったアルファ成分から0.5のオフセットを引いて、2のべき乗して色成分に出力します。0.5で引くのは、256段階で128の値として定義した指数の基準値のピクセルシェーダで読み込まれたときの値が0.5だからです。}今回のプログラムでは、HDR画像を環境マップで使います。スフィア環境マップでHDR画像を読み込んで、あとはSchlickの近似によるフレネル項をかけてからLDRに戻して加算合成しました。ここで、NvやVvは、ビュー座標系での法線ベクトルや視線ベクトルです。座標系での視線ベクトルは、頂点の位置を考えない近似としてz軸と同一視できるので、その近似を利用して計算量を減らしています(きちんと計算しても、違いはよくわかりませんよ)。}なお、頂点シェーダプログラムは、次のようになります。BRDF」のプログラムに、ビュー座標系での法線ベクトルを追加したものになります。}なお、アプリケーションプログラムでは、下のような構文でテクスチャを読み込んで、あとは普通のテクスチャと同じように取り扱います。■最後にはぁ~、他人のプログラムを読むのは疲れますな。不完全なので、完全なプログラムに修正された方はどうぞください。あと、ガンマ補正とか露光補正を全然していないので、その点おかしいと思います。もどるimagire@nifty.com。