Skip to content

第11回 行列と座標変換1

前回: 第10回 スキンメッシュ基礎

前回の振り返り

ボーンとスキンメッシュの関係に触れました

  • 第10回では、スキンメッシュがボーンの動きに合わせて頂点を変形する仕組みを扱いました
  • ボーンは Transform の階層であり、親の変換が子に伝わります
  • バインドポーズでは、最初の姿勢を基準として保存し、現在のボーン姿勢との差分で頂点を動かしました
  • その背景には、位置、回転、スケールをまとめて扱う 行列座標変換 があります
  • 今回は、ローカル空間、ワールド空間、ビュー空間の違いを整理し、座標変換の流れを理解します

今回の授業内容

座標空間から変換まで、シェーダーで必須の基礎

  • 座標空間(Object、World、View、Clip、Screen)
  • Transform と行列の関係
  • スカラー、ベクトル、マトリクス、テンソル
  • 4x4 行列と同次座標
  • Model、View、Projection の変換パイプライン
  • 位置と方向の扱いの違い
  • Shader Graph での PositionTransform ノード
  • 座標空間の統一の必要性

座標空間とは

どの基準で位置を表すか

座標空間の変換の流れ
1つの頂点は Object から World、View、Clip へ変換され、最終的に画面上の位置に投影されます

  • 座標空間は、位置や方向を表すための基準です
  • 同じ座標でも、モデル自身を基準にするのか、シーン全体を基準にするのか、カメラを基準にするのかで値が変わります
  • 数値が異なっても、指している実際の場所が同じなら、それは別の座標空間で同じ点を表しているだけです

身近な例

教室内の位置と学校全体の位置

  • 机の位置を「教室の入口から右に2m、奥に3m」と表すことができます
  • 同じ机を「校舎の玄関から東に20m、北に15m」と表すこともできます
  • どちらも同じ机を指していますが、基準が違うため数値が違います
  • 3D CG の座標空間も同じで、どこを原点にし、どの向きを軸にするか が異なります

ローカル空間

モデル自身を基準にした空間

  • Local SpaceObject Space は、モデル自身を基準にした座標空間です
  • モデルの中心、向き、スケールを基準にして頂点位置を表します
  • 例えば同じ立方体をシーンの別の場所に置いても、立方体内部の頂点座標は同じです
  • モデルの形状やその変形を扱うときの依拠空間を基準にします

ワールド空間

シーン全体を基準にした空間

  • World Space は、シーン全体を基準にした座標空間です
  • Scene View のグリッドや、GameObject の Transform に表示される位置は、多くの場合ワールド空間の値です
  • オブジェクトを移動すると、ローカル座標は変わらないままワールド座標が変化します
  • 世界に固定された建造物、地形の高さ、ライトやカメラなどを扱う主な空間です

ローカルとワールドの違い

座標で作ったパターンがどこに固定されるか

ローカル空間とワールド空間の座標パターンの違い
Object Space の座標パターンはメッシュに貼り付き、World Space の座標パターンは空間側に固定される

  • ここでいうパターンは、画像テクスチャーではなく、座標値を色に変換して作る縞やグラデーションのことです
  • たとえば Position の X 成分を色に使うと、X 座標の値に応じた縞パターンを作れます
  • ローカル空間の座標からパターンを作ると、オブジェクトを動かしてもパターンは物体についてきます
  • ワールド空間の座標からパターンを作ると、オブジェクトを動かしたときにパターンの通る位置が変わります
  • どちらが正しいかは表現次第です
  • 物体に貼り付けたい色変化はローカル空間、地面を通るスキャンラインや空間ノイズはワールド空間の座標を使います

ビュー空間

カメラを基準にした空間

  • View Space は、カメラを基準にした座標空間です
  • カメラから見て右、上、奥の方向を基準に位置や方向を表します
  • カメラが動くと、同じワールド位置の点でもビュー空間での値は変わります
  • 視線方向、フレネル表現、カメラ距離フェード、depth-based エフェクトはビュー空間を使います

クリップ空間とスクリーン空間

画面に映すための空間

  • Clip Space は、3D の点を画面へ投影する直前の座標空間です
  • カメラの視野角、Near、Far、アスペクト比などが反映されます
  • Screen Space は、最終的に画面上のどの位置に描かれるかを表す空間です
  • ポストエフェクト、画面座標を使ったノイズ表現などではスクリーン空間が使われます

主な座標空間

何を基準にしているかで使い分ける

