--/--/--掲示板に質問があったので、集中線と波紋のエフェクトを紹介します。両方ともやっていることは大差なく、一度テクスチャにレンダリングした画像を変形させながら再レンダリングしているだけです。集中線は画像サイズを微妙に小さく(もしくは大きく)しながら複数回、半透明でレンダリングします。固定頂点で実装するなら、いわゆるフィードバックブラーの一種になるかと思います。厳密にはフィードバックしていないのですが、まぁ似たような絵にはなります。最後に漫画っぽく実線の集中線を書き込むとよりそれっぽく見えるかもしれません。波紋は画素毎の変位量をあらかじめ別テクスチャに書き込んでおいて、それをピクセルシェーダで適用しています。波紋以外にも様々な2D変位が簡単に実現できるので便利です。多少描画コストは高くなるかもしれません。いうわけで、今回のソースです。いつものことながら、エラーチェックは最低限であり、このサンプルの使用によるいかなる不幸も当方では責任を負いかねます。PS2.0以上必須です。--/--/--最近、3D業界ではHDR処理が流行っています。これをまともに扱うには浮動小数点バッファが必要です。D3DFMT_A16B16G16R16F、D3DFMT_A32B32G32R32Fといったフォーマットですね。ところが、このフォーマットDirectX9世代ではろくにサポートされていません。Geforce6シリーズより前では使うことすらできないですし、RadeonシリーズでもX1000より前のものではアルファブレンドやフィルタリングができないという困った制約があります。現在のようなカード依存の状況が緩和されると思われます。いえ、世代交代にあと数年はかかりそうです。今回のネタは、整数バッファでアルファチャンネルを使わずにグレア処理をやってみましょうという話です。DOUBLE-S.T.E.A.Lですっかり有名になったこの処理ですが、高輝度部の抽出に一工夫いります。こちらの資料を眺めてください。浮動小数点バッファを使わない場合、アルファチャンネルを使って、HDR処理をかける手が定番です。アルファチャンネルを使ってしまうと、アルファブレンドができなくなります。当たり前とはいえ、ちょっと不便です。高輝度部分は0,1のバイナリマスクで抽出できればいいや、と割り切ってみました。このマスクはBチャンネルの輝度Max近辺に保存します。輝度を[0:1]の範囲とすると、0.95(この値自体は適当なので、以下BMAXとする)までは普通に使って、そこで値をクリップします。輝度をBMAX以上の値にします。要は、BチャンネルにBMAX以上の値が入っている部分が高輝度部となります。BMAX〜1の間で明るさが変化したところで、ほとんど知覚できないので、そこにマスクを仕込んでしまえということです。ちなみにBチャンネルを使うのは、人間の目が青色に対して感度が悪いからという理由です。レンダリングのパスとしては、まずこのBMAXを境界にした高輝度部マスク付の画像を生成します。次に高輝度部のみを抽出した白黒のバイナリイメージを生成します。この結果にローパスフィルタをかけてぼかし、ぼかした結果を十字型に引き伸ばします。十字型になったぼけ画像(グレア)の結果は、毎フレーム半透明合成されます。この処理は簡易的なモーションブラーと同じです。グレアの元ネタがバイナリイメージなので、さすがに高輝度部の抽出精度が悪くなっています。時間方向のローパスであるモーションブラーをかけて、より自然に見せています。最後に、グレアをBMAXを境界にした画像に加算合成すれば完成です。基本的には前出の資料と同じやり方です。いうわけで、今回のソースです。いつものことながら、エラーチェックは最低限であり、このサンプルの使用によるいかなる不幸も当方では責任を負いかねます。PS2.0以上必須です。アルファチャンネルを使っていないので、アルファブレンドが可能です。四角のポリゴンにアルファチャンネル付のテクスチャを張って、丸くくりぬいています。過渡期的なアイデアですが、DirectX9世代でグレアを使う一手ということで。--/--/--以前ゲームを作ったときに使った、アナグリフ式立体視のお話です。アナグリフとか言うと難しく聞こえるので、赤青メガネ方式といった方が分かりやすいでしょう。赤いレンズ越しには、赤い絵が見えず、青いレンズ越しには青い絵が見えません。赤い絵と青い絵で表示すれば、眼鏡越しには立体画像として見えます。世間的には、赤青メガネといっていますが、良く見かけるのは左目が赤、右目がシアンの組み合わせです。シアンなのかというのは、こことかここのサイトをご覧ください。赤とシアンは補色の関係にあるからなんですね。プログラム上は、注視点を固定し位置を平行移動させたカメラを使って、2枚の画像をテクスチャにレンダリングします。片方の画像はRチャンネルだけ残し、GとBチャンネルは白く塗りつぶします。一方の画像はG,Bチャンネルを残して、Rチャンネルを白く塗りつぶします。この処理は、ピクセルシェーダで書くのが手っ取り早いです。赤一色で加算合成すればG,Bチャンネルが残ります。最後に2枚のテクスチャを加算合成してレンダリングすれば終了です。一意には決められません。適当に決めてしまいましょう。コンフィグで設定できるようにしておく方が無難かと思います。いうわけで、今回のソースです。いつものことながら、エラーチェックは最低限であり、このサンプルの使用によるいかなる不幸も当方では責任を負いかねます。固定頂点での実装です。現在米国滞在中につき、赤青メガネが手元にありません。そんな訳でちゃんと立体に見えるのか不安一杯なので、パラメータの調節は各自行ってください。--/--/--前回紹介したトゥーンシェードは、一般的な実装です。プログラマ的にはこれで問題ありませんが、野村XXは”一応”絵描きの端くれなので、あの絵は正直許せません。なんというか、生気に欠ける感じがしませんか?そんな訳で、ひと手間加えて、萌え具合を上げて見ましょう。先に、結果を出しておきます。左側が今回の結果、右側が前回の結果になります。如何でしょうか?陰の色が変わったことと、ハイライトが入ったことで、ずいぶん印象が変わったと思います。陰の色については、こちらのサイトさんが非常に面白い記事を出しているので、ご覧下さい。説明がHSVの色空間でされているので、なじみのない方には分かりづらいかもしれません。googleさんにでも聞きながら読んでみてください。前回の実装のように、シェーディングの成分を乗算すると、大雑把には色度は同じで輝度が落ちた絵になります。先の記事によると、色度も合わせて変化させなければなりません。ある色の物体に対して、どのような陰の色を与えれば、見栄えが良くなるのかということに関しては主観が入るので一概には言えません。この辺りは、絵描きのセンスですね。そこで、プログラム側としては陰の色は手動で設定してもらうことにします。シェーディング用テクスチャのU座標は濃淡に使っているので、V座標をマテリアル毎に使い分けます。肌色用の陰、髪の毛用の陰、服用の陰、etc...、と別々に陰の色を指定します。ソースに同梱のテクスチャを見ていただけるば、一目瞭然だと思います。マテリアル色をテクスチャにする、やっつけプログラムはこちらです。このプログラムで出力したbmpをベースに濃淡をつけると多少は作業がはかどるでしょう。ハイライトを追加します。ハイライト自体は固定頂点で言う所の、Phongモデルのスペキュラーをそのまま使っています。スペキュラーは鏡面反射のモデルなので、あまり強く使うと肌がテカテカになってしまいます。この辺も、要サジ加減ですね。いうわけで、今回のソースです。いつものことながら、エラーチェックは最低限であり、このサンプルの使用によるいかなる不幸も当方では責任を負いかねます。ピクセルシェーダ1.1必須です。ハイライトという構成は、いわゆる一枚絵のアニメ塗りでは定番です。少量のハイライトというケースがほとんどです。今回のようにモデルが動いているときに陰に2色使うと、結構くどい感じになりますね。--/--/--今回は、定番のトゥーンシェードです。いろんなサイトで既に実装例が出ているので、いまさら感がありますね。HLSLベースでモデルのテクスチャとマテリアルがちゃんと反映されているものが見当たらなかったので、ソースを公開しておきます。基本的なアイデアは、Microsoftのものと一緒です。2パスのレンダリングで3階調程度に塗り分けられたシェーディングと、輪郭線の表示を行います。使うのは頂点シェーダのみです。参考までにシェーディングの部分にはピクセルシェーダの実装も入れてあります。素直に固定頂点機能を使っておく方が幸せでしょう。シェーディングの原理は、あらかじめ3階調程度に塗ったテクスチャを用意し、モデルの法線ベクトルとライトの方向ベクトルの内積の値をテクスチャ座標にして、シェーディングの濃さを決めます。内積が1になるほど明るくなれば良いわけです。これをあらかじめu方向に濃淡を付けたテクスチャのu座標に適用すればOKです。シェーディング用に一枚テクスチャを使うので、モデルに張ってあるテクスチャを生かすためにはマルチテクスチャの設定が必要です。固定頂点ならSetTextureStageStateで設定し、ピクセルシェーダーならsamplerを2つ使います。マルチテクスチャについてはこちらが詳しいです。輪郭線を描く方法は、面をひっくり返したモデルを法線方向に拡大して黒塗りで表示するという定番の方法です。輪郭線の太さがモデルの距離に依存しないようにしています。これは単にモデルのwの値を拡大率にあらかじめ掛けておくだけです。wの値はパース補正に使われるので、これをキャンセルするわけです。アニメでは、輪郭線は均一の太さなのでこの方が自然に見えると思います。何らかのアンチエイリアシング処理を入れておく方が無難です。ハードウェアでFSAAをかけてしまうのが簡単ですね。輪郭線の太さと色を変えて複数回レンダリングするなりすると良いでしょう。いうわけで、今回のソースです。いつものことながら、エラーチェックは最低限であり、このサンプルの使用によるいかなる不幸も当方では責任を負いかねます。