移動・回転・拡大を、1つの行列で表現したい。
変換行列を統一して扱いたい。
そんな要望を実現するのが、同次座標です。
同次座標は、移動・回転・拡大を統一的に扱える座標系です。
通常の3D座標(x, y, z)に、w成分を加えて(x, y, z, w)で表現します。
これにより、移動・回転・拡大を、1つの4×4行列で表現できますね。
この記事では、同次座標をゲームで使う理由について、Unity実装例とともに解説します。
- 同次座標とは何か、よく分からない…
- 移動・回転・拡大を統一的に扱いたい。
- 変換行列を理解したい。
✨ この記事でわかること
- 同次座標の基本概念
- 移動・回転・拡大の統一的表現
- 4×4変換行列の構成
- Unityでの実装方法
- 初心者でも理解できる同次座標の考え方
Unity入門の森をチェック Unity初心者でも安心。動画解説+完成サンプル付きで実装まで進められます
同次座標とは何か(ゲーム制作目線)

同次座標は、通常の座標に、w成分を加えた座標系です。
3D座標(x, y, z)を、(x, y, z, w)で表現します。
通常はw = 1とします。
同次座標の特徴は、移動・回転・拡大を統一的に扱えることです。
3×3行列では、回転と拡大しか表現できません。
しかし、4×4行列を使うことで、移動も含めた変換を表現できます。
Unityでは、Matrix4x4構造体で、4×4変換行列を扱えます。
ゲームでの具体的な使い道

同次座標が、ゲームでどう使われているか確認してみましょう。
変換行列の統一
移動・回転・拡大を、1つの4×4行列で表現します。
これにより、変換を統一的に扱えます。
アフィン変換
移動・回転・拡大を含む変換を、アフィン変換と呼びます。
同次座標を使うことで、アフィン変換を1つの行列で表現できます。
行列の合成
複数の変換を合成する場合、行列の積で簡単に計算できますね。
移動→回転→拡大の順に変換する場合、行列を掛け算するだけです。
座標変換
ワールド座標とローカル座標の変換など、座標変換に使われます。
変換行列を使うことで、正確な座標変換ができます。
- 変換行列の統一(移動・回転・拡大)
- アフィン変換の表現
- 行列の合成(複数の変換の組み合わせ)
- 座標変換(ワールド・ローカル座標など)
作り方は分かった。
でも完成まで行けない人へ
当たり判定・移動・カメラ・AIまで、
実装しながら学べる「永久会員チケット」です。
※ まずは内容を見るだけでOK
考え方・仕組みを図解イメージで説明

同次座標を使った変換は、「同次座標の作成 → 変換行列の適用 → 通常座標への変換」という流れで実現できます。
同次座標の作成
通常の3D座標(x, y, z)に、w = 1を加えて、(x, y, z, 1)にします。
これが同次座標です。
変換行列の適用
4×4変換行列を、同次座標に掛けます。
行列の積で、変換後の座標を計算します。
通常座標への変換
変換後の同次座標(x’, y’, z’, w’)から、通常座標を計算します。
w’で割って、(x’/w’, y’/w’, z’/w’)が通常座標です(通常はw’ = 1)。
4×4行列の構成
4×4変換行列は、以下のような構成です。
左上の3×3部分が回転・拡大、右端の列が移動、下端の行は(0, 0, 0, 1)です。
- 同次座標は、通常の座標にw成分を加えた座標系
- 移動・回転・拡大を統一的に扱える
- 4×4行列で、アフィン変換を表現できる
- 行列の合成で、複数の変換を組み合わせられる
Unityで実装する際の注意点(代表例)