空間基準主な用途
Object / Localモデル自身頂点変形、物体に貼り付く色変化
Worldシーン全体ライト位置、空間ノイズ、高さ表現
Viewカメラ視線方向、カメラ距離、カメラ基準の表現
Clipカメラの投影後描画パイプライン内部、画面への投影
Screen画面ポストエフェクト、画面座標による表現
  • Shader Graph のノードには、どの空間で扱われるかを指定する Space が選択可能なものがあります
    例えば PositionNormal VectorView Direction などは、どの空間で扱うかを切り替えることができます

Transform とは

位置、回転、スケールをまとめたもの

Transform の構成要素

Transform は移動、回転、拡大縮小をまとめてオブジェクトの配置を決める

  • Unity の GameObject は Transform を持っています
  • Transform は、位置 Position、回転 Rotation、スケール Scale をまとめたものです
  • 親子関係がある場合、親の Transform が先に適用され、子の Transform がその上に重なります
  • 例えば末端のモデルのローカル座標に Transform を適用すると、親から継承されたワールド空間での位置と向き、大きさが決まります

スカラー、ベクトル、マトリクス、テンソル

数値要素を扱うためのデータ構造

スカラー、ベクトル、マトリクス、テンソルの比較

シェーダーでは、1つの数値だけでなく、複数の数値をまとめたデータを頻繁に扱う

種類シェーダーでの例
Scalar1つの数値時間、透明度、明るさ、しきい値
Vector数値の並び位置、方向、色、UV
Matrix行と列に並んだ数値座標変換、回転、スケール、投影
Tensorさらに高次元の数値のまとまり画像データ、ボリュームデータ、機械学習の内部データ
  • スカラー:時間、強度など単一の数値
  • ベクトル:位置、方向、色など複数の値をひとまとまりにしたもの
  • マトリクス(行列):値を行と列に並べ、座標変換や回転などを表す
  • テンソル:スカラーからベクトル、行列へ、さらに高次元へと拡張できるデータ型の総称
  • この授業では主に、ベクトルを行列で変換する という使い方を扱います

行列とは

変換をまとめて表す数値の表

  • 行列(マトリクス、Matrix)は、数値を縦横に並べたものです
  • 3D CG では、移動、回転、スケールのような変換を行列として表します
  • 頂点座標に行列を掛けると、別の座標空間での位置に変換できます
  • 行列は行列同士で掛け算することもでき、複数の変換をまとめて1つの行列にできます
    例えば、回転してから移動する変換を1つの行列にまとめることができます
  • 複数の座標系変換をまとめて扱えるため、シェーダーでは行列を使った座標変換がよく使われます

4x4 行列

3D の位置変換によく使われる形

text
[ m00 m01 m02 m03 ]
[ m10 m11 m12 m13 ]
[ m20 m21 m22 m23 ]
[ m30 m31 m32 m33 ]
  • 3D の位置は本来 (x, y, z) の3つの値で表せます
  • しかし移動、回転、スケール、投影をまとめて扱うために、シェーダーでは 4x4 行列と (x, y, z, w) の4成分ベクトルをよく使います
  • この4成分目の w を使う考え方を、同次座標系と呼びます
  • まずは「何に便利か」ではなく、同次座標系がどのように通常の座標を表しているのかを確認します

同次座標系

1つ多い成分で座標を表す方法

同次座標ではWで割って通常座標へ戻す

同次座標では、3D の点を4成分の比として表す

  • 通常の3D座標は (x, y, z) の3成分で点を表します
  • 同次座標系では、同じ点を (X, Y, Z, W) の4成分で表します
  • W0 ではない場合、通常の3D座標には次のように戻せます

$$
(x, y, z) = \left(\frac{X}{W}, \frac{Y}{W}, \frac{Z}{W}\right)
$$

  • (1, 2, 3, 1)(2, 4, 6, 2) は異なる同次座標ですが、W で割ると両方 (1, 2, 3) になります
  • 3D グラフィックスでは、通常の点を (x, y, z, 1) として表し、方向を (x, y, z, 0) として表します

なぜ1つ多い成分が必要なのか

  • ベクトルと行列の乗算では、次元がそろっている必要があります
  • 具体的には、行列の列数と、掛けられるベクトルの成分数が一致している必要があります
  • 例えば3成分のベクトル (x, y, z) は、3x3 行列とは乗算できます
  • しかし4x4 行列とはそのままでは乗算できません
