見出し画像

ARKitのMetalレンダリングテンプレートを読んだメモ

Appleのサンプルコードは「入門」向けというより、どっちかというと実践レベルのが多いと思う。たとえばこの記事で紹介したサンプルでは任意の頂点への自前実装ヒットテストロジックがしれっと入ってたりするが、ターゲットを入門者に向けているとしたらまずは標準APIに入っているヒットテストメソッドだけでサンプルを構成すると思う。

なので、最初はただただ複雑に見えるが、だんだん参考になるコードの宝庫に見えてくる。昨日の記事でもテーマにしたARKitのMetalレンダリングテンプレートもMetalにまだまだ慣れてない自分には参考になる部分がいろいろとあるので、そういうのをこの記事にメモっておく。

(x, y, u, v) の配列を構造体としてシェーダに渡す

テンプレートで勝手に生成されるプロジェクトのRenderer.swiftにこういう配列が定義されている。

let kImagePlaneVertexData: [Float] = [
    -1.0, -1.0,  0.0, 1.0,
    1.0, -1.0,  1.0, 1.0,
    -1.0,  1.0,  0.0, 0.0,
    1.0,  1.0,  1.0, 0.0,
]

当初これを (x, y, z, w) の配列だと勘違いし、z, wにあたる部分に値が釈然とせず、なぜ2Dの矩形を表すはずなのにzやwが頂点ごとに違うんだ?と疑問に思っていた。

後々コードを読んで理解したが、これはx, y, u, vの配列で、Shader.metalで定義されている、

typedef struct {
    float2 position [[attribute(kVertexAttributePosition)]];
    float2 texCoord [[attribute(kVertexAttributeTexcoord)]];
} ImageVertex;

の構造体としてシェーダに渡される。

こうすることで、頂点シェーダ関数では次のような引数で構造体のインスタンスを受け取り、

vertex ImageColorInOut
capturedImageVertexTransform(ImageVertex in [[stage_in]])

次のようにシンプルに4次元ベクトル型の頂点座標([[position]]修飾)と、テクスチャ座標とを持つ構造体を生成することができる。

ImageColorInOut out;
out.position = float4(in.position, 0.0, 1.0);
out.texCoord = in.texCoord;

で、Renderer.swiftで定義されている4x4の行列を、ImageVertexのようなfloat2型の要素2つを持つ構造体に格納してシェーダに渡すところをどうやってるかというと、

ここから先は

2,253字

¥ 100

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/