動画の解説を参照
3D CGではたくさんの面 (ポリゴン) でいろいろな形を表現します。その際、「面に表裏を設定して裏側を描画しない」という決まりにしたがって描画すれば余計な処理をせずに済みます。
ポリゴンの面に垂直な方向は表・裏の2通りありますが、表方向を向いたベクトルのことを
法線ベクトルといいます。
法線ベクトルは、定義上長さが1でなくても構いません。
ここでは、規格化していない法線ベクトルを
\(\boldsymbol{n}\)
注目したいのは向きだけなので、多くの場合は長さを1にした、
規格化された法線ベクトル
\(\boldsymbol{n}_0\)
を使います。
表裏の判定には、カメラからポリゴンを向いたベクトルも必要になります。
例えば下の図のように (3, 0, 0) の位置にカメラ、(0, 0, 0) の位置にポリゴンがあるとき、
始点をカメラ、終点をポリゴンの中心とするベクトルは、
\(\boldsymbol{v} = (-3, 0, 0)\)
となります。これは
視線ベクトルといい、視線方向を表すものとして使えます。
この場合は、
規格化された視線ベクトルは
\(\boldsymbol{v}_0 = (-1, 0, 0)\)
こうなります。
視線ベクトルと法線ベクトルを使うと、カメラから見て面が表裏のどちらを向いているかを判定できます。
CGではこの判定結果に応じて、面が表を向いているときだけレンダリングすればいいことになります。
| \(\boldsymbol{v}\cdot\boldsymbol{n}\) |
面の向き |
描画の必要 |
| 正 |
裏 |
ない |
| 0 |
横 |
ない |
| 負 |
表 |
ある |
以下で \(\theta\) に -180 ~ 180 の範囲の数値を入れて「入力」を押すと面の向きが変わります。
赤矢印が規格化された視線ベクトル \(\boldsymbol{v}_0\)、青矢印が面の規格化された法線ベクトル \(\boldsymbol{n}_0\) です。
\(\theta=\)
\(\boldsymbol{v}_0\) = (-1, 0, 0),
\(\boldsymbol{n}_0\)
\(\boldsymbol{v}_0\cdot\boldsymbol{n}_0\)
→
動画の解説を参照
三角形の3つの頂点の座標が分かっていれば、その面の法線の方向を求めることができます。
三角形の表・裏は2通り考えられますが、よく使われる向きの基準として「頂点に1~3の番号を振って、1から3の順に見たときの右ネジの向きを法線の方向 (表側) とする」というものがあります。
この授業でもその基準を採用することにします。
頂点1から
頂点2に向かうベクトルを
\(\boldsymbol{a}\),
頂点1から
頂点3に向かうベクトルを
\(\boldsymbol{b}\)
とすると、まさに \(\boldsymbol{a}\times\boldsymbol{b}\) がこの三角形の面の法線ベクトルになります。
\(\boldsymbol{n}=\boldsymbol{a}\times\boldsymbol{b}\)
3つの頂点の座標を \((x_1, y_1, z_1), (x_2, y_2, z_2), (x_3, y_3, z_3)\) とすると、\(\boldsymbol{a}\), \(\boldsymbol{b}\)
の成分はこのようにして求められます。
\(
\begin{eqnarray}
\boldsymbol{a} &=& (x_2-x_1, y_2-y_1, z_2-z_1)\\
\boldsymbol{b} &=& (x_3-x_1, y_3-y_1, z_3-z_1)
\end{eqnarray}
\)
以下に座標 (-5~5の整数) を入れて「入力」をクリック (タップ) すると
図の三角形が更新されます。水色の線がこの三角形の規格化された法線ベクトル \(\boldsymbol{n}_0\) です。
頂点1の座標
(
,
,
)
頂点2の座標
(
,
,
)
頂点3の座標
(
,
,
)
動画の解説を参照
今回見た2つのテクニックを組み合わせれば、カメラから見て三角形が表か裏か、つまり描画すべきかどうかを判定できます。
今回の第1項の図では四角形の中心、第2項の図では三角形の中心をポリゴンの位置としましたが、実は図形を含む面上のどの点をポリゴンの位置としても表裏の判定は同じになります。
つまり、面の裏表の判定だけが目的なら、「頂点1」「頂点2」「頂点3」「三角形の重心」のどれをポリゴンの位置としてもかまいません。
「頂点1」をポリゴンの位置として使うなら、カメラの座標を \((x_0, y_0, z_0)\) とすれば、視線ベクトルは
\(\boldsymbol{v} = (x_1-x_0, y_1-y_0, z_1-z_0)\)
で求められます。これと3つの頂点から求めた法線ベクトル \(\boldsymbol{n}\) との内積をとれば、その符号から描画の必要の有無を判定できます。