コンピュータグラフィックス:理論(4)(抜粋)
レンダリング(1)
数学的基礎
ベクトルの内積(dot product) と外積(cross product)
ベクトル
$ \overrightarrow{v_1} = \begin{pmatrix}x_1 \\ y_1 \\ z_1 \end{pmatrix} $
,
$ \overrightarrow{v_2} = \begin{pmatrix}x_2 \\ y_2 \\ z_2 \end{pmatrix} $
のなす角を$\theta$とすると、
内積
$ \overrightarrow{v_1} \cdot \overrightarrow{v_1}
= x_1 x_2 + y_1 y_2 + z_1 z_2 = |\overrightarrow{v_1}| |\overrightarrow{v_2}| \cos\theta
$
,
外積
$ \overrightarrow{v_1} \times \overrightarrow{v_1}
= \begin{pmatrix} y_1 z_2 - z_1 y_2 \\ z_1 x2 - x_1 z_2 \\ x_1 y2 - y_1 x_2 \end{pmatrix}
\equiv \overrightarrow{v_3}
$
$\quad\quad\quad$計算方法
$\overrightarrow{v_3} $ は「
$\overrightarrow{v_1}$ が $\overrightarrow{v_2}$ の方向を向くように回転させたとき右ねじが進む方向 」
のベクトルであり、大きさは「$\overrightarrow{v_1}$ と $\overrightarrow{v_2}$が作る平行四辺形」の面積と等しい。
$|\overrightarrow{v_3}| = |\overrightarrow{v_1}| |\overrightarrow{v_2}| \sin\theta $
$\overrightarrow{v_3} \cdot \overrightarrow{v_1} = 0 \quad , \quad \quad
\overrightarrow{v_3} \cdot \overrightarrow{v_2} = 0 $
証明
$\displaystyle
\begin{eqnarray}
\overrightarrow{v_3} \cdot \overrightarrow{v_1} & = & (y_1 z_2 - z_1 y_2)x_1 + (z_1 x_2 - x_1 z_2) y_1 + (x_1 y_2 - y_1 x_2) z_1 \\
& = & x_1 y_1 z_2 - x_1 y_2 z_1 + x_2y_1z_1 - x_1y_1z_2 + x_1y_2z_1 - y_1x_2z_1 \\
& = & 0 \\
\overrightarrow{v_3} \cdot \overrightarrow{v_2} & = & (y_1 z_2 - z_1 y_2)x_2 + (z_1 x_2 - x_1 z_2) y_2 + (x_1 y_2 - y_1 x_2) z_2 \\
& = & x_2 y_1 z_2 - x_2 y_2 z_1 + x_2 y_2 z_1 - x_1 y_2 z_2 + x_1 y_2 z_2 - x_2 y_1 z_2 \\
& = & 0 \\
\end{eqnarray}
$
$|\overrightarrow{v_3}| = |\overrightarrow{v_1}| |\overrightarrow{v_2}| \sin\theta $ を証明する。
ベクトル
$ \overrightarrow{v_1} = \begin{pmatrix}x_1 \\ y_1 \\ 0 \end{pmatrix} $
,
$ \overrightarrow{v_2} = \begin{pmatrix}x_2 \\ y_2 \\ 0 \end{pmatrix} $
とおいても一般性能は失われない。このとき
$ \overrightarrow{v_3} = \begin{pmatrix}0 \\ 0 \\ x_1 y_2 - y_1 x_2 \end{pmatrix} $
$ \overrightarrow{v_1}$ と
$ \overrightarrow{v_2}$ のなす角を $\theta$ とすると、
$\displaystyle
\begin{eqnarray}
|\overrightarrow{v_1}| |\overrightarrow{v_2}| \sin \theta & = & |\overrightarrow{v_1}| |\overrightarrow{v_2}| \sqrt{1-\cos^2 \theta} \\
& = & |\overrightarrow{v_1}| |\overrightarrow{v_2}| \sqrt{1- \left( \frac{\overrightarrow{v_1} \cdot \overrightarrow{v_2}}{|\overrightarrow{v_1}| |\overrightarrow{v_2}|} \right)^2 } \\
& = & \sqrt{|\overrightarrow{v_1}|^2 |\overrightarrow{v_2}|^2 - (\overrightarrow{v_1} \cdot \overrightarrow{v_2})^2} \\
& = & \sqrt{(x_1^2 + y_1^2)(x_2^2+y_2^2) - (x_1 x_2 + y_1 y_2)^2} \\
& = & \sqrt{x_1^2 x_2^2 + x_1^2 y_2^2 + y_1^2 x_2^2 + y_1^2 y_2^2 - (x_1^2 x_2^2 + 2 x_1 x_2 y_1 y_2 + y_1^2 y_2^2)} \\
& = & \sqrt{x_1^2 y_2^2 - 2 x_1 x_2 y_1 y_2 + y_1^2 x_2^2} \\
& = & \sqrt{ (x_1 y_2 - y_1 x_2)^2} \\
& = & |x_1 y_2 - y_1 x_2| \\
& = & |\overrightarrow{v_3}|
\end{eqnarray}
$
概要
「レンダリング」とは
「コンピュータ内部に記述された形状データから2次元デジタル画像を生成する処理」
のことである。光の物理的な性質に基づいて描画を行うことで写実的な画像を生成できる。
写実表現のレベル
3次元物体を2次元画像として表示する。
カメラで実際の物体を撮影したときに得られるような
写実的な画像を生成するフォトリアリスティックレンダリング手法が開発されてきた。
- ワイヤーフレーム(線画),デプスキューイング(遠くの線の輝度を落とす), 隠線消去 (見えない線の消去)
- 隠面消去&シェーディング(陰影づけ)、影つけ、テクスチャ(物体表面の模様)の付加
リアリティの要素
- 遠近感
- 可視面の表示
- 陰影と影つけ
- 物体の材質
- 表面の滑らかさ
- 反射光の計算
- スムーズシェーディング(滑らかな陰影つけ)
- バンプマッピング(表面の微細な凹凸の表現)
- テクスチャマッピング (表面の詳細な模様の表現)
写実的表現のためのモデリング
3次元モデルの幾何学的形状だけでなく、物体の材質や
表面の滑らかさなどの物理的な属性も重要である。
複雑なシーンについてリアルな画像を生成するには、適切なモデリングと
レンダリング手法を組み合わせることが必要となる。
- 物体表面の反射率、RGBごとの反射率、拡散反射率、鏡面反射率
- 金属表面や透明物を表示する場合には、表面の粗さ係数や屈折率が必要となる。
- 物体表面の反射特性である BRDF (双方向反射分布関数) を使うと、より一般化された反射を扱うことができる。
レンダリングを構成する処理
陰面消去
バックフェースカリング
バックフェースカリング (back-face culling) は、陰面消去の前処理で、
視点から不可視となる裏面を除去する処理のことである。
面の法線ベクトル $\vec{N}$ と視線方向ベクトル $\vec{V}$ のなす角度が、鋭角のときは可視(表面)、
鈍角のときは不可視(裏面)と判断する。
ベクトルの内積 $\vec{V}\cdot\vec{N}$ で計算できる。
$\vec{V}\cdot\vec{N} = |\vec{V}| |\vec{N}| \cos \theta$
視線方向ベクトルと法線ベクトル
視線方向ベクトル V は、面を構成する任意の頂点
$\vec{P_i}$
から視点
$\vec{P_E}$
へのベクトルなので
$\vec{V} = \overrightarrow{P_i P_E} = \vec{P_E} - \vec{P_i}$ となる。
物体を構成する凸ポリゴンの頂点は、物体を外側から見て反時計回りに番号付けされているものとする。
ポリゴンの任意の3頂点を$P_i$, $P_j$, $P_k$ (ただし$i \lt j \lt k$)を用いて、
法線ベクトル $\vec{N}$ は次の式で計算できる。
$\vec{N} = \overrightarrow{P_j P_i} \times \overrightarrow{P_k P_j}
= \overrightarrow{P_i P_j} \times \overrightarrow{P_j P_k}$
2つのベクトルの外積とはつぎのような計算である。
$
(x_0,y_0, z_0) \times
(x_1,y_1, z_1)
=
(
y_0 * z_1 - y_1 * z_0
,
z_0 * x_1 - z_ 1 * x_ 0
,
x_0 * y_1 - x_1 * y_0
)
$
隠面消去法
- 物体空間アルゴリズム (object space algorithm) --- 3次元で陰面消去の判定を直接行う方法
- 画像空間アルゴリズム (image space algorithm) --- 物体が投影されるスクリーン状のスキャンラインやピクセル単位で陰面消去の処理を行う方法(スキャンライン法、Zバッファ法、レイトレーシング法)
- 優先順位アルゴリズム (priority algorithm) --- 面の可視性の優先順位に基づいて陰面消去を行う方法
Zバッファ法
Zバッファ法 (Z-buffer algorithm) は、画素ごとに奥行きの判定を行い
隠面消去を行う方法。
フレームバッファ (画像の画素の色を格納する)と同じ解像度の
Zバッファ (奥行きであるz座標を格納する。デプスバッファとも言う)
を設ける。
ポリゴンの奥行き(z値)の計算
- ポリゴンの法線ベクトル
$\vec{N} =(n_x, n_y, n_z)$ 、
ポリゴンのいずれかの頂点を
$\vec{P_i} = (x_i, y_i,z_i)$,
ポリゴンを含む平面上の点を
$\vec{P} = (x,y,z)$
とすると、
$\overrightarrow{P_i P} \cdot \vec{N} = 0$
これを成分で表すと
$n_x x + n_y y + n_z z - (n_x x_i + n_y y_i + n_z z_i) = 0$
。
-
$z = (-n_x x - n_y y + n_x x_i + n_y y_i +n_z z_i) / n_z$
すなわち、$x$が1だけ変化すると$z$は$-n_x / n_z$変化するだけなので、単なる加算で計算できる。
Zバッファ法の特徴
- Zバッファ用のメモリが必要となる。
- アルゴリズムが比較的簡単でハードウェア化しやすい。
-
メモリ価格の低下により、PC用の3次元グラフィックスハードウェア
GPUではZバッファ法が採用されている。
コンピュータグラフィックス:理論(5)(抜粋)
レンダリング(2)
シェーディング
光源によって照らされた、物体の面の明るさや色を求める際に、
光の物理手な性質や法則をシェーディングモデルに導入することにより、
リアルな画像を生成することができる。
シェーディングの基礎と概要
3次元CGにおいて、光の当たり具合によって濃淡が変化する部分の明るさを
計算して表示することを「シェーディング (shading) 」とよぶ。
他の物体や面によって光が遮られた領域には影 (shadow) ができる。
影を表示するには、影付け (shadowing) の処理が必要となる。
放射量と測光量
光は電磁波であり、エネルギーは放射によって伝播し、波長の違いは色として認識される。
光の物理エネルギーは放射量(radiant quantities)として、
人間の眼が感じる明るさは測光量(luminous quantities)として扱われる。
- 光束 --- 単位時間にある面を通過する放射エネルギー量が「放射束(radiant flux, radiant power)」。放射束を眼の感度のフィルタに適して見た量が「光束(luminous flux)」で
単位は lm (ルーメン)。
- 光度 --- 点光源のある方向への光度 (luminous intensity)は
光源位置を頂点とする単位立体角内に放射される光束。単位は cd (カンデラ)。
光源の空間への光度分布を表したものを配光特性 (luminous intensity distribution
charastics)という。
- 照度 --- 単位面積に入射する光束で単位は lx (ルクス)。
点光源の照度は光度に比例し、距離の2乗に逆比例する。
- 光束発散度 --- 単位面積から発散する光束。単位は lm/m2
(ルーメン/平方メートル)
- 輝度 --- 反射面や発光面をある方向から見たとき、
その方向への光度を見かけの面積で割った値が輝度 (luminance)。
眼で見たときの明るさに相当する。
単位はcd/m2 (カンデラ/平方メートル)。
$\theta$方向の輝度$\displaystyle L_{\theta} =\frac{dI_{\theta}}{dS'} =\frac{dI_{\theta}}{dS \cos\theta}$
。どの方向から見ても輝度が等しい面を完全拡散面といい、法線方向の光度
$dI_{n}$
と$\theta$方向の光度
$dI_{\theta}$
との間にランバートの余弦則
$dI_{\theta} = dI_{n} \cos \theta$
が成り立つ。
シェーディングモデル
光源によって照らされた物体を表示するための物理モデルが
「シェーディングモデル(shading model, 照明モデル、ライティングモデルとも言う)」。
- 局所照明モデル --- 直射光に関して照明計算を行う
- 大域照明モデル --- 間接光まで含めて照明計算を行う。
光源の種類には平行光線、点光源、線光源、面光源がある。
光と物質の相互作用で光は分類できる。
- 直接光 --- 光源から出た光が他の物質と相互作用をせずに直接被照面に到達する光。
- 間接光 --- 光源から出た光が一旦他の物質と相互作用を起こしてから、被照面を照らす光。
- 反射光 --- 物体表面で反射、または物体表面から入った光が物体内で
多重散乱した後に表面に出てきた光。
拡散反射成分(面をどの方向から見ても輝度が一様となる反射。
強さは光源の位置と面の法線に依存する)と
鏡面反射成分(正反射方向に近づくほど強くなり、面を見る方向によって輝度が変化する)からなる。
- 透過光 --- 物体を通過した光
- 散乱光 --- 微粒子によって散乱された光
環境光
「環境光(ambient light)」とは間接光を非常に大まかに近似したもので、
周囲からくる一様な光である。
環境光に照らされた物体面の反射光の強さ$I$ は
$k_a$を環境光に対する反射率、
$I_a$を環境光の強さとすると
$I = k_a I_a$
となる。環境光は陰や影の領域にもある程度の明るさを与えるために
用いられる。
間接光を精度良く計算する手法に「ラジオシティ法 」がある。
拡散反射
「拡散反射 (diffuse reflection)」とは、
入射した光が物体内部の浅い部分で多重散乱したあと、表面から放射された
光である。
石膏やチョークの表面での反射のように、どの方向から見ても物体面の
輝度が一定となる反射である。
- 平行光線
面の輝度は視線方向には依存せず、平行光線の入射角の $\cos \alpha$ に比例する。
面の拡散反射率を $k_d$ ,
入射光の強さを $I_i$,
面の法線ベクトルと入射光のなす角を $\alpha$ とすると、
拡散反射光の強さ $I$ は
$I = k_d I_i cos \alpha$
- 点光源
光が光源から放射状にひろがるため、光の強度は光源からの距離の2乗に反比例する。
面の拡散反射率を $k_d$,
点光源の光度を $I_q$,
光源から点Pまでの距離 $r$、
面の法線ベクトルと入射光のなす角を $\alpha$ とすると、
拡散反射光の強さ $I$ は
$\displaystyle I = \frac{k_d I_q}{r^2} \cos \alpha$
鏡面反射
「鏡面反射 (specular reflection)」は、物体表面での直接反射によって生じた光である。
金属表面などでは、鏡面反射によりハイライト (highlight)を生じる。
入射角と等しい反射角となる正反射方向に強く反射される。
鏡面反射の計算よく用いられる「フォンのモデル」では、
視点方向と正反射方向のなす角 γ により、鏡面反射成分を
cos n γ
で減少させる。
入射光の強さを $I_i$,
視線方向と正反射光のなす角を γ ,
面の鏡面反射率を $W(\alpha)$ とすると、
鏡面反射光の強さ $I$ は
$I = W(\alpha) I_i \cos^{n}\gamma$
となる。
入射光の波長によって鏡面反射律は異なるが、通常は一定値として計算することが多い。
より精密なモデルである
「ブリンのモデル」では、「面を微小な完全鏡面反射面の集まりと考えて、その微小な面の
法線を特定の分布にしたがって設定する」。
さらに改良した
「クック・トランスのモデル」では、
反射率が光の波長に依存することや、反射率分布の入射角に依存することを
考慮して計算する。
スムーズシェーディング
曲面を小さなポリゴンで近似して表示を行うことが多い。
- コンスタントシェーディング (constant shading) ---
ポリゴンの代表点での
明るさを用いてポリゴン全体を一定の明るさで表示する。
マッハバンド効果 (Mach band effect)のため、人間は実際よりも輝度差を
大きく感じてしまうので、ポリゴン間の輝度の変化が滑らかに感じられない。
-
スムーズシェーディング (smooth shading) --- ポリゴン内の輝度を補正して
近似的に滑らかな明るさの表示を行う。
- グローシェーディング (Gouraud shading) --- ポリゴンの各頂点の輝度をバイリニア補間する。
- フォンシェーディング (Phong shading) --- ポリゴンの各頂点の法線ベクトルを
バイリニア補間することで内部の点の法線を求め、それを用いて輝度を計算する。