text
3x3 Matrix * 3D Vector = 3D Vector   // 計算できる
4x4 Matrix * 3D Vector = ?           // 次元が合わない
4x4 Matrix * 4D Vector = 4D Vector   // 計算できる
  • 3D グラフィックスでは、回転、スケール、移動、投影をまとめて扱いたい場面が多くあります
  • 回転やスケールは 3x3 行列でも扱えますが、移動を同じ掛け算の形で合成するには 4x4 行列が必要になります
  • 3x3 行列で表せる変換は、基本的に原点を基準にした回転、拡大縮小、傾きの変化です
  • 平行移動は原点そのものの位置をずらす変換なので、3成分ベクトルに3x3行列を掛けるだけでは同じ形で表せません
  • そのため、3D の位置 (x, y, z) を同次座標 (x, y, z, 1) に拡張し、4x4 行列と乗算できる形にそろえます
  • 同次座標系は、3D の点を4x4行列で変換できる形にするための座標表現 でもあります
  • このおかげで、ModelViewProjection のような複数の変換を、行列の掛け算として連結できます

w の値で移動の影響が変わる

意味変換時の挙動
(x, y, z, 1)位置移動行列の影響を受ける
(x, y, z, 0)方向移動行列の影響を受けない
  • 位置は空間内の場所を示すため、オブジェクトを移動すれば一緒に移動します
  • 方向は向きだけを表すため、オブジェクトを移動しても向きそのものは変わりません
  • 法線、ライト方向、視線方向のようなベクトルは方向として扱う必要があります
  • 位置と方向を同じように変換すると、ライティングが不正になります

変換の順番

行列の掛け算は順番で結果が変わる

変換順序の違い
同じ移動と回転でも、順番が変わると最終位置が変わる

  • 行列の掛け算は、通常の数値の掛け算と違い、順番を入れ替えると結果が変わります
  • 「回転してから移動」と「移動してから回転」は、同じ変換量でも最終位置が違います
  • Unity の Transform 階層でも、親の変換と子の変換の順番が重要です
  • スキンメッシュのボーン階層で関節位置が重要だったのも、この変換の順番が関係しています

Model Matrix

Object から World へ変換する

  • Model Matrix は、モデルのローカル座標をワールド座標へ変換する行列です
  • Unity では Object to World の変換として扱われます
  • モデルの頂点位置に Model Matrix を掛けると、シーン内での実際の位置になります
  • GameObject の Transform を変えると、Model Matrix も変わります

View Matrix

World から View へ変換する

  • View Matrix は、ワールド座標をカメラ基準の座標へ変換する行列です
  • カメラ自体を動かす代わりに、世界全体をカメラの反対方向へ動かしているように考えることもできます
  • View Space では、カメラから見た位置や方向を扱いやすくなります
  • 第08回の View Direction や第09回のライト空間の考え方にもつながります

Projection Matrix

View から Clip へ変換する

  • Projection Matrix は、カメラから見た3D空間を画面へ投影するための行列です
  • 遠くのものを小さく見せる透視投影や、奥行きの範囲を Clip Space に収める処理に関係します
  • カメラの Field of View、Near、Far、アスペクト比などが Projection Matrix に反映されます
  • これにより、3D の点が画面上のどこに映るかを決められます

MVP の流れ

頂点が画面に届くまで

text
Object Position
  -> Model Matrix
  -> World Position
  -> View Matrix
  -> View Position
  -> Projection Matrix
  -> Clip Position
  -> Screen Position
  • MVPModelViewProjection の頭文字です
  • 頂点シェーダーでは、頂点位置を最終的に Clip Space へ変換する必要があります
  • Shader Graph では多くの処理を Unity が隠してくれますが、内部ではこのような変換が行われています
  • 自分で HLSL を書く場合や、特殊な頂点変形を行う場合は、この流れを理解していることが重要です

シェーダーで空間をそろえる

内積や比較は同じ空間で行う

  • 第07回では、法線とライト方向の内積で明るさを作りました
  • このとき法線が Object Space、ライト方向が World Space のままだと、正しい角度を比較できません
  • 第09回の Shadow Map でも、比較するために現在の点をライト空間へ変換しました
  • ベクトル同士を比較するときは、同じ座標空間にそろえる のが基本です

Shader Graph の Position ノード

空間を切り替えて値を確認する

  • Shader Graph の Position ノードは、現在の点の位置を出力します
  • SpaceObject にすると、モデル自身を基準にした位置になります
  • SpaceWorld にすると、シーン全体を基準にした位置になります
  • Split で X、Y、Z 成分に分けると、座標値を色やマスクに使えます
  • 素数値を控して芙控を機能させる引物候漄がありましたら、MultiplyFractionSaturate などのノードを使って値を調整します

