[Unity] StructuredBufferに配列を含んだ構造体を転送する


前置き

オブジェクトの衝突判定をGPU側に任せようとした際に直面した問題の解決方法です。

2次元の点と矩形の衝突判定では、「点」と「矩形の各辺」との交差判定を行う必要があります。その際に矩形の頂点を配列として定義しておけば、辺を算出するアルゴリズムが単純になります。
本記事では矩形の構造体を用意する前提で話を進めます。

追記 :
もっと効率のいい手法がありそうなので、調査完了次第記事にします。

C#側の構造体

矩形には

  • 矩形の頂点座標(左上、左下、右下、右上)
  • ピボット(回転中心)座標
  • ラジアン回転角

の情報を持たせます。
このデータの頂点座標4点が配列で扱えると嬉しいわけですが、

struct Rectangle {
    public Vector2 p0;    // 左上
    public Vector2 p1;    // 左下
    public Vector2 p2;    // 右下
    public Vector2 p3;    // 右上
    public Vector2 center;    // ピボット
    public float rotation;    // 回転角
}

C#側は配列にせず、展開した状態で構造体を定義します。

シェーダー側の構造体

シェーダーでの構造体定義で、矩形の頂点を固定長配列にすることで値を受け取ることができました。

struct Rectangle {
    float2 points[4];
    float2 center;
    float rotation;
};

値の利用は、単純にStructuredBufferから取り出すようにして

float2 leftUp = buffer[InstanceID].points[0]; 

で可能です。

追記

構造体の転送は、C#側で「マーシャリング」を行うことで柔軟に対応できるようです。
これに関する記事はを後日書く予定です。

References