頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


Blenderの -Z Forward , Y Up の設定

Blenderで3Dのモデルを作成して、objファイルを出力してそれをiOSのOpenGL ESで使っているんだけど、この時、BlenderとOpenGLの座標系が違うのに同じように表示されるのはなんでだろうな、と思っていたんだわ。

どういうことかというとBlenderではz軸が上を向いててy軸がこちらじゃなくてむこうを向いてる。
OpenGL ESだとy軸が上を向いてて、z軸が手前を向いてる。
どちらも右手系というのは同じ。

Blenderでロボット

↑まずBlenderでこういうモデルを作成してみる。このモデルはz軸を上にしてるデータを持っているはずだよね。

ところがBlenderでobjファイルを出力、全く回転させない状態をiOSで表示させると、、、

-Z Forward, Y Upで出力時の描画

↑同じように表示される。OpenGL ESの座標はy軸が上になってるのに!どこの誰がよきにはからってくれてるの?!


今までなんの問題もなかったのでスルーしてきたんだけど、ちょっと具合が悪くなったのでよくよく調べるとBlenderの出力時にそういうオプションが設定されていたみたい。
objファイル出力時に左側のペインの下の方にそういう設定項目がある。

ForwardとUpの設定

↑ここね。ここが -Z Forward , Y Up となってる。多分Blenderのデフォルトの設定かと思う。
これのおかげでOpenGL ESの座標系に持ってきても同じように表示されていたのね。

ちなみに Z Forward ってするとどうなるんだろ?鏡のようになるの?と思ってやってみると、、、

Z Forward, Y Upで出力時の描画

↑あー、なるほど、右手をあげてるのは変わらないで反対向くのね。そういうことか。


Metalでシェーダが受けるデータの型

Objective-C++ でMetalを使う場合のお話。現時点iOS 8.0.2でのお話ね。今だけかもしれない。

こういう頂点データをシェーダに渡そうとしたのよ。なんのことはない三角形一つのデータ。
const float vertexData[] = {
    0.5, -0.5, 0.0, 
    -0.5, 0.5, 0.0, 
    -0.5, -0.5, 0.0,
};
OpenGL ESで扱ってきたデータがこういう形だからこれを渡せるとデータを作り直さなくてもいいはず。データをMetalだからって作り直すのが面倒だしねえ。
ところがどうもうまくいかない。
vertexBuffer = [device newBufferWithBytes:vertexData length:sizeof(vertexData) options:0];
てな感じでvertex buffer作る。

シェーダ側は
vertex float4 basic_vertex(device packed_float3 *vertex_array [[ buffer(0) ]] , unsigned int vid [[ vertex_id ]]) {   
	return float4(float3(vertex_array[vid]) , 1.0);
}
こんな感じでいけると思うんだけど、ダメなんだよなあ???

ところが引数の部分を自作の構造体を用意しといてそれで受けとる。
typedef struct {
    packed_float3 position;
} vertex_t;

vertex float4 basic_vertex( device vertex_t *vertex_array [[ buffer(0) ]] , unsigned int vid [[ vertex_id ]]) { 
	return float4(vertex_array[vid].position, 1.0);
}
↑こちらだといけるんだよな。どちらもpacked_float3のデータをもらってるのは同じだと思うんだけどなあ? まあうまくいってないんだから俺がなにか勘違いしてるんだろう。

Metalで表示した三角形
↑表示結果のスクショ。

ちなみに
iOS 8 Metal Tutorial with Swift: Getting Started - Ray Wenderlich
↑このチュートリアルはSwiftなんだけどこれをObjective-C++でやろうとしてたのよ。




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.