Shader Graph の Transform ノード

値を別の空間へ変換する

  • Transform ノードは、位置や方向を別の座標空間へ変換するためのノードです
  • 例えば Object Space の方向を World Space へ変換したり、World Space の位置を View Space へ変換したりできます
  • 変換する値が Position なのか Direction なのかで結果が変わるため、ノード設定を確認します
  • Normal VectorView DirectionPosition などの Space が一致しているか確認します

よくあるミス

空間の不一致で見た目が崩れる

起こりうる問題:

  • オブジェクトを回転するとライトの当たり方が不自然に変わる
  • カメラを動かすと、物体に貼り付いているはずのパターンがずれる
  • ワールド座標のノイズを使ったつもりが、オブジェクトごとに異なるパターンになる
  • 法線と視線方向の Space が異なり、フレネルが不正な位置に出現
  • 頂点変形後に Bounds を更新せず、メッシュが画面外へ出ると消える

対策:どの値がどの空間にあるか を Shader Graph で確認します

実習

座標空間の違いを見えるようにする

Object と World の違いを Shader Graph で確認します

実習1

Object Space の座標で色を作る

  1. Lit Shader Graph または Unlit Shader Graph を作成する
  2. Position ノードを追加し、Space を Object にする
  3. Split で X、Y、Z を取り出す
  4. X 成分を Multiply で拡大し、Fraction または Sine で繰り返す値にする
  5. 色へ接続し、オブジェクトを移動しても縞パターンが物体についてくることを確認する

実習2

World Space の座標で色を作る

  1. Position ノードの Space を World に変更する
  2. 同じように X 成分から繰り返す値を作る
  3. オブジェクトを移動し、縞パターンの位置がワールド側に固定されることを確認する
  4. 複数のオブジェクトへ同じマテリアルを適用し、縞パターンが連続するか確認する
  5. Object Space との違いをスクリーンショットで比較する

実習3

Transform ノードで空間を変換する

  1. Position ノードを Object にする
  2. Transform ノードで Object から World へ変換する
  3. 変換後の X 成分を使って色を作る
  4. 最初から Position を World にした場合と同じ見た目になるか確認する
  5. PositionDirection の設定を変え、結果がどう変わるか観察する

実習4

View Space を使ってカメラ依存の表現を見る

  1. Position または View Direction を View Space で取得する
  2. カメラからの距離や向きに応じて色を変える
  3. カメラを移動し、見た目が変わることを確認する
  4. World Space の位置を使った表現と比較する
  5. カメラに依存させたい表現か、世界に固定したい表現かを考える

授業内課題

Object Space と World Space の違いが分かる マテリアルを作成してください

座標空間の選択が 見た目にどう影響するかを示します

課題の条件

以下を満たしてください

  • Shader Graph で Position ノードを使っている
  • Object Space を使った見た目と World Space を使った見た目を比較している
  • オブジェクトを移動、回転、スケールしたときの変化を確認している
  • SplitMultiplyFractionSaturateStep のいずれかを使って座標値を加工している
  • どの値がどの座標空間にあるかを説明できる
  • スクリーンショットまたは短い動画で、違いが確認できる

確認観点

チェックすべき項目

  • 座標から作った色変化がオブジェクトに貼り付いているか
  • 座標から作った色変化がワールド空間に固定されているか
  • オブジェクトを移動したときに値が変わるのはどちらか
  • カメラを動かしたときに値が変わる表現になっているか
  • 法線、視線方向、ライト方向の Space がそろっているか
  • Transform ノードの変換元と変換先を説明できるか

この回の到達目標

  • ローカル空間、ワールド空間、ビュー空間の違いを説明できる
  • Transform が位置、回転、スケールをまとめたものであることを説明できる
  • 行列が座標変換を表すために使われることを説明できる
  • 位置と方向で変換の扱いが違うことを説明できる
  • Shader Graph で Object Space と World Space の違いを確認できる

今回のまとめ

座標変換は基準を変える処理

  • 座標空間は、位置や方向を表すための基準です
  • Object Space はモデル自身、World Space はシーン全体、View Space はカメラを基準にします
  • Transform は位置、回転、スケールをまとめ、行列として頂点座標を変換できます
  • Model、View、Projection の流れで、頂点は最終的に画面へ投影されます
  • シェーダーでは、値の座標空間をそろえてから計算することが重要です

おつかれさまでした!

次回予告 第12回 行列と座標変換2

ボーン階層と頂点変形を もう少し深く見ていきます