<HEAD>
<TITLE>Fake Sphere Mapping</TITLE>
</HEAD>

<BODY BACKGROUND="../Image/Back2.GIF"
	TEXT="#E0E0E0"
	BGCOLOR="#191919"
	LINK="#90D0FF"
	VLINK="#4080D0"
	ALINK="#0000FF">

<BASEFONT SIZE="3"> <!-- FACE="ＭＳ Ｐ明朝"> -->

<BR>
<CENTER>
<FONT SIZE="7" COLOR="80FF80"><I>W-Buffering 3rd</I></FONT>
<P>
<P>
</CENTER>

<CENTER>
<IMG SRC="../Image/Bar2.gif" ALT "-------------------------------------------" width=100% height="8">
</CENTER>
<P>

<P>
<DL>
<DT>
<FONT SIZE="3" COLOR="#FFFF80"><B><I>2000/07/13（木）　</I></B></FONT>
<FONT SIZE="4"><B>− W-Buffering 3rd − すいませんウソ書いてました（大汗</B></FONT>
<P>
<DD>
　<A HREF="98-08-02.html">98.08.02 のコラム</A>で「謎は解けた？」とか
書いておきながら、実は大嘘を書いていました。
推測でモノを書くとロクなことになりませんね。
このコラムを読んでくださっている人も結構いらっしゃるようなので、
本来なら間違いが判った時にすぐ訂正すべきだったのですが、大変遅くなってしまいました。
<BR>
ていうか訂正が遅れたのは単なる手抜きでしかありません。
<P>
<CENTER>
<FONT COLOR="#FF80FF" SIZE="4"><B>大変申し訳ありません（大汗</B></FONT>
</CENTER>
<P>
　えぇと、そういう訳で気を取り直して結論から言おう。
<FONT COLOR="#FF80FF" SIZE="3"><B>W-Buffering</B></FONT>
とは、その名の通り<FONT COLOR="#FF80FF" SIZE="3"><B>デプステストにＷ値を利用する</B></FONT>
方法である。
<WBR>
ここで言うＷ値とは、
<FONT COLOR="#FF80FF" SIZE="3"><B>視野座標系から透視変換を行った後のｗ</B></FONT>
であり、
Direct3D の場合は視野座標系でのｚと等しい（仮に OpenGL で実装された場合は−ｚとなるだろう）。
ヘルプなどで透視変換行列を調べて確認してみよう。
また、以前
<FONT COLOR="#FF80FF" SIZE="3"><B>W-Buffering は浮動小数点で実装される</B></FONT>
という話も書いたが、
実際には
<FONT COLOR="#FF80FF" SIZE="3"><B>浮動小数点であるか否かは特に関係ない</B></FONT>（別問題である）ようだ。
<BR>
　さて、W-Buffering はｗ値（つまり透視変換前のｚ値）であるため、
<FONT COLOR="#FF80FF" SIZE="3"><B>
ラスタライズ段階での座標系（透視変換後のスクリーン座標）では、
ｗ値はｘ，ｙ値に対して非線形に変化してしまう</B></FONT>という性質がある。
スクリーン座標系でのｚ値による通常のデプステストでは、
ｘ，ｙ，ｚ値がすべて透視変換された後の値であるため、
ポリゴン内部のｚ値は頂点からの単純な線形補間によって求まる。
しかし、ｗ値を用いる場合、ピクセル単位での
<FONT COLOR="#FF80FF" SIZE="3"><B>パース補正</B></FONT>
が必要になるということを意味している。
このためリアルタイム処理では、
<FONT COLOR="#FF80FF" SIZE="3"><B>ハードウェアでの実装がほとんど前提</B></FONT>となる。
<P>
　さらに注意すべき点として、
<FONT COLOR="#FF80FF" SIZE="3"><B>ｗ値はｒｈｗ（ｗの逆数）から計算される</B></FONT>
ため、
自前で座標変換を行う場合は、
<FONT COLOR="#FF80FF" SIZE="3"><B>ｒｈｗに適切な値（１／ｗ）をセットしておく必要がある。</B></FONT>
さらに、
<FONT COLOR="#FF80FF" SIZE="3"><B>
デプステストに使われるｗの最大値（視点座標系でのファークリップ）は
プロジェクションマトリクスから計算される</B></FONT>
ため、
<FONT COLOR="#FF80FF" SIZE="3"><B>
自前で座標変換する場合もプロジェクションマトリクスをセットしておかなくてはならない。</B></FONT>
実際に必要な要素は一部なので、<BR>
matProj._43 = 0;<BR>
matProj._34 = 1;<BR>
matProj._44 = dvWNear; // not used（現在の実装ではニアクリップ値は使われない）<BR>
matProj._33 = dvWNear / (dvWFar - dvWNear) + 1;<BR>
だけで良い（nVIDIA の W-Buffering に関する資料より抜粋）。
<P>
　さて、従来のようなｚ値によるデプステストに対し、
ｗ値によるテストを行うメリットは何だろうか。
<WBR>
それは、
<FONT COLOR="#FF80FF" SIZE="3"><B>
ｚ値によるデプステストでは、Z-Buffer の精度を有効に活用することが難しい
</B></FONT>
ことに他ならない。
もっとも 24 bits や 32 bits といった大きな深度を持つ場合あまり問題になることはない。
問題になるのは 16 bits 程度の精度の低い Z-Buffer を使う場合である。
当然だが透視変換を行った座標は、視点から離れるほどサイズが小さくなる。
ピクセルの分解能が低くなることは一目瞭然であろう。
そしてこれと同じことはｚ値にも起こり、
<FONT COLOR="#FF80FF" SIZE="3"><B>
遠くの座標ほど Z-Buffer の分解能が低くなる。</B></FONT>
<BR>
　例えばニアクリップ面とファークリップ面との距離の比率が
<FONT COLOR="#FF80FF" SIZE="3"><B>100 倍</B></FONT>
ある場合、
ニアクリップ付近のポリゴンとファークリップ付近のポリゴンでは
画面上のサイズに 100 倍程の差が現れ、
<FONT COLOR="#FF80FF" SIZE="3"><B>
Z-Buffer の分解脳も同様に 100 倍程の差が現れる。</B></FONT>
ニアからファーまで、16 bits なら 65536 段階のｚ座標しか存在しないのに、
ニアとファーの位置で 100 倍の精度差が現れるのは、
かなり痛い現象であることがなんとなく判るだろう。
<BR>
　<FONT COLOR="#FF80FF" SIZE="3"><B>あくまで Z-Buffering </B></FONT>
でこの問題を回避（軽減）するためには、
なるべくニアクリップとファークリップの距離の比率を小さくするしかない。
具体的には、
<FONT COLOR="#FF80FF" SIZE="3"><B>ニアクリップをできる限り遠くに設定する</B></FONT>
ことだ。
距離の比率を小さくするにはこれが最も有効だからである。
<BR>
　考えれば容易に判ることだが、
<FONT COLOR="#FF80FF" SIZE="3"><B>Z-Buffering ではニアクリップと
ファークリップの距離の比率がほとんどそのまま精度に直結する。</B></FONT>
例えば ニア 10.0、ファー 100.0 に設定（ニアとファーの距離の比率が 10）した際のｚバッファ精度は、
ニア 0.01、ファー 100.0 に設定（比率 10000）した場合の精度と比較して 1000 倍以上にもなる。
何故なら、
<FONT COLOR="#FF80FF" SIZE="3"><B>
ニアを 0.01 にセットしている場合、Z-Buffer の全分解能の内 99.91% が
ニア（0.01）〜 10.0 までの間に割り当てられてしまう</B></FONT>
からだ。
逆に
<FONT COLOR="#FF80FF" SIZE="3"><B>
 10.0 〜ファー（100.0）の間には、全分解能の内 0.09% しか使えない。</B></FONT>
