前回ピクセル単位で、半透明のソートを行うシェーダーを作成しました。
Direct3D 10 ShaderModel4.0 ピクセル単位の半透明ソートを行う
Direct3D 10 ShaderModel 4.0 半透明ソート補足

レンダリング時にはカラー値をためておくだけにして、最後にシェーダーで
一気に Z ソートして合成をかけます。

そのため常に順番が正しく描画されることと、ピクセル単位なので交差
しようが自分自身と重なろうが、描画が矛盾しないという特徴があります。

他にも、最後の Blend をシェーダーで求めているため、通常のハードウエア
Blend だけでは表現できない複雑かつ高度な半透明合成ができるという利点も
あります。

今回はその点に着目して偏光板を作ってみました。

polarization shader

単純な板なので、実際に走らせて動いているところを見ないと少々わかり
にくいかもしれません。ダウンロードは下記からどうぞ。

wheelhandle_ss11t.zip

[SPACE]    pauge 一時停止
[U]        + Plane 追加
[D]        - Plane 削除
[Up]       camera up
[Down]     camera down
[Left]     rotate
[Right]    rotate

今回シミュレートしているのはあくまで偏光板同士の透過率の変化です。
背景画像など、一般の映像をカメラなどの偏光フィルターを通した場合の
表現ではない点にご注意ください。


この偏光板シェーダーは、透明度として Alpha の代わりに Tangent Vector を
用います。
ソートのあと、順番に Blend 合成するときに 2枚の偏光板同士の位相に応じて
透明度が変化します。

  TV  = Tangent Vector
  Tr  = Transparency

  blendf= saturate( 1.0f - abs( dot( TV[i-1], TV[i] ) ) * Tr )

透過度の最大値を Tr で与えています。0 または 180度で透過度が最大と
なり、90度ずれると 0% になります。

上記のように、2ピクセル間の関連性でのみ透過度を求めます。そのため、
2枚重なったエリアよりも 3枚以上重なったエリアの方が透過度が上がる
(明るくなる)ことがあります。

例えば A と C が 90度ずれている場合透明度は 0% で真っ黒になります。
ところが間に 45度ずれた B を挿入すると透過度が上がります。

A --------90--------- C   0%

A ---45--- B ---45--- C   50%

A と C の間は真っ黒なのに、B など斜めの板が重なってるエリアは
明るくなっているのがわかるでしょうか。(Aが手前、Cが奥です)

polarization shader

これは現実の偏光板でも起こる正しい現象のようです。

パラメターが増えたために、MRT は 6 枚使っています。
フレームバッファ 1pixel 96byte もあります。

データがただの板でわかりにくいですが、ソートされているのでカーソルキー
左右で回転などしても大丈夫です。ちなみに板の裏面は色つきです。