視錐台



簡単のためスクリーン=nearプレーンとされる。

nearのz値をN
farのz値をF
とすると

$$
\frac{x'}{x}=\frac{y'}{y}=\frac{z'}{z}=\frac{N}{z}
$$

である。ここで
(x, y, z)はパース変換すべき3Dモデルの頂点座標。
(x', y', z')はx, yを焼き付けたい平面上の座標であり、
焼き付けるべき平面がスクリーン(=nearプレーン)であるならば
(x', y', N)である。

であるからしてすなわち上述の式から

$$
x'=N\frac{x}{z}\\
y'=N\frac{y}{z}
$$


MAP

なにやら適当な数値を[min, max]範囲内において[0, +1]に収めることを考えると、その変換式は

$$
(value-min)/(max-min)
$$

戻す時は

$$
min + (max-min)*t \quad (0 \leq t \leq 1)
$$

[-1, +1]に収めるならば

$$
2*(value-min)/(max-min) - 1
$$

戻す時は

$$
min + (max-min)*\frac{(t+1)}{2} \quad (-1 \leq t \leq 1)
$$


ここで[0, +1]に収めるだの[-1, +1]に収めるだのは、
変換後の値を等間隔に出力させることを暗に意味している。
そういう等間隔に出力させるのは線形変換であって、1次関数の仕事である。

例えば

$${(value-min)/(max-min)}$$や$${2*(value-min)/(max-min) - 1}$$

の場合、

$$
value*A + B
$$

なる形に強引に変換できて、出力範囲が[0, +1]の場合、これが
value=min の時、出力0
value=maxの時、出力1
となれば良い訳だから

$$
min*A+B=0\\
max*A+B=1
$$

なる連立方程式が立つ。
これを解くと

$$
A=\frac{1}{max-min}\\
B=\frac{-min}{max-min}
$$

となって、

$$
value*A + B
$$

に戻すと

$$
(value-min)/(max-min)
$$

であることが分かる。


透視射影

参考
ゲームプログラミングのための3Dグラフィックス数学 単行本(ソフトカバー) – 2002/10/25 Eric Lengyel (著), 狩野 智英 (著)

ここでx', y' を[-1, +1]の範囲に収めることを考える。

$$
x''=(x'-left)\frac{2}{right-left}-1\\
y''=(y'-bottom)\frac{2}{top-bottom}-1
$$

x' やy' (スクリーン座標)をx, y (3Dモデルの座標)で表すと

$$
x''=\frac{2N}{right-left}(-\frac{x}{z})-\frac{right+left}{right-left}\\
y''=\frac{2N}{top-bottom}(-\frac{y}{z})-\frac{top+bottom}{top-bottom}\\
$$

ついでだから全部文字にすると

$$
x''=\frac{2near}{right-left}(-\frac{x}{z})-\frac{right+left}{right-left}\\
y''=\frac{2near}{top-bottom}(-\frac{y}{z})-\frac{top+bottom}{top-bottom}\\
$$

深度

ここでx' y' に対応付いたz' を考え、これを深度とみなす。

この深度という値は、あると便利だから作られる。また、便利なので深度の範囲は[-1,+1]や[0, +1]に収められる。

MAPの項で記述したとおり、素朴に線形に変換するのなら

$$
z'' = A * z' + B
$$

であり、

z' = -1 = min ,
z' = +1 = max

として連立方程式を立てれば良いのであるが、

$$
z'' = A * \frac{1}{z'} + B
$$

とすることが推奨される。便利だからである。

the reversed-Z mapping is basically magic.
(1/Z マッピングは魔法です)

NVIDIA DEVELOPER

1/zによる連立方程式は

$$
-1=\frac{A}{N}+B\\
1=\frac{A}{F}+B
$$

であるから

$$
A=\frac{-2FN}{F-N}
B=\frac{F+N}{F-N}
$$

ゆえに3Dモデルの頂点座標zに応じた深度z''は

$$
z'' = \frac{-2FN}{F-N}(\frac{1}{z})+\frac{F+N}{F-N}
$$

z'' を図示すると反比例のグラフを成す。

x' y' に対応付いていることが重要で、元々異なるx,y 座標値を持っていても、パース変換を経て、スクリーン座標上で同一のx' y' を有することがある。その場合、あらかじめz' を計算しておけば表示をするしないを選択できる。

この場合、スクリーン上の全てのピクセルにおいてz'値が比較テストされる。

まず、スクリーンのピクセル個分のデータ格納領域であるZバッファを用意する。これはプログラム的にはスクリーンのピクセル個分の要素を持つ配列あるいは2重配列であり、CPUなりGPUなりにハード的に実装されたメモリ領域であったりする。

スクリーン描画時に描画座標(x', y')に対応するz' 値を確認し、まだ何も描画されていないのであればz' を記録。すでにz' が記録されているならばz' を比較した後に描画座標(x', y')に描画するかしないかを決める。すなわち後ろに隠れている物は描画する必要がない。

元々のz値を使えないのか
おそらく使えると思われるが、利便性のために[-1, +1]あるいは[0, +1]の範囲に正規化されると思われる。

クリッピングも同時に行われる。
Zバッファ情報を用いてオブジェクトに影を付けることができる(シャドウマッピング)


陰面消去

Zソート(画家のアルゴリズム)

ポリゴンを後ろから順番に描画していく。
ポリゴン同士が交差している場合、ポリゴンを分割するなどの迂回策が必要となる。(Newell's algorithmなど)

Zバッファ(深度バッファ、デプスバッファ)

深度の項を参照。


この記事が気に入ったらサポートをしてみませんか?