16 bits Z-Buffer では、10.0 〜 100.0 の間には実に
<FONT COLOR="#FF80FF" SIZE="3"><B>59 段階程度</B></FONT>
しか分解能が無いのである。
これでは表示が破綻して当然だ。
当たり前だが、ニアを 10.0 にセットしていれば、10.0 〜 100.0 の間に 65536 段階使える。
つまり、この違いだけで Z-Buffer 精度に
<FONT COLOR="#FF80FF" SIZE="3"><B>1111 倍</B></FONT>
もの差が出るのである。
<BR>
　しかし、ニアクリップ平面を遠くにするにも限界があるため、
場合によってはこの方法では対処しきれないことがある。
<P>
　このような場合に Z-Buffering の代わりに W-Buffering を利用する訳である。
<FONT COLOR="#FF80FF" SIZE="3"><B>
W-Buffer であれば近くも遠くも精度が同じになる</B></FONT>
ことから、
特にニアクリップの距離を気にしなくとも、遠くの描画が破綻することが無いからである。
</DL>

<!-- Signature -->
<FONT SIZE="3" FACE="ＭＳ Ｐ明朝">

<CENTER>
<IMG SRC="../Image/Bar2.gif" ALT "-------------------------------------------" width=90% height="16">
</CENTER>

<UL>
	<A HREF="index.html"><B><I>Masa's Column</I></B>に戻る</A>

	<TABLE>
	<TR>
	<TD>
	<A HREF="../index.html"><IMG SRC="../Image/MasaPlate.gif" BORDER="0" WIDTH="112" HEIGHT="48"></A>
	</TD>
	<TD><A HREF="../index.html">ホームページに戻る</A></TD>
	</TR>
	</TABLE>

	本ページの御意見・御感想は<BR>
<B>
<ADDRESS>
	<A HREF="mailto:masa@daionet.gr.jp">
		<I>E-Mail: masa@daionet.gr.jp</I></A>
</ADDRESS>
</B></UL>

</FONT>
<!-- Signature -->

</BODY>
