~下の画像をクリックすると、アニメーションが見られます。さんがいらっしゃいます。そちらのページでは、サブサーフェス散乱やシルエットエッジレンダリングのような興味深い研究が公開されています。その中でも特に興味を引いた研究はレリーフテクスチャに関しての研究でした。興味深いネタだと思います。今回は、DirectX9のパワーを利用して、逆ワーピング法でレリーフテクスチャを実装してみたいと思います。ちなみに、上の画像はポリゴンを1枚レンダリングしただけです。(レリーフテクスチャ:DirectX9)まぁ、いつものように適当にファイルが入っています。出力されるフレームワークのファイルは紹介を省かせていただきます。color.bmp:デカールテクスチャあと、実行ファイル及び、プロジェクトファイルが入っています。メッシュからリリーフテクスチャのための画像を作るためのプログラムも作ってみました。メッシュを読み込んで色、深度、法線ベクトルを表示します。左右のカーソルで見る方向を変えることができます。Screen」ないし、画面キャプチャで気に入った画像を取り出してください。最低限の機能ですが、現在表示されているテクスチャを保存する機能をつけました。MRTを3枚使っているので、動くかどうか保証できません。ご注意ください(駄目だったら報告をお願いします)。(セーブができない古いバージョン)■レリーフテクスチャとはレリーフテクスチャとは、深度マップを利用して比較的高速に立体的なオブジェクトをレンダリングする方法です。ずらしたテクスチャ座標によって、シーンをレンダリングします。すれたテクスチャ座標さえ求めることができれば、デカールのマップや法線マップから思うがままにレンダリングできることはすぐに分かると思います。平面的なポリゴンの板をレンダリングしますが、幾何学的に見た目が正しいレンダリング結果を出力します。そのテクスチャ座標で各種テクスチャをサンプリングします。具体的には、テクスチャを何枚ものレイヤーに重ねた状況を考えます。交差したUV値をデカールテクスチャなどのテクスチャ座標としてサンプリングします。これ以外の方法としては、前方ワーピング法と呼ばれる方法があります。3次元空間に置かれたポリゴンの位置情報と深度からレンダリングターゲットの位置座標を調べて、レンダリングします。現在のプログラマブルシェーダのアーキテクチャでは、直接的なハードウェアの支援は難しいものとなっています。ポリゴンからはみ出した部分は掛けてしまうので、取り扱いに注意が必要です。欠けることなくレンダリングできます。レリーフのような板を掘り込んだ画像しか作ることができません。奥に回りこんだ部分は再現できずに、奥に伸びた画像になってしまいます。斜めから見ると厚みが無い殻のオブジェクトに見えてしまいます。シェーダの説明だけにさせてもらいます。ちなみに、ポリゴンの板のローカル座標はのように、z=0平面上においています。テクスチャ座標は、今回、一回り大きめにとりました。しておくと、傾いたときに切り落とされる部分が少なくなります。特殊な視線ベクトルを出力します。}今回の視線ベクトルは、いつもの視点へのベクトルを0.2倍して、z成分で割っています。z成分が0.2の視線方向へのベクトルになっています。この視線ベクトルは、手前のレイヤーから、奥のレイヤーまでの視線ベクトル方向の変位ベクトルになります。射影空間とテクスチャ座標系の間で向きが違うy軸をひっくり返しておきます。ちなみに、0.2fという視線ベクトルに掛けた値は適当です。このスケールの値は、レリーフの厚みになります。視線ベクトルは、テクスチャ座標系でもワールド座標系と同じ傾きで進むと適切なレンダリング結果が得られます。スケールの値を1.0fにすると、正しい結果が得られます。スケールの値を1.0fに書き換えてレンダリングすると、のレンダリング画像が得られます。「カプセル状」の結果が得られることになります。正しいスケールを与えていることの検証になります。奥に伸ばすとサンプリングしたレイヤーが見えてしまいます。作成したテクスチャをさらに深度比較しながら合成する方法で解決できます。ピクセルシェーダですが、同じ関数をコピー&ペーストで実行する荒業を使っています。テクスチャ座標系を検索する座標値になります。最初は元のテクスチャ座標を検索して、その後は視線ベクトル方向に少しずつずらして、深度を検索します。深度テクスチャは「TexSamp」です。最終的に色をサンプリングするUV値に指定します。以降はUV値を上書きしないように設定しています。実際にプログラムしてみたら、命令数が増えてしまったので、今の形にしています。ちなみに、プログラムの上限はピクセルシェーダの命令数になります。ps.2.0+ではより多くの命令がつかえるので、さらに多くのレイヤーを使って分解能を高くできるでしょう。最後に求めたUV値で色テクスチャを読み込んで表示します。何所にも衝突しなかったピクセルはアルファ成分に0を代入して透明にして表示しています。2パス目で色々な加工をする手もありだと思います。}■より分解能の高いレンダリングps.2.xを使えば、より精度の高いレンダリングが可能なはずです。ソフトウェア実行で)分解能をテクスチャの分解能と同じ256段階で実行するプログラムは、次のようになります。}このプログラムは、上のほうにある画像のティーポットのレンダリングに使っています。プログラムを組んでみました。前出したツールで作った深度マップと法線マップとデカールマップを6面体に張り合わせてそれぞれリリーフテクスチャマッピングを施しました。照明計算はランバート拡散です。下のファイルが6面使うレリーフテクスチャマッピングのサンプルソースです。元になった深度マップをそのまま貼り付けた6面体を見てみましょう。これがあたかも立体に見えるのですからすごいものです。それがあっても結構まともに見えています。すべての向きでこのようにきれいに見えるわけではありません。上ですでに述べていますが、原理的には、直方体しか厳密に再現できません。埋められてしまいます。このモデルの場合には、上から見ると髪の毛が出っ張っているために顔がなくなってしまいます。それ以外にもトラのモデルを使えば、足の間が埋まってしまったりします。遠くから見てごまかすときにしか使えなさそうです。1」に書き換えればすぐに256枚のレイヤーで表示できます。あっ、REFで実行するのを忘れずにね)。10枚のレイヤーを使った時には次のようになります。見れたものではないですね。50枚以上のレイヤーは欲しいところです。ちなみにプログラムは次のアセンブラになります。};今回のプログラムはHLSLでは10枚のレイヤーを使うプログラムがコンパイルできなかったので、手でアセンブルしました。奥のレイヤーから深度マップの値がそのレイヤーの深度よりも前にあるか比較しながらテクスチャ座標を検索しました。最終的にこの値が変化していないかどうかで視線がモデルを貫いているかどうかチェックします。値が変化していないときは、アルファ成分に0を入れて、線形補間で透明にしています。今回苦労したのは、順序従属テクスチャでした。使えないというやつです。多くのテクスチャを読み込むときにはどうしても前に使ったレジスタを使い回さざる終えなくなります。すると順序従属テクスチャの制限に引っかっりやすくなります。この部分は、あまりやりたくないレジスタの組み合わせのパズルの悪夢が残っていますが、がんばってアセンブルしてパフォーマンスをあげましょう。いれば関係ありません。それまで待つのもひとつの手です。今回は、5個のtexldを同時にして、10個の一時レジスタを使うのを2回おこない、後は法線マップやデカールの読み込みにもう一段の順序従属テクスチャ読み込みを使っています。あと、最後のほうの部分は、ピクセル単位のランバート拡散なので、難しくないでしょう。それぞれのテクスチャに応じて違います。90度だけ適当な方向に回せばよいです。この方向は、テクスチャを作ったときのビュー行列から求まります。今回は、ポリゴンとテクスチャ座標をぴったりとあわせてレンダリングします。それ以外には、ライトの方向をモデルのローカル座標系で渡すのを忘れないようにしましょう。);■最後に思った以上に高速にレンダリングできますね。実は実用的なのかもしれません。1つの手法として確立されるのではないでしょうか。動かして見たいですね。もどるimagire@gmail.com。