Unityで同次座標を扱う場合の注意点を見ていきましょう。
Matrix4x4を使った実装
UnityのMatrix4x4構造体で、4×4変換行列を扱います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class HomogeneousCoordinateExample : MonoBehaviour { void Start() { // 移動行列を作成 Matrix4x4 translationMatrix = Matrix4x4.Translate(new Vector3(5, 0, 0)); // 回転行列を作成 Matrix4x4 rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 45, 0)); // 拡大行列を作成 Matrix4x4 scaleMatrix = Matrix4x4.Scale(new Vector3(2, 2, 2)); // 変換を合成(移動→回転→拡大) Matrix4x4 combinedMatrix = translationMatrix * rotationMatrix * scaleMatrix; // 座標を変換 Vector3 originalPosition = new Vector3(1, 0, 0); Vector3 transformedPosition = combinedMatrix.MultiplyPoint3x4(originalPosition); Debug.Log($"変換前: {originalPosition}, 変換後: {transformedPosition}"); } } |
移動行列の作成
移動だけを行う4×4行列を作成します。
|
1 2 3 4 5 6 7 8 9 |
public static Matrix4x4 CreateTranslationMatrix(Vector3 translation) { Matrix4x4 matrix = Matrix4x4.identity; matrix.m03 = translation.x; // 移動X matrix.m13 = translation.y; // 移動Y matrix.m23 = translation.z; // 移動Z return matrix; } |
回転行列の作成
回転だけを行う4×4行列を作成します。
|
1 2 3 4 5 6 |
public static Matrix4x4 CreateRotationMatrix(Quaternion rotation) { Matrix4x4 matrix = Matrix4x4.Rotate(rotation); return matrix; } |
拡大行列の作成
拡大だけを行う4×4行列を作成します。
|
1 2 3 4 5 6 7 8 9 |
public static Matrix4x4 CreateScaleMatrix(Vector3 scale) { Matrix4x4 matrix = Matrix4x4.identity; matrix.m00 = scale.x; // X軸の拡大 matrix.m11 = scale.y; // Y軸の拡大 matrix.m22 = scale.z; // Z軸の拡大 return matrix; } |
変換の合成
複数の変換を合成して、1つの行列にします。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class MatrixComposition : MonoBehaviour { void Start() { Vector3 position = new Vector3(5, 0, 0); Quaternion rotation = Quaternion.Euler(0, 45, 0); Vector3 scale = new Vector3(2, 2, 2); // 各変換行列を作成 Matrix4x4 translationMatrix = Matrix4x4.Translate(position); Matrix4x4 rotationMatrix = Matrix4x4.Rotate(rotation); Matrix4x4 scaleMatrix = Matrix4x4.Scale(scale); // 変換を合成(順番が重要:移動→回転→拡大) Matrix4x4 transformMatrix = translationMatrix * rotationMatrix * scaleMatrix; // オブジェクトに適用 transform.position = transformMatrix.GetColumn(3); // 移動部分 transform.rotation = rotation; // 回転 transform.localScale = scale; // 拡大 } } |
座標変換の実装
変換行列を使って、座標を変換します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class CoordinateTransform : MonoBehaviour { public Transform target; void Update() { // 変換行列を取得 Matrix4x4 transformMatrix = target.localToWorldMatrix; // ローカル座標をワールド座標に変換 Vector3 localPos = new Vector3(1, 0, 0); Vector3 worldPos = transformMatrix.MultiplyPoint3x4(localPos); Debug.Log($"ローカル座標: {localPos}, ワールド座標: {worldPos}"); } } |
同次座標の手動計算
同次座標を手動で計算する場合の実装です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public static Vector4 ToHomogeneous(Vector3 position) { // 同次座標に変換(w = 1) return new Vector4(position.x, position.y, position.z, 1f); } public static Vector3 FromHomogeneous(Vector4 homogeneous) { // 通常座標に変換(wで割る) if (Mathf.Abs(homogeneous.w) > 0.0001f) { return new Vector3( homogeneous.x / homogeneous.w, homogeneous.y / homogeneous.w, homogeneous.z / homogeneous.w ); } return Vector3.zero; } |

まとめ

この記事では、同次座標をゲームで使う理由について見てきました。
重要なポイントをおさらいします。
- 同次座標は、通常の座標にw成分を加えた座標系
- 移動・回転・拡大を統一的に扱える
- 4×4行列で、アフィン変換を表現できる
- UnityのMatrix4x4構造体で簡単に扱える
- 変換の合成や座標変換などに活用できる
同次座標は、変換行列を統一的に扱うために重要な概念です。
移動・回転・拡大を1つの行列で表現すれば、変換の合成や座標変換が簡単になります。
4×4変換行列を使うことで、様々な変換を統一的に扱えます。
実際のゲーム実装とセットで学ぶことで、理解が深まるはずです。
Unity入門の森では、変換行列を含むベクトルと行列を、実際のゲーム実装とともに体系的に学べます。
ぜひチェックしてみてください。
Unity入門の森をチェック Unity初心者でも安心。動画解説+完成サンプル付きで実装まで進められます





コメント