<HEAD>
<TITLE>W-Buffering</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</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>98/06/25（木）　</I></B></FONT>
<FONT SIZE="4"><B>− W-Buffering − DirectX6の新概念の謎</B></FONT>
<P>
<DD>
　<FONT COLOR ="#FF9090">DirectX6</FONT>には、
<FONT COLOR ="#FF9090">清3Zさんのページ</FONT>でも紹介されているように、
さまざまな新機能が採用されている。
この中新機能の１つに、
<FONT COLOR ="#FF9090">W-Buffering（W バッファリング）</FONT>
というものがある。
DirectX5までの<FONT COLOR ="#FF9090">Zバッファ</FONT>では、
単純にZ座標をそのまま整数（の範囲に）に
変換してZテストしていた。
<FONT COLOR ="#FF9090">Wバッファ</FONT>とは、このテスト用のZ座標を
<FONT COLOR ="#FF9090">
1 / Z</FONT>
で計算するというものである。
<P>
　何故こうするのか、理由は簡単である。
こうした方が<FONT COLOR ="#FF9090">
Zテストの精度が向上する</FONT>からだ。
ディスプレイ座標に変換された頂点座標は、
<FONT COLOR ="#FF9090">遠くにあるもの程小さく</FONT>なっている。
従来のDirect3Dの計算方法では、
<FONT COLOR ="#FF9090">
遠くにあってほとんど大きさを持たないような座標にも、
手前の方にある大きな座標にも同じZ座標の精度を持たせている。</FONT>
このため、<FONT COLOR ="#FF9090">
遠くは不必要に精度が高く、視点近くでは精度が足らない</FONT>という状況に陥っていた。
しかし、このWバッファの計算方法では、Zテストに使用するZ座標の精度は、
<FONT COLOR ="#FF9090">
ディスプレイ座標のサイズに比例する</FONT>
ため、このような事態を防げるのである。
<BR>
　Wバッファの採用には、もう１つメリットがある。
それは、Zテストに使用するZ値の計算誤差を軽減できるはずだからである。
こちらは意外と話に出ないので、簡単に説明しよう。
<BR>
　グラフィックスハードウェアは、与えられた頂点を結び、ポリゴンを描画する。
与えられる座標には<FONT COLOR ="#FF9090">Z値も含まれており</FONT>、
これでZテストを行い、<FONT COLOR ="#FF9090">隠面消去</FONT>を実行する。
このZテストは当然<FONT COLOR ="#FF9090">ピクセル単位で行う必要がある</FONT>ため、
ハードウェアは、与えられた頂点座標から、
<FONT COLOR ="#FF9090">ピクセル単位でz値を計算する</FONT>必要がある。
<BR>
　通常このZ値は、<FONT COLOR ="#FF9090">線形補間</FONT>で求めているはずである。
ところが、もう気付かれた方もいらっしゃると思うが、
これでは<FONT COLOR ="#FF9090">正確なZ値は求まらない</FONT>のである。
<BR>
　ディスプレイ座標の求め方は、簡単に書くなら
<P>
<CENTER>
<FONT COLOR ="#FF9090" SIZE="5">
dx = x / z<BR>
dy = y / z<BR>
</FONT>
</CENTER>
<P>
である。
ただし、<FONT COLOR ="#FF9090">dx, dy がディスプレイ座標、x, y, z が視点座表系での頂点座標</FONT>だ。
従来のZバッファでは、さらに
<P>
<CENTER>
<FONT COLOR ="#FF9090" SIZE="5">
dz = z<BR>
</FONT>
</CENTER>
<P>
となる。
x, y 座標をzで割っているのは、まあ
<FONT COLOR ="#FF9090">
「２倍の距離にあるものは１／２の大きさに見える」
</FONT>
と単純に考えてもらえば解りやすいだろう。
<BR>
実はこの式は、<FONT COLOR ="#FF9090">
三次元的に見たときポリゴンが曲面になる</FONT>可能性がある。
まあ当然と言えば当然で、
<BR>
<FONT COLOR ="#FF9090" SIZE="5">
dx = x / z
</FONT>
<BR>
などとzで割ったものは、z値によって
<FONT COLOR ="#FF9090">反比例のグラフ</FONT>を描くような
座標系になるからである。
<BR>
　ところが、zの計算にWバッファの計算式を使うと、つまり、
<P>
<FONT COLOR ="#FF9090" SIZE="5">
<CENTER>
dx = x / z<BR>
dy = y / z<BR>
dz = 1 / z<BR>
</CENTER>
</FONT>
<P>
で計算すると、座標系の直線が保持できるのである。
<BR>
　では、曲面だと何が問題になるのだろうか？
<BR>
　それが実は先程述べた、
<FONT COLOR ="#FF9090">
ピクセル単位のz値を頂点座標からの線形補間で求められない
</FONT>
ということなのである。
<FONT COLOR ="#FF9090">
曲面の座標を線形補間で正しく計算する事ができない</FONT>のは自明である。
<FONT COLOR ="#FF9090">
パースペクティブコレクション</FONT>のように、
<FONT COLOR ="#FF9090">ピクセル単位での透視変換が必要</FONT>になってしまう。
<P>
　ところで、Zテストを行うのは<FONT COLOR ="#FF9090">
ハードウェア</FONT>だが、頂点のZ座標をハードウェアに
与えるのは<FONT COLOR ="#FF9090">ソフトウェア</FONT>である。
何が言いたいのかというと、
<FONT COLOR ="#FF9090">Direct3DのIM（イミディエイトモード）</FONT>を使い、
<FONT COLOR ="#FF9090">
1/z を元に計算した値</FONT>をディスプレイ座標のz値として渡してやれば、
別に<FONT COLOR ="#FF9090">DirectX5以前</FONT>
でも、このような処理は可能だということである。
<BR>
　また、<FONT COLOR ="#FF9090">
OpenGL</FONT>では、
<FONT COLOR ="#FF9090">
初めから1/zを元にする仕様となっている。</FONT>
何故いまさら<FONT COLOR ="#FF9090">新機能</FONT>
としてWバッファなどと言い出したのか、
これまで納得いかなかった。
もう１つ、Wバッファには、
<FONT COLOR ="#FF9090">ハードウェアの対応が必要</FONT>ということもである。
上にも書いたように、ソフトウェア側の計算方法の見直しだけで済むはずなのに、
<FONT COLOR ="#FF9090" SIZE="5">
「なんでやねーん」</FONT>
などと思っていたのだが、最近<FONT COLOR ="#FF9090">清3Zさん</FONT>に、
その謎の答えを頂いた。
<BR>
　分かってしまえば別になんと言う程のことでもなく、実は、
<FONT COLOR ="#FF9090">DirectX6のWバッファ</FONT>
というのは、Zテストそのものを、
<FONT COLOR ="#FF9090">浮動小数点で行う</FONT>のだそうだ。
確かに、浮動小数点を使うというのは今までになかったから
<FONT COLOR ="#FF9090" SIZE="5">「新」</FONT>だし、
当然<FONT COLOR ="#FF9090">ハードウェアの対応が必要</FONT>である。
<P>
　しかし、DirectX5まででは、Zバッファというのは、
かなりいい加減な計算方法だったことになる。
よくこれで不具合が出なかったものだと、妙に感心してしまった。
